summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/importer/firefox3_importer.h2
-rw-r--r--chrome/browser/importer/firefox_importer_unittest.cc37
-rw-r--r--chrome/browser/importer/firefox_importer_unittest_messages_internal.h33
-rw-r--r--chrome/browser/importer/firefox_importer_unittest_utils.h84
-rw-r--r--chrome/browser/importer/firefox_importer_unittest_utils_mac.cc266
-rw-r--r--chrome/browser/importer/firefox_importer_utils.h11
-rw-r--r--chrome/browser/importer/firefox_importer_utils_mac.mm20
-rw-r--r--chrome/browser/importer/nss_decryptor_mac.h8
-rw-r--r--chrome/browser/importer/nss_decryptor_mac.mm62
-rw-r--r--chrome/chrome.gyp3
-rw-r--r--chrome/test/data/firefox2_nss_mac/README7
-rwxr-xr-xchrome/test/data/firefox2_nss_mac/libfreebl3.dylibbin0 -> 760240 bytes
-rwxr-xr-xchrome/test/data/firefox2_nss_mac/libnspr4.dylibbin0 -> 489180 bytes
-rwxr-xr-xchrome/test/data/firefox2_nss_mac/libnss3.dylibbin0 -> 983796 bytes
-rwxr-xr-xchrome/test/data/firefox2_nss_mac/libplc4.dylibbin0 -> 132308 bytes
-rwxr-xr-xchrome/test/data/firefox2_nss_mac/libplds4.dylibbin0 -> 117784 bytes
-rwxr-xr-xchrome/test/data/firefox2_nss_mac/libsoftokn3.dylibbin0 -> 732596 bytes
-rw-r--r--chrome/test/data/firefox3_nss_mac/README13
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libfreebl3.dylibbin0 -> 794556 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libnspr4.dylibbin0 -> 482780 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libnss3.dylibbin0 -> 2204396 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libnssdbm3.dylibbin0 -> 311236 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libnssutil3.dylibbin0 -> 190752 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libplc4.dylibbin0 -> 115456 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libplds4.dylibbin0 -> 105576 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libsoftokn3.dylibbin0 -> 443048 bytes
-rwxr-xr-xchrome/test/data/firefox3_nss_mac/libsqlite3.dylibbin0 -> 883860 bytes
-rw-r--r--ipc/ipc_sync_message_unittest.h2
-rw-r--r--ipc/ipc_tests.cc2
29 files changed, 520 insertions, 30 deletions
diff --git a/chrome/browser/importer/firefox3_importer.h b/chrome/browser/importer/firefox3_importer.h
index 12a678f..9daa6b53a 100644
--- a/chrome/browser/importer/firefox3_importer.h
+++ b/chrome/browser/importer/firefox3_importer.h
@@ -80,7 +80,7 @@ class Firefox3Importer : public Importer {
std::wstring source_path_;
std::wstring app_path_;
- DISALLOW_EVIL_CONSTRUCTORS(Firefox3Importer);
+ DISALLOW_COPY_AND_ASSIGN(Firefox3Importer);
};
#endif // CHROME_BROWSER_IMPORTER_FIREFOX3_IMPORTER_H_
diff --git a/chrome/browser/importer/firefox_importer_unittest.cc b/chrome/browser/importer/firefox_importer_unittest.cc
index 1c0af23..e7e9470 100644
--- a/chrome/browser/importer/firefox_importer_unittest.cc
+++ b/chrome/browser/importer/firefox_importer_unittest.cc
@@ -8,46 +8,61 @@
#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/browser/importer/firefox2_importer.h"
+#include "chrome/browser/importer/firefox_importer_unittest_utils.h"
#include "chrome/browser/importer/firefox_importer_utils.h"
#include "chrome/browser/importer/nss_decryptor.h"
#include "chrome/common/chrome_paths.h"
using base::Time;
-// TODO(jeremy): Port NSSDecryptor to OSX and enable these tests.
-#if !defined(OS_MACOSX)
+// The following 2 tests require the use of the NSSDecryptor, on OSX this needs
+// to run in a separate process, so we use a proxy object so we can share the
+// same test between platforms.
TEST(FirefoxImporterTest, Firefox2NSS3Decryptor) {
std::wstring nss_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &nss_path));
+#ifdef OS_MACOSX
+ file_util::AppendToPath(&nss_path, L"firefox2_nss_mac");
+#else
file_util::AppendToPath(&nss_path, L"firefox2_nss");
+#endif // !OS_MACOSX
std::wstring db_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &db_path));
file_util::AppendToPath(&db_path, L"firefox2_profile");
- NSSDecryptor decryptor;
- EXPECT_TRUE(decryptor.Init(nss_path, db_path));
- EXPECT_EQ(L"hello", decryptor.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
+
+ FFUnitTestDecryptorProxy decryptor_proxy;
+ ASSERT_TRUE(decryptor_proxy.Setup(nss_path));
+
+ EXPECT_TRUE(decryptor_proxy.DecryptorInit(nss_path, db_path));
+ EXPECT_EQ(L"hello", decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
"wFAYIKoZIhvcNAwcECBJM63MpT9rtBAjMCm7qo/EhlA=="));
// Test UTF-16 encoding.
- EXPECT_EQ(L"\x4E2D", decryptor.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
+ EXPECT_EQ(L"\x4E2D", decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
"wFAYIKoZIhvcNAwcECN9OQ5ZFmhb8BAiFo1Z+fUvaIQ=="));
}
TEST(FirefoxImporterTest, Firefox3NSS3Decryptor) {
std::wstring nss_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &nss_path));
+#ifdef OS_MACOSX
+ file_util::AppendToPath(&nss_path, L"firefox3_nss_mac");
+#else
file_util::AppendToPath(&nss_path, L"firefox3_nss");
+#endif // !OS_MACOSX
std::wstring db_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &db_path));
file_util::AppendToPath(&db_path, L"firefox3_profile");
- NSSDecryptor decryptor;
- EXPECT_TRUE(decryptor.Init(nss_path, db_path));
- EXPECT_EQ(L"hello", decryptor.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
+
+ FFUnitTestDecryptorProxy decryptor_proxy;
+ ASSERT_TRUE(decryptor_proxy.Setup(nss_path));
+
+ EXPECT_TRUE(decryptor_proxy.DecryptorInit(nss_path, db_path));
+ EXPECT_EQ(L"hello", decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
"wFAYIKoZIhvcNAwcECKajtRg4qFSHBAhv9luFkXgDJA=="));
// Test UTF-16 encoding.
- EXPECT_EQ(L"\x4E2D", decryptor.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
+ EXPECT_EQ(L"\x4E2D", decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAE"
"wFAYIKoZIhvcNAwcECLWqqiccfQHWBAie74hxnULxlw=="));
}
-#endif // !OS_MACOSX
TEST(FirefoxImporterTest, Firefox2BookmarkParse) {
bool result;
diff --git a/chrome/browser/importer/firefox_importer_unittest_messages_internal.h b/chrome/browser/importer/firefox_importer_unittest_messages_internal.h
new file mode 100644
index 0000000..72eff6f
--- /dev/null
+++ b/chrome/browser/importer/firefox_importer_unittest_messages_internal.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This header is meant to be included in multiple passes, hence no traditional
+// header guard.
+// See ipc_message_macros.h for explanation of the macros and passes.
+
+#include "ipc/ipc_message_macros.h"
+
+// Messages definitions for messages sent between the unit test binary and
+// a child process by FFUnitTestDecryptorProxy.
+IPC_BEGIN_MESSAGES(Test)
+
+// Server->Child: Initialize the decrytor with the following paramters.
+IPC_MESSAGE_CONTROL2(Msg_Decryptor_Init,
+ std::wstring /* dll_path */,
+ std::wstring /* db_path */)
+// Child->Server: Return paramter from init call.
+IPC_MESSAGE_CONTROL1(Msg_Decryptor_InitReturnCode,
+ bool /* ret */)
+
+// Server->Child: Decrypt a given string.
+IPC_MESSAGE_CONTROL1(Msg_Decrypt,
+ std::string /* crypt */)
+// Child->Server: Decrypted String.
+IPC_MESSAGE_CONTROL1(Msg_Decryptor_Response,
+ std::wstring /* unencrypted_str */)
+
+// Server->Child: Die.
+IPC_MESSAGE_CONTROL0(Msg_Decryptor_Quit)
+
+IPC_END_MESSAGES(Test)
diff --git a/chrome/browser/importer/firefox_importer_unittest_utils.h b/chrome/browser/importer/firefox_importer_unittest_utils.h
new file mode 100644
index 0000000..cb53cce
--- /dev/null
+++ b/chrome/browser/importer/firefox_importer_unittest_utils.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UNITTEST_UTILS_H_
+#define CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UNITTEST_UTILS_H_
+
+#include "base/basictypes.h"
+#include "base/process_util.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/importer/nss_decryptor.h"
+
+class FFDecryptorServerChannelListener;
+namespace IPC {
+ class Channel;
+} // namespace IPC
+class MessageLoopForIO;
+
+// On OS X NSSDecryptor needs to run in a separate process. To allow us to use
+// the same unit test on all platforms we use a proxy class which spawns a
+// child process to do decryption on OS X, and calls through directly
+// to NSSDecryptor on other platforms.
+// On OS X:
+// 2 IPC messages are sent for every method of NSSDecryptor, one containing the
+// input arguments sent from Server->Child and one coming back containing
+// the return argument e.g.
+//
+// -> Msg_Decryptor_Init(dll_path, db_path)
+// <- Msg_Decryptor_InitReturnCode(bool)
+class FFUnitTestDecryptorProxy {
+ public:
+ FFUnitTestDecryptorProxy();
+ virtual ~FFUnitTestDecryptorProxy();
+
+ // Initialize a decryptor, returns true if the object was
+ // constructed successfully.
+ bool Setup(std::wstring& nss_path);
+
+ // This match the parallel functions in NSSDecryptor.
+ bool DecryptorInit(const std::wstring& dll_path, const std::wstring& db_path);
+ std::wstring Decrypt(const std::string& crypt);
+
+ private:
+#if defined(OS_MACOSX)
+ // Blocks until either a timeout is reached, or until the client process
+ // responds to an IPC message.
+ // Returns true if a reply was recieved successfully and false if the
+ // the operation timed out.
+ bool WaitForClientResponse();
+
+ base::ProcessHandle child_process_;
+ scoped_ptr<IPC::Channel> channel_;
+ scoped_ptr<FFDecryptorServerChannelListener> listener_;
+ scoped_ptr<MessageLoopForIO> message_loop_;
+#else
+ NSSDecryptor decryptor_;
+#endif // !OS_MACOSX
+ DISALLOW_COPY_AND_ASSIGN(FFUnitTestDecryptorProxy);
+};
+
+// On Non-OSX platforms FFUnitTestDecryptorProxy simply calls through to
+// NSSDecryptor.
+#if !defined(OS_MACOSX)
+FFUnitTestDecryptorProxy::FFUnitTestDecryptorProxy() {
+}
+
+FFUnitTestDecryptorProxy::~FFUnitTestDecryptorProxy() {
+}
+
+bool FFUnitTestDecryptorProxy::Setup(std::wstring& /* nss_path */) {
+ return true;
+}
+
+bool FFUnitTestDecryptorProxy::DecryptorInit(const std::wstring& dll_path,
+ const std::wstring& db_path) {
+ return decryptor_.Init(dll_path, db_path);
+}
+
+std::wstring FFUnitTestDecryptorProxy::Decrypt(const std::string& crypt) {
+ return decryptor_.Decrypt(crypt);
+}
+#endif // !OS_MACOSX
+
+#endif // CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UNITTEST_UTILS_H_
diff --git a/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc b/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc
new file mode 100644
index 0000000..d44b336
--- /dev/null
+++ b/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc
@@ -0,0 +1,266 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/importer/firefox_importer_unittest_utils.h"
+
+#include "base/command_line.h"
+#include "base/debug_on_start.h"
+#include "base/file_path.h"
+#include "base/message_loop.h"
+#include "chrome/browser/importer/firefox_importer_utils.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_descriptors.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_utils.h"
+#include "ipc/ipc_switches.h"
+#include "testing/multiprocess_func_list.h"
+
+// Definition of IPC Messages used for this test.
+#define MESSAGES_INTERNAL_FILE \
+ "chrome/browser/importer/firefox_importer_unittest_messages_internal.h"
+#include "ipc/ipc_message_macros.h"
+
+namespace {
+
+// Name of IPC Channel to use for Server<-> Child Communications.
+const char kTestChannelID[] = "T1";
+
+// Launch the child process:
+// |nss_path| - path to the NSS directory holding the decryption libraries.
+// |channel| - IPC Channel to use for communication.
+// |handle| - On return, the process handle to use to communicate with the
+// child.
+bool LaunchNSSDecrypterChildProcess(const std::wstring& nss_path,
+ const IPC::Channel& channel, base::ProcessHandle* handle) {
+ CommandLine cl(*CommandLine::ForCurrentProcess());
+ cl.AppendSwitchWithValue(L"client", L"NSSDecrypterChildProcess");
+
+ FilePath ff_dylib_dir = FilePath::FromWStringHack(nss_path);
+ // Set env variable needed for FF encryption libs to load.
+ // See "chrome/browser/importer/nss_decryptor_mac.mm" for an explanation of
+ // why we need this.
+ base::environment_vector env;
+ std::pair<const char*,const char*> dyld_override;
+ dyld_override.first = "DYLD_FALLBACK_LIBRARY_PATH";
+ dyld_override.second = ff_dylib_dir.value().c_str();
+ env.push_back(dyld_override);
+
+ base::file_handle_mapping_vector fds_to_map;
+ const int ipcfd = channel.GetClientFileDescriptor();
+ if (ipcfd > -1) {
+ fds_to_map.push_back(std::pair<int,int>(ipcfd, kPrimaryIPCChannel + 3));
+ } else {
+ return false;
+ }
+
+ bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDebugChildren);
+ return base::LaunchApp(cl.argv(), env, fds_to_map, debug_on_start,
+ handle);
+}
+
+} // namespace
+
+//----------------------- Server --------------------
+
+// Class to communicate on the server side of the IPC Channel.
+// Method calls are sent over IPC and replies are read back into class
+// variables.
+// This class needs to be called on a single thread.
+class FFDecryptorServerChannelListener : public IPC::Channel::Listener {
+ public:
+ FFDecryptorServerChannelListener()
+ : got_result(false), sender_(NULL) {}
+
+ void SetSender(IPC::Message::Sender* sender) {
+ sender_ = sender;
+ }
+
+ void OnInitDecryptorResponse(bool result) {
+ DCHECK(!got_result);
+ result_bool = result;
+ got_result = true;
+ MessageLoop::current()->Quit();
+ }
+
+ void OnDecryptedTextResonse(std::wstring decrypted_text) {
+ DCHECK(!got_result);
+ result_string = decrypted_text;
+ got_result = true;
+ MessageLoop::current()->Quit();
+ }
+
+ void QuitClient() {
+ if (sender_)
+ sender_->Send(new Msg_Decryptor_Quit());
+ }
+
+ virtual void OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(FFDecryptorServerChannelListener, msg)
+ IPC_MESSAGE_HANDLER(Msg_Decryptor_InitReturnCode, OnInitDecryptorResponse)
+ IPC_MESSAGE_HANDLER(Msg_Decryptor_Response, OnDecryptedTextResonse)
+ IPC_END_MESSAGE_MAP()
+ }
+
+ // If an error occured, just kill the message Loop.
+ virtual void OnChannelError() {
+ got_result = false;
+ MessageLoop::current()->Quit();
+ }
+
+ // Results of IPC calls.
+ std::wstring result_string;
+ bool result_bool;
+ // True if IPC call succeeded and data in above variables is valid.
+ bool got_result;
+
+ private:
+ IPC::Message::Sender* sender_; // weak
+};
+
+FFUnitTestDecryptorProxy::FFUnitTestDecryptorProxy()
+ : child_process_(0) {
+}
+
+bool FFUnitTestDecryptorProxy::Setup(std::wstring& nss_path) {
+ // Create a new message loop and spawn the child process.
+ message_loop_.reset(new MessageLoopForIO());
+
+ listener_.reset(new FFDecryptorServerChannelListener());
+ channel_.reset(new IPC::Channel(kTestChannelID,
+ IPC::Channel::MODE_SERVER,
+ listener_.get()));
+ channel_->Connect();
+ listener_->SetSender(channel_.get());
+
+ // Spawn child and set up sync IPC connection.
+ bool ret = LaunchNSSDecrypterChildProcess(nss_path,
+ *(channel_.get()),
+ &child_process_);
+ return ret && (child_process_ != 0);
+}
+
+FFUnitTestDecryptorProxy::~FFUnitTestDecryptorProxy() {
+ listener_->QuitClient();
+ channel_->Close();
+
+ if (child_process_) {
+ base::WaitForSingleProcess(child_process_, 5000);
+ base::CloseProcessHandle(child_process_);
+ }
+}
+
+// A message_loop task that quits the message loop when invoked, setting cancel
+// causes the task to do nothing when invoked.
+class CancellableQuitMsgLoop : public base::RefCounted<CancellableQuitMsgLoop> {
+ public:
+ CancellableQuitMsgLoop() : cancelled_(false) {}
+ void QuitNow() {
+ if (!cancelled_)
+ MessageLoop::current()->Quit();
+ }
+ bool cancelled_;
+};
+
+// Spin until either a client response arrives or a timeout occurs.
+bool FFUnitTestDecryptorProxy::WaitForClientResponse() {
+ const int64 kLoopTimeoutMS = 10 * 1000; // 10 seconds.
+
+ // What we're trying to do here is to wait for an RPC message to go over the
+ // wire and the client to reply. If the client does not replyy by a given
+ // timeout we kill the message loop.
+ // The way we do this is to post a CancellableQuitMsgLoop for 3 seconds in
+ // the future and cancel it if an RPC message comes back earlier.
+ // This relies on the IPC listener class to quit the message loop itself when
+ // a message comes in.
+ scoped_refptr<CancellableQuitMsgLoop> quit_task =
+ new CancellableQuitMsgLoop();
+ MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
+ quit_task.get(), &CancellableQuitMsgLoop::QuitNow), kLoopTimeoutMS);
+
+ message_loop_->Run();
+ bool ret = !quit_task->cancelled_;
+ quit_task->cancelled_ = false;
+ return ret;
+}
+
+bool FFUnitTestDecryptorProxy::DecryptorInit(const std::wstring& dll_path,
+ const std::wstring& db_path) {
+ channel_->Send(new Msg_Decryptor_Init(dll_path, db_path));
+ bool ok = WaitForClientResponse();
+ if (ok && listener_->got_result) {
+ listener_->got_result = false;
+ return listener_->result_bool;
+ }
+ return false;
+}
+
+std::wstring FFUnitTestDecryptorProxy::Decrypt(const std::string& crypt) {
+ channel_->Send(new Msg_Decrypt(crypt));
+ bool ok = WaitForClientResponse();
+ if (ok && listener_->got_result) {
+ listener_->got_result = false;
+ return listener_->result_string;
+ }
+ return L"";
+}
+
+//---------------------------- Child Process -----------------------
+
+// Class to listen on the client side of the ipc channel, it calls through
+// to the NSSDecryptor and sends back a reply.
+class FFDecryptorClientChannelListener : public IPC::Channel::Listener {
+ public:
+ FFDecryptorClientChannelListener()
+ : sender_(NULL) {}
+
+ void SetSender(IPC::Message::Sender* sender) {
+ sender_ = sender;
+ }
+
+ void OnDecryptor_Init(std::wstring dll_path, std::wstring db_path) {
+ bool ret = decryptor_.Init(dll_path, db_path);
+ sender_->Send(new Msg_Decryptor_InitReturnCode(ret));
+ }
+
+ void OnDecrypt(std::string crypt) {
+ std::wstring unencrypted_str = decryptor_.Decrypt(crypt);
+ sender_->Send(new Msg_Decryptor_Response(unencrypted_str));
+ }
+
+ void OnQuitRequest() {
+ MessageLoop::current()->Quit();
+ }
+
+ virtual void OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(FFDecryptorClientChannelListener, msg)
+ IPC_MESSAGE_HANDLER(Msg_Decryptor_Init, OnDecryptor_Init)
+ IPC_MESSAGE_HANDLER(Msg_Decrypt, OnDecrypt)
+ IPC_MESSAGE_HANDLER(Msg_Decryptor_Quit, OnQuitRequest)
+ IPC_END_MESSAGE_MAP()
+ }
+
+ virtual void OnChannelError() {
+ MessageLoop::current()->Quit();
+ }
+
+ private:
+ NSSDecryptor decryptor_;
+ IPC::Message::Sender* sender_;
+};
+
+// Entry function in child process.
+MULTIPROCESS_TEST_MAIN(NSSDecrypterChildProcess) {
+ MessageLoopForIO main_message_loop;
+ FFDecryptorClientChannelListener listener;
+
+ IPC::Channel channel(kTestChannelID, IPC::Channel::MODE_CLIENT, &listener);
+ channel.Connect();
+ listener.SetSender(&channel);
+
+ // run message loop
+ MessageLoop::current()->Run();
+
+ return 0;
+}
diff --git a/chrome/browser/importer/firefox_importer_utils.h b/chrome/browser/importer/firefox_importer_utils.h
index 41b88fa..fa7e50b 100644
--- a/chrome/browser/importer/firefox_importer_utils.h
+++ b/chrome/browser/importer/firefox_importer_utils.h
@@ -25,7 +25,16 @@ int GetCurrentFirefoxMajorVersionFromRegistry();
// Detects where Firefox lives. Returns a empty string if Firefox
// is not installed.
std::wstring GetFirefoxInstallPathFromRegistry();
-#endif
+#endif // OS_WIN
+
+#if defined(OS_MACOSX)
+
+// Get the directory in which the Firefox .dylibs live, we need to load these
+// in order to decoded FF profile passwords.
+// The Path is usuall FF App Bundle/Contents/Mac OS/
+// Returns empty path on failure.
+FilePath GetFirefoxDylibPath();
+#endif // OS_MACOSX
// Detects version of Firefox and installation path from given Firefox profile
bool GetFirefoxVersionAndPathFromProfile(const std::wstring& profile_path,
diff --git a/chrome/browser/importer/firefox_importer_utils_mac.mm b/chrome/browser/importer/firefox_importer_utils_mac.mm
index 5fd24b0..bea6b71 100644
--- a/chrome/browser/importer/firefox_importer_utils_mac.mm
+++ b/chrome/browser/importer/firefox_importer_utils_mac.mm
@@ -23,9 +23,27 @@ FilePath GetProfilesINI() {
ini_file = FilePath([profiles_ini fileSystemRepresentation]);
}
}
-
+
if (file_util::PathExists(ini_file))
return ini_file;
return FilePath();
}
+
+FilePath GetFirefoxDylibPath() {
+ CFURLRef appURL = nil;
+ if (LSFindApplicationForInfo(kLSUnknownCreator,
+ CFSTR("org.mozilla.firefox"),
+ NULL,
+ NULL,
+ &appURL) != noErr) {
+ return FilePath();
+ }
+ NSBundle *ff_bundle = [NSBundle
+ bundleWithPath:[reinterpret_cast<const NSURL*>(appURL) path]];
+ CFRelease(appURL);
+ NSString *ff_library_path = [[ff_bundle executablePath]
+ stringByDeletingLastPathComponent];
+
+ return FilePath([ff_library_path fileSystemRepresentation]);
+}
diff --git a/chrome/browser/importer/nss_decryptor_mac.h b/chrome/browser/importer/nss_decryptor_mac.h
index 1eaf109..477cf53 100644
--- a/chrome/browser/importer/nss_decryptor_mac.h
+++ b/chrome/browser/importer/nss_decryptor_mac.h
@@ -114,9 +114,8 @@ class NSSDecryptor {
: NSS_Init(NULL), NSS_Shutdown(NULL), PK11_GetInternalKeySlot(NULL),
PK11_CheckUserPassword(NULL), PK11_FreeSlot(NULL),
PK11_Authenticate(NULL), PK11SDR_Decrypt(NULL), SECITEM_FreeItem(NULL),
- PL_ArenaFinish(NULL), PR_Cleanup(NULL),
is_nss_initialized_(false) {}
- ~NSSDecryptor() {}
+ ~NSSDecryptor();
// Initializes NSS if it hasn't already been initialized.
bool Init(const std::wstring& /* dll_path */,
@@ -150,14 +149,9 @@ class NSSDecryptor {
PK11AuthenticateFunc PK11_Authenticate;
PK11SDRDecryptFunc PK11SDR_Decrypt;
SECITEMFreeItemFunc SECITEM_FreeItem;
- PLArenaFinishFunc PL_ArenaFinish;
- PRCleanupFunc PR_Cleanup;
// Libraries necessary for decrypting the passwords.
static const wchar_t kNSS3Library[];
- static const wchar_t kSoftokn3Library[];
- static const wchar_t kPLDS4Library[];
- static const wchar_t kNSPR4Library[];
// True if NSS_Init() has been called
bool is_nss_initialized_;
diff --git a/chrome/browser/importer/nss_decryptor_mac.mm b/chrome/browser/importer/nss_decryptor_mac.mm
index 97e85b6..dc6dd0d 100644
--- a/chrome/browser/importer/nss_decryptor_mac.mm
+++ b/chrome/browser/importer/nss_decryptor_mac.mm
@@ -4,20 +4,68 @@
#include <Cocoa/Cocoa.h>
+#include <dlfcn.h>
+
+#include "base/sys_string_conversions.h"
+
#include "chrome/browser/importer/nss_decryptor_mac.h"
+#include "chrome/browser/importer/firefox_importer_utils.h"
#include "base/logging.h"
// static
const wchar_t NSSDecryptor::kNSS3Library[] = L"libnss3.dylib";
-const wchar_t NSSDecryptor::kSoftokn3Library[] = L"libsoftokn3.dylib";
-const wchar_t NSSDecryptor::kPLDS4Library[] = L"libplds4.dylib";
-const wchar_t NSSDecryptor::kNSPR4Library[] = L"libnspr4.dylib";
+// Important!! : On OS X the nss3 libraries are compiled with depedencies
+// on one another, referenced using dyld's @executable_path directive.
+// To make a long story short in order to get the libraries to load, dyld's
+// fallback path needs to be set to the directory containing the libraries.
+// To do so, the process this function runs in must have the
+// DYLD_FALLBACK_LIBRARY_PATH set on startup to said directory.
bool NSSDecryptor::Init(const std::wstring& dll_path,
const std::wstring& db_path) {
- // TODO(port): Load the NSS libraries and call InitNSS()
- // http://code.google.com/p/chromium/issues/detail?id=15455
- NOTIMPLEMENTED();
- return false;
+ FilePath dylib_file_path = FilePath::FromWStringHack(dll_path);
+ FilePath nss3_path = dylib_file_path.Append("libnss3.dylib");
+
+ void *nss_3_lib = dlopen(nss3_path.value().c_str(), RTLD_LAZY);
+ if (!nss_3_lib) {
+ LOG(ERROR) << "Failed to load nss3 lib" << dlerror();
+ return false;
+ }
+
+ NSS_Init = (NSSInitFunc)dlsym(nss_3_lib, "NSS_Init");
+ NSS_Shutdown = (NSSShutdownFunc)dlsym(nss_3_lib, "NSS_Shutdown");
+ PK11_GetInternalKeySlot =
+ (PK11GetInternalKeySlotFunc)dlsym(nss_3_lib, "PK11_GetInternalKeySlot");
+ PK11_CheckUserPassword =
+ (PK11CheckUserPasswordFunc)dlsym(nss_3_lib, "PK11_CheckUserPassword");
+ PK11_FreeSlot = (PK11FreeSlotFunc)dlsym(nss_3_lib, "PK11_FreeSlot");
+ PK11_Authenticate =
+ (PK11AuthenticateFunc)dlsym(nss_3_lib, "PK11_Authenticate");
+ PK11SDR_Decrypt = (PK11SDRDecryptFunc)dlsym(nss_3_lib, "PK11SDR_Decrypt");
+ SECITEM_FreeItem = (SECITEMFreeItemFunc)dlsym(nss_3_lib, "SECITEM_FreeItem");
+
+ if (!NSS_Init || !NSS_Shutdown || !PK11_GetInternalKeySlot ||
+ !PK11_CheckUserPassword || !PK11_FreeSlot || !PK11_Authenticate ||
+ !PK11SDR_Decrypt || !SECITEM_FreeItem) {
+ LOG(ERROR) << "NSS3 importer couldn't find entry points";
+ return false;
+ }
+
+ SECStatus result = NSS_Init(base::SysWideToNativeMB(db_path).c_str());
+
+ if (result != SECSuccess) {
+ LOG(ERROR) << "NSS_Init Failed returned: " << result;
+ return false;
+ }
+
+ is_nss_initialized_ = true;
+ return true;
+}
+
+NSSDecryptor::~NSSDecryptor() {
+ if (NSS_Shutdown && is_nss_initialized_) {
+ NSS_Shutdown();
+ is_nss_initialized_ = false;
+ }
}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 93190d3..a833360 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -3931,7 +3931,10 @@
'browser/history/url_database_unittest.cc',
'browser/history/visit_database_unittest.cc',
'browser/history/visit_tracker_unittest.cc',
+ 'browser/importer/firefox_importer_unittest_messages_internal.h',
'browser/importer/firefox_importer_unittest.cc',
+ 'browser/importer/firefox_importer_unittest_utils.h',
+ 'browser/importer/firefox_importer_unittest_utils_mac.cc',
'browser/importer/importer_unittest.cc',
'browser/importer/safari_importer_unittest.mm',
'browser/importer/toolbar_importer_unittest.cc',
diff --git a/chrome/test/data/firefox2_nss_mac/README b/chrome/test/data/firefox2_nss_mac/README
new file mode 100644
index 0000000..74e6b27
--- /dev/null
+++ b/chrome/test/data/firefox2_nss_mac/README
@@ -0,0 +1,7 @@
+The NSPR and NSS DLLs in this directory (libnspr4.dylib, libnssdbm3.dylib, libplc4.dylib, libsoftokn3.dylib
+libfreebl3.dylib, libnss3.dylib, libnssutil3.dylib, libplds4.dylib, libsqlite3.dylib) come from the Firefox 2.0.0.20
+distribution for OS X.
+
+The source code of NSPR and NSS, which you may use, modify, and distribute, is
+available to you free-of-charge from www.mozilla.org under the Mozilla Public
+License and other open source software licenses.
diff --git a/chrome/test/data/firefox2_nss_mac/libfreebl3.dylib b/chrome/test/data/firefox2_nss_mac/libfreebl3.dylib
new file mode 100755
index 0000000..1eb3bc9
--- /dev/null
+++ b/chrome/test/data/firefox2_nss_mac/libfreebl3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox2_nss_mac/libnspr4.dylib b/chrome/test/data/firefox2_nss_mac/libnspr4.dylib
new file mode 100755
index 0000000..7d1653f
--- /dev/null
+++ b/chrome/test/data/firefox2_nss_mac/libnspr4.dylib
Binary files differ
diff --git a/chrome/test/data/firefox2_nss_mac/libnss3.dylib b/chrome/test/data/firefox2_nss_mac/libnss3.dylib
new file mode 100755
index 0000000..4406d2a
--- /dev/null
+++ b/chrome/test/data/firefox2_nss_mac/libnss3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox2_nss_mac/libplc4.dylib b/chrome/test/data/firefox2_nss_mac/libplc4.dylib
new file mode 100755
index 0000000..642f84e
--- /dev/null
+++ b/chrome/test/data/firefox2_nss_mac/libplc4.dylib
Binary files differ
diff --git a/chrome/test/data/firefox2_nss_mac/libplds4.dylib b/chrome/test/data/firefox2_nss_mac/libplds4.dylib
new file mode 100755
index 0000000..7d932a4
--- /dev/null
+++ b/chrome/test/data/firefox2_nss_mac/libplds4.dylib
Binary files differ
diff --git a/chrome/test/data/firefox2_nss_mac/libsoftokn3.dylib b/chrome/test/data/firefox2_nss_mac/libsoftokn3.dylib
new file mode 100755
index 0000000..de32c01
--- /dev/null
+++ b/chrome/test/data/firefox2_nss_mac/libsoftokn3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/README b/chrome/test/data/firefox3_nss_mac/README
new file mode 100644
index 0000000..b54a99e
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/README
@@ -0,0 +1,13 @@
+The NSPR and NSS DLLs in this directory (mozcrt19.dll, nss3.dll, nssutil3.dll
+plds4.dll, sqlite3.dll, freebl3.dll, nspr4.dll, nssdbm3.dll, plc4.dll, and
+softokn3.dll) come from the Firefox 3.0 distribution for Windows.
+
+The source code of NSPR and NSS, which you may use, modify, and distribute, is
+available to you free-of-charge from www.mozilla.org under the Mozilla Public
+License and other open source software licenses.
+
+The source code of sqlite3.dll is in the public domain.
+
+mozcrt19.dll is the Mozilla Custom C Runtime, in which Mozilla replaced the
+default allocator with jemalloc. mozcrt19.dll is distributed in the object
+code form only and as part of the NSPR and NSS DLLs.
diff --git a/chrome/test/data/firefox3_nss_mac/libfreebl3.dylib b/chrome/test/data/firefox3_nss_mac/libfreebl3.dylib
new file mode 100755
index 0000000..702d231
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libfreebl3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libnspr4.dylib b/chrome/test/data/firefox3_nss_mac/libnspr4.dylib
new file mode 100755
index 0000000..5484689
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libnspr4.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libnss3.dylib b/chrome/test/data/firefox3_nss_mac/libnss3.dylib
new file mode 100755
index 0000000..d18c65c
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libnss3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libnssdbm3.dylib b/chrome/test/data/firefox3_nss_mac/libnssdbm3.dylib
new file mode 100755
index 0000000..e7f7cb7
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libnssdbm3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libnssutil3.dylib b/chrome/test/data/firefox3_nss_mac/libnssutil3.dylib
new file mode 100755
index 0000000..0e6e48f
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libnssutil3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libplc4.dylib b/chrome/test/data/firefox3_nss_mac/libplc4.dylib
new file mode 100755
index 0000000..e5bf110
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libplc4.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libplds4.dylib b/chrome/test/data/firefox3_nss_mac/libplds4.dylib
new file mode 100755
index 0000000..fc65226
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libplds4.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libsoftokn3.dylib b/chrome/test/data/firefox3_nss_mac/libsoftokn3.dylib
new file mode 100755
index 0000000..91a3b81
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libsoftokn3.dylib
Binary files differ
diff --git a/chrome/test/data/firefox3_nss_mac/libsqlite3.dylib b/chrome/test/data/firefox3_nss_mac/libsqlite3.dylib
new file mode 100755
index 0000000..4f6d5eb
--- /dev/null
+++ b/chrome/test/data/firefox3_nss_mac/libsqlite3.dylib
Binary files differ
diff --git a/ipc/ipc_sync_message_unittest.h b/ipc/ipc_sync_message_unittest.h
index 7b252b5..06c9af0 100644
--- a/ipc/ipc_sync_message_unittest.h
+++ b/ipc/ipc_sync_message_unittest.h
@@ -95,4 +95,4 @@ IPC_BEGIN_MESSAGES(Test)
IPC_SYNC_MESSAGE_ROUTED3_3(Msg_R_3_3, int, std::string, bool, std::string,
int, bool)
-IPC_END_MESSAGES(TestMsg)
+IPC_END_MESSAGES(Test)
diff --git a/ipc/ipc_tests.cc b/ipc/ipc_tests.cc
index 172284e..7094308 100644
--- a/ipc/ipc_tests.cc
+++ b/ipc/ipc_tests.cc
@@ -270,7 +270,7 @@ TEST_F(IPCChannelTest, ChannelProxyTest) {
L"RunTestClient",
fds_to_map,
debug_on_start);
-#endif // defined(OS_POXIX)
+#endif // defined(OS_POSIX)
ASSERT_TRUE(process_handle);