15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/files/scoped_temp_dir.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/importer/firefox_importer_unittest_utils.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/importer/nss_decryptor.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "sql/connection.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "testing/gtest/include/gtest/gtest.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(jschuh): Disabled on Win64 build. http://crbug.com/179688
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_NSS(x) DISABLED_##x
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_NSS(x) x
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The following test requires the use of the NSSDecryptor, on OSX this needs
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to run in a separate process, so we use a proxy object so we can share the
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// same test between platforms.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(FirefoxImporterTest, MAYBE_NSS(Firefox3NSS3Decryptor)) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath nss_path;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &nss_path));
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nss_path = nss_path.AppendASCII("firefox3_nss_mac");
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nss_path = nss_path.AppendASCII("firefox3_nss");
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !OS_MACOSX
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath db_path;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &db_path));
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_path = db_path.AppendASCII("firefox3_profile");
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FFUnitTestDecryptorProxy decryptor_proxy;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(decryptor_proxy.Setup(nss_path));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(decryptor_proxy.DecryptorInit(nss_path, db_path));
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::ASCIIToUTF16("hello"),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECKa"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              "jtRg4qFSHBAhv9luFkXgDJA=="));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test UTF-16 encoding.
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::WideToUTF16(L"\x4E2D"),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECLW"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              "qqiccfQHWBAie74hxnULxlw=="));
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Test empty string edge case.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(base::string16(), decryptor_proxy.Decrypt(std::string()));
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Test invalid base64.
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(base::string16(), decryptor_proxy.Decrypt("Not! Valid! Base64!"));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// The following test verifies proper detection of authentication scheme in
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// firefox's signons db. We insert two entries into moz_logins table. The first
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// has httpRealm column filled with non-empty string, therefore resulting
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// PasswordForm should have SCHEME_BASIC in scheme. The second entry has NULL
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// httpRealm, so it should produce a SCHEME_HTML PasswordForm.
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST(FirefoxImporterTest, MAYBE_NSS(FirefoxNSSDecryptorDeduceAuthScheme)) {
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ScopedTempDir temp_dir;
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::FilePath signons_path = temp_dir.path().AppendASCII("signons.sqlite");
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sql::Connection db_conn;
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(db_conn.Open(signons_path));
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(db_conn.Execute(
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "CREATE TABLE moz_logins (id INTEGER PRIMARY KEY, hostname TEXT NOT "
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "NULL, httpRealm TEXT, formSubmitURL TEXT, usernameField TEXT NOT NULL,"
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "passwordField TEXT NOT NULL, encryptedUsername TEXT NOT NULL,"
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "encryptedPassword TEXT NOT NULL, guid TEXT, encType INTEGER,"
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "timeCreated INTEGER, timeLastUsed INTEGER, timePasswordChanged "
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "INTEGER, timesUsed INTEGER)"));
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(db_conn.Execute(
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "CREATE TABLE moz_disabledHosts (id INTEGER PRIMARY KEY, hostname TEXT "
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "UNIQUE ON CONFLICT REPLACE)"));
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(db_conn.Execute(
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "INSERT INTO 'moz_logins' VALUES(1,'http://server.com:1234',"
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "'http_realm',NULL,'','','','','{bfa37106-a4dc-0a47-abb4-dafd507bf2db}',"
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "1,1401883410959,1401883410959,1401883410959,1)"));
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(db_conn.Execute(
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "INSERT INTO 'moz_logins' VALUES(2,'http://server.com:1234',NULL,"
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "'http://test2.server.com:1234/action','username','password','','',"
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "'{71ad64fa-b5d4-cf4d-b390-2e4d56fe2aff}',1,1401883939239,"
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "1401883939239, 1401883939239,1)"));
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  db_conn.Close();
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::FilePath nss_path;
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &nss_path));
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_MACOSX)
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  nss_path = nss_path.AppendASCII("firefox3_nss_mac");
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  nss_path = nss_path.AppendASCII("firefox3_nss");
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // !OS_MACOSX
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::FilePath db_path;
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &db_path));
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  db_path = db_path.AppendASCII("firefox3_profile");
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FFUnitTestDecryptorProxy decryptor_proxy;
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(decryptor_proxy.Setup(nss_path));
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(decryptor_proxy.DecryptorInit(nss_path, db_path));
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<autofill::PasswordForm> forms =
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      decryptor_proxy.ParseSignons(signons_path);
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_EQ(2u, forms.size());
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(autofill::PasswordForm::SCHEME_BASIC, forms[0].scheme);
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML, forms[1].scheme);
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
116