summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-15 00:27:20 +0000
committerkuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-15 00:27:20 +0000
commit1851d3b3a7a499157ec236df20bd8d3aa61a1265 (patch)
tree6ea5b5057ac19b8d77f0b18c6e76dccb7c6d4994 /chrome
parent9fe5c5244c7df4682ab9c09a769c897253ba7a43 (diff)
downloadchromium_src-1851d3b3a7a499157ec236df20bd8d3aa61a1265.zip
chromium_src-1851d3b3a7a499157ec236df20bd8d3aa61a1265.tar.gz
chromium_src-1851d3b3a7a499157ec236df20bd8d3aa61a1265.tar.bz2
Import passwords from Firefox 3.1 and above.
BUG=9103 Review URL: http://codereview.chromium.org/165352 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23503 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/importer/firefox3_importer.cc26
-rw-r--r--chrome/browser/importer/importer_unittest.cc109
-rw-r--r--chrome/browser/importer/nss_decryptor.cc69
-rw-r--r--chrome/browser/importer/nss_decryptor_linux.h8
-rw-r--r--chrome/browser/importer/nss_decryptor_mac.h6
-rw-r--r--chrome/browser/importer/nss_decryptor_win.h6
-rw-r--r--chrome/test/data/firefox35_profile/cert8.dbbin0 -> 65536 bytes
-rw-r--r--chrome/test/data/firefox35_profile/cookies.sqlitebin0 -> 2048 bytes
-rw-r--r--chrome/test/data/firefox35_profile/key3.dbbin0 -> 16384 bytes
-rw-r--r--chrome/test/data/firefox35_profile/places.sqlitebin0 -> 131072 bytes
-rw-r--r--chrome/test/data/firefox35_profile/prefs.js32
-rw-r--r--chrome/test/data/firefox35_profile/search.sqlitebin0 -> 2048 bytes
-rw-r--r--chrome/test/data/firefox35_profile/secmod.dbbin0 -> 16384 bytes
-rw-r--r--chrome/test/data/firefox35_profile/signons.sqlitebin0 -> 11264 bytes
14 files changed, 201 insertions, 55 deletions
diff --git a/chrome/browser/importer/firefox3_importer.cc b/chrome/browser/importer/firefox3_importer.cc
index 8ee342c..0a951ad 100644
--- a/chrome/browser/importer/firefox3_importer.cc
+++ b/chrome/browser/importer/firefox3_importer.cc
@@ -265,18 +265,22 @@ void Firefox3Importer::ImportPasswords() {
!decryptor.Init(app_path_, source_path_))
return;
- // Firefox 3 uses signons3.txt to store the passwords.
- std::wstring file = source_path_;
- file_util::AppendToPath(&file, L"signons3.txt");
- if (!file_util::PathExists(file)) {
- file = source_path_;
- file_util::AppendToPath(&file, L"signons2.txt");
- }
-
- std::string content;
- file_util::ReadFileToString(file, &content);
std::vector<PasswordForm> forms;
- decryptor.ParseSignons(content, &forms);
+ FilePath source_path = FilePath::FromWStringHack(source_path_);
+ FilePath file = source_path.AppendASCII("signons.sqlite");
+ if (file_util::PathExists(file)) {
+ // Since Firefox 3.1, passwords are in signons.sqlite db.
+ decryptor.ReadAndParseSignons(file, &forms);
+ } else {
+ // Firefox 3.0 uses signons3.txt to store the passwords.
+ file = source_path.AppendASCII("signons3.txt");
+ if (!file_util::PathExists(file))
+ file = source_path.AppendASCII("signons2.txt");
+
+ std::string content;
+ file_util::ReadFileToString(file, &content);
+ decryptor.ParseSignons(content, &forms);
+ }
if (!cancelled()) {
for (size_t i = 0; i < forms.size(); ++i) {
diff --git a/chrome/browser/importer/importer_unittest.cc b/chrome/browser/importer/importer_unittest.cc
index 6a348ec..729c2a1 100644
--- a/chrome/browser/importer/importer_unittest.cc
+++ b/chrome/browser/importer/importer_unittest.cc
@@ -51,6 +51,46 @@ class ImporterTest : public testing::Test {
ASSERT_FALSE(file_util::PathExists(test_path_));
}
+ void Firefox3xImporterTest(std::wstring profile_dir,
+ ImporterHost::Observer* observer,
+ ProfileWriter* writer,
+ bool import_search_plugins) {
+ std::wstring data_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
+ file_util::AppendToPath(&data_path, profile_dir + L"\\*");
+ ASSERT_TRUE(file_util::CopyDirectory(data_path, profile_path_, true));
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
+ file_util::AppendToPath(&data_path, L"firefox3_nss");
+ ASSERT_TRUE(file_util::CopyDirectory(data_path, profile_path_, false));
+
+ std::wstring search_engine_path = app_path_;
+ file_util::AppendToPath(&search_engine_path, L"searchplugins");
+ CreateDirectory(search_engine_path.c_str(), NULL);
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
+ file_util::AppendToPath(&data_path, L"firefox3_searchplugins");
+ if (!file_util::PathExists(data_path)) {
+ // TODO(maruel): Create test data that we can open source!
+ LOG(ERROR) << L"Missing internal test data";
+ return;
+ }
+ ASSERT_TRUE(file_util::CopyDirectory(data_path, search_engine_path, false));
+
+ MessageLoop* loop = MessageLoop::current();
+ ProfileInfo profile_info;
+ profile_info.browser_type = FIREFOX3;
+ profile_info.app_path = app_path_;
+ profile_info.source_path = profile_path_;
+ scoped_refptr<ImporterHost> host = new ImporterHost(loop);
+ host->SetObserver(observer);
+ int items = HISTORY | PASSWORDS | FAVORITES;
+ if (import_search_plugins)
+ items = items | SEARCH_ENGINES;
+ loop->PostTask(FROM_HERE, NewRunnableMethod(host.get(),
+ &ImporterHost::StartImportSettings, profile_info,
+ static_cast<Profile*>(NULL), items, writer, true));
+ loop->Run();
+ }
+
MessageLoopForUI message_loop_;
std::wstring test_path_;
std::wstring profile_path_;
@@ -675,11 +715,15 @@ static const int kDefaultFirefox3KeywordIndex = 8;
class Firefox3Observer : public ProfileWriter,
public ImporterHost::Observer {
public:
- Firefox3Observer() : ProfileWriter(NULL) {
- bookmark_count_ = 0;
- history_count_ = 0;
- password_count_ = 0;
- keyword_count_ = 0;
+ Firefox3Observer()
+ : ProfileWriter(NULL), bookmark_count_(0), history_count_(0),
+ password_count_(0), keyword_count_(0), import_search_engines_(true) {
+ }
+
+ Firefox3Observer(bool import_search_engines)
+ : ProfileWriter(NULL), bookmark_count_(0), history_count_(0),
+ password_count_(0), keyword_count_(0),
+ import_search_engines_(import_search_engines) {
}
virtual void ImportItemStarted(ImportItem item) {}
@@ -690,11 +734,13 @@ class Firefox3Observer : public ProfileWriter,
EXPECT_EQ(arraysize(kFirefox3Bookmarks), bookmark_count_);
EXPECT_EQ(1, history_count_);
EXPECT_EQ(arraysize(kFirefox3Passwords), password_count_);
- EXPECT_EQ(arraysize(kFirefox3Keywords), keyword_count_);
- EXPECT_EQ(kFirefox3Keywords[kDefaultFirefox3KeywordIndex].keyword,
- default_keyword_);
- EXPECT_EQ(kFirefox3Keywords[kDefaultFirefox3KeywordIndex].url,
- default_keyword_url_);
+ if (import_search_engines_) {
+ EXPECT_EQ(arraysize(kFirefox3Keywords), keyword_count_);
+ EXPECT_EQ(kFirefox3Keywords[kDefaultFirefox3KeywordIndex].keyword,
+ default_keyword_);
+ EXPECT_EQ(kFirefox3Keywords[kDefaultFirefox3KeywordIndex].url,
+ default_keyword_url_);
+ }
}
virtual bool BookmarkModelIsLoaded() const {
@@ -780,42 +826,19 @@ class Firefox3Observer : public ProfileWriter,
int history_count_;
int password_count_;
int keyword_count_;
+ bool import_search_engines_;
std::wstring default_keyword_;
std::wstring default_keyword_url_;
};
-TEST_F(ImporterTest, Firefox3Importer) {
- std::wstring data_path;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
- file_util::AppendToPath(&data_path, L"firefox3_profile\\*");
- ASSERT_TRUE(file_util::CopyDirectory(data_path, profile_path_, true));
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
- file_util::AppendToPath(&data_path, L"firefox3_nss");
- ASSERT_TRUE(file_util::CopyDirectory(data_path, profile_path_, false));
-
- std::wstring search_engine_path = app_path_;
- file_util::AppendToPath(&search_engine_path, L"searchplugins");
- CreateDirectory(search_engine_path.c_str(), NULL);
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
- file_util::AppendToPath(&data_path, L"firefox3_searchplugins");
- if (!file_util::PathExists(data_path)) {
- // TODO(maruel): Create test data that we can open source!
- LOG(ERROR) << L"Missing internal test data";
- return;
- }
- ASSERT_TRUE(file_util::CopyDirectory(data_path, search_engine_path, false));
-
- MessageLoop* loop = MessageLoop::current();
- ProfileInfo profile_info;
- profile_info.browser_type = FIREFOX3;
- profile_info.app_path = app_path_;
- profile_info.source_path = profile_path_;
- scoped_refptr<ImporterHost> host = new ImporterHost(loop);
+TEST_F(ImporterTest, Firefox30Importer) {
Firefox3Observer* observer = new Firefox3Observer();
- host->SetObserver(observer);
- loop->PostTask(FROM_HERE, NewRunnableMethod(host.get(),
- &ImporterHost::StartImportSettings, profile_info,
- static_cast<Profile*>(NULL),
- HISTORY | PASSWORDS | FAVORITES | SEARCH_ENGINES, observer, true));
- loop->Run();
+ Firefox3xImporterTest(L"firefox3_profile", observer, observer, true);
+}
+
+TEST_F(ImporterTest, Firefox35Importer) {
+ bool import_search_engines = false;
+ Firefox3Observer* observer = new Firefox3Observer(import_search_engines);
+ Firefox3xImporterTest(L"firefox35_profile", observer, observer,
+ import_search_engines);
}
diff --git a/chrome/browser/importer/nss_decryptor.cc b/chrome/browser/importer/nss_decryptor.cc
index ccdd3ce..13bb14b 100644
--- a/chrome/browser/importer/nss_decryptor.cc
+++ b/chrome/browser/importer/nss_decryptor.cc
@@ -4,7 +4,9 @@
#include "chrome/browser/importer/nss_decryptor.h"
+#include "base/scoped_ptr.h"
#include "build/build_config.h"
+#include "chrome/common/sqlite_utils.h"
#if defined(OS_LINUX)
#include <pk11pub.h>
@@ -226,3 +228,70 @@ void NSSDecryptor::ParseSignons(const std::string& content,
}
}
}
+
+bool NSSDecryptor::ReadAndParseSignons(const FilePath& sqlite_file,
+ std::vector<webkit_glue::PasswordForm>* forms) {
+ sqlite3* sqlite;
+ if (OpenSqliteDb(sqlite_file, &sqlite) != SQLITE_OK)
+ return false;
+ sqlite_utils::scoped_sqlite_db_ptr db(sqlite);
+
+ SQLStatement s;
+ const char* stmt = "SELECT hostname FROM moz_disabledHosts";
+ if (s.prepare(db.get(), stmt) != SQLITE_OK)
+ return false;
+
+ GURL::Replacements rep;
+ rep.ClearQuery();
+ rep.ClearRef();
+ rep.ClearUsername();
+ rep.ClearPassword();
+ // Read domains for which passwords are never saved.
+ while (s.step() == SQLITE_ROW) {
+ PasswordForm form;
+ form.origin = GURL(s.column_string(0)).ReplaceComponents(rep);
+ form.signon_realm = form.origin.GetOrigin().spec();
+ form.blacklisted_by_user = true;
+ forms->push_back(form);
+ }
+
+ SQLStatement s2;
+ const char* stmt2 = "SELECT hostname, httpRealm, formSubmitURL, "
+ "usernameField, passwordField, encryptedUsername, "
+ "encryptedPassword FROM moz_logins";
+
+ if (s2.prepare(db.get(), stmt2) != SQLITE_OK)
+ return false;
+
+ while (s2.step() == SQLITE_ROW) {
+ GURL url;
+ std::string realm(s2.column_string(1));
+ if (!realm.empty()) {
+ // In this case, the scheme may not exsit. Assume HTTP.
+ std::string host(s2.column_string(0));
+ if (host.find("://") == std::string::npos)
+ host = "http://" + host;
+ url = GURL(host);
+ } else {
+ url = GURL(s2.column_string(0));
+ }
+ // Skip this row if the URL is not valid.
+ if (!url.is_valid())
+ continue;
+
+ PasswordForm form;
+ form.origin = url.ReplaceComponents(rep);
+ form.signon_realm = form.origin.GetOrigin().spec();
+ if (!realm.empty())
+ form.signon_realm += realm;
+ form.ssl_valid = form.origin.SchemeIsSecure();
+ // The user name, password and action.
+ form.username_element = UTF8ToWide(s2.column_string(3));
+ form.username_value = Decrypt(s2.column_string(5));
+ form.password_element = UTF8ToWide(s2.column_string(4));
+ form.password_value = Decrypt(s2.column_string(6));
+ form.action = GURL(s2.column_string(2)).ReplaceComponents(rep);
+ forms->push_back(form);
+ }
+ return true;
+}
diff --git a/chrome/browser/importer/nss_decryptor_linux.h b/chrome/browser/importer/nss_decryptor_linux.h
index 508b30a..d73c733 100644
--- a/chrome/browser/importer/nss_decryptor_linux.h
+++ b/chrome/browser/importer/nss_decryptor_linux.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/file_path.h"
namespace webkit_glue {
struct PasswordForm;
@@ -35,7 +36,12 @@ class NSSDecryptor {
void ParseSignons(const std::string& content,
std::vector<webkit_glue::PasswordForm>* forms);
- private:
+ // Reads and parses the Firefox password sqlite db, decrypts the
+ // username/password and reads other related information.
+ // The result will be stored in |forms|.
+ bool ReadAndParseSignons(const FilePath& sqlite_file,
+ std::vector<webkit_glue::PasswordForm>* forms);
+private:
// Does not actually free the slot, since we'll free it when NSSDecryptor is
// destroyed.
void FreeSlot(PK11SlotInfo* slot) const {};
diff --git a/chrome/browser/importer/nss_decryptor_mac.h b/chrome/browser/importer/nss_decryptor_mac.h
index 46933cc..1eaf109 100644
--- a/chrome/browser/importer/nss_decryptor_mac.h
+++ b/chrome/browser/importer/nss_decryptor_mac.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/file_path.h"
#include "base/logging.h"
// The following declarations of functions and types are from Firefox
@@ -131,6 +132,11 @@ class NSSDecryptor {
void ParseSignons(const std::string& content,
std::vector<webkit_glue::PasswordForm>* forms);
+ // Reads and parses the Firefox password sqlite db, decrypts the
+ // username/password and reads other related information.
+ // The result will be stored in |forms|.
+ bool ReadAndParseSignons(const FilePath& sqlite_file,
+ std::vector<webkit_glue::PasswordForm>* forms);
private:
PK11SlotInfo* GetKeySlotForDB() const { return PK11_GetInternalKeySlot(); }
void FreeSlot(PK11SlotInfo* slot) const { PK11_FreeSlot(slot); }
diff --git a/chrome/browser/importer/nss_decryptor_win.h b/chrome/browser/importer/nss_decryptor_win.h
index b191206..f0b2345 100644
--- a/chrome/browser/importer/nss_decryptor_win.h
+++ b/chrome/browser/importer/nss_decryptor_win.h
@@ -131,6 +131,12 @@ class NSSDecryptor {
void ParseSignons(const std::string& content,
std::vector<webkit_glue::PasswordForm>* forms);
+ // Reads and parses the Firefox password sqlite db, decrypts the
+ // username/password and reads other related information.
+ // The result will be stored in |forms|.
+ bool ReadAndParseSignons(const FilePath& sqlite_file,
+ std::vector<webkit_glue::PasswordForm>* forms);
+
private:
// Performs tasks common across all platforms to initialize NSS.
bool InitNSS(const std::wstring& db_path,
diff --git a/chrome/test/data/firefox35_profile/cert8.db b/chrome/test/data/firefox35_profile/cert8.db
new file mode 100644
index 0000000..ac40a33
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/cert8.db
Binary files differ
diff --git a/chrome/test/data/firefox35_profile/cookies.sqlite b/chrome/test/data/firefox35_profile/cookies.sqlite
new file mode 100644
index 0000000..f9ec2f5
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/cookies.sqlite
Binary files differ
diff --git a/chrome/test/data/firefox35_profile/key3.db b/chrome/test/data/firefox35_profile/key3.db
new file mode 100644
index 0000000..6788cae
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/key3.db
Binary files differ
diff --git a/chrome/test/data/firefox35_profile/places.sqlite b/chrome/test/data/firefox35_profile/places.sqlite
new file mode 100644
index 0000000..9540a3e
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/places.sqlite
Binary files differ
diff --git a/chrome/test/data/firefox35_profile/prefs.js b/chrome/test/data/firefox35_profile/prefs.js
new file mode 100644
index 0000000..c65a9be2
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/prefs.js
@@ -0,0 +1,32 @@
+# Mozilla User Preferences
+
+/* Do not edit this file.
+ *
+ * If you make changes to this file while the application is running,
+ * the changes will be overwritten when the application exits.
+ *
+ * To make a manual change to preferences, you can visit the URL about:config
+ * For more information, see http://www.mozilla.org/unix/customizing.html#prefs
+ */
+
+user_pref("app.update.lastUpdateTime.addon-background-update-timer", 1211306768);
+user_pref("app.update.lastUpdateTime.background-update-timer", 1211306767);
+user_pref("app.update.lastUpdateTime.blocklist-background-update-timer", 1211306767);
+user_pref("app.update.lastUpdateTime.microsummary-generator-update-timer", 1211306768);
+user_pref("app.update.lastUpdateTime.search-engine-update-timer", 1211306768);
+user_pref("browser.migration.version", 1);
+user_pref("browser.places.importBookmarksHTML", false);
+user_pref("browser.places.importDefaults", false);
+user_pref("browser.places.leftPaneFolderId", -1);
+user_pref("browser.places.migratePostDataAnnotations", false);
+user_pref("browser.places.smartBookmarksVersion", 1);
+user_pref("browser.places.updateRecentTagsUri", false);
+user_pref("browser.search.selectedEngine", "IMDB");
+user_pref("browser.search.useDBForOrder", true);
+user_pref("browser.sessionstore.resume_session_once", true);
+user_pref("browser.startup.homepage_override.mstone", "rv:1.9");
+user_pref("extensions.enabledItems", "{972ce4c6-7e08-4474-a285-3208198ce6fd}:3.0");
+user_pref("extensions.lastAppVersion", "3.0");
+user_pref("intl.charsetmenu.browser.cache", "UTF-8");
+user_pref("network.cookie.prefsMigrated", true);
+user_pref("urlclassifier.keyupdatetime.https://sb-ssl.google.com/safebrowsing/newkey", 1213898771);
diff --git a/chrome/test/data/firefox35_profile/search.sqlite b/chrome/test/data/firefox35_profile/search.sqlite
new file mode 100644
index 0000000..55d45cb
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/search.sqlite
Binary files differ
diff --git a/chrome/test/data/firefox35_profile/secmod.db b/chrome/test/data/firefox35_profile/secmod.db
new file mode 100644
index 0000000..cb8cc20
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/secmod.db
Binary files differ
diff --git a/chrome/test/data/firefox35_profile/signons.sqlite b/chrome/test/data/firefox35_profile/signons.sqlite
new file mode 100644
index 0000000..b3e0aa0
--- /dev/null
+++ b/chrome/test/data/firefox35_profile/signons.sqlite
Binary files differ