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) 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/importer/firefox_importer_unittest_utils.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_switches.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/scoped_file.h" 139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/posix/global_descriptors.h" 1558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/kill.h" 1658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/launch.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/importer/firefox_importer_utils.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_descriptors.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_listener.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_multiprocess_test.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/multiprocess_func_list.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_MESSAGE_IMPL 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/importer/firefox_importer_unittest_messages_internal.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Name of IPC Channel to use for Server<-> Child Communications. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTestChannelID[] = "T1"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Launch the child process: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |nss_path| - path to the NSS directory holding the decryption libraries. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |channel| - IPC Channel to use for communication. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |handle| - On return, the process handle to use to communicate with the 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// child. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool LaunchNSSDecrypterChildProcess(const base::FilePath& nss_path, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Channel* channel, base::ProcessHandle* handle) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine cl(*CommandLine::ForCurrentProcess()); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cl.AppendSwitchASCII(switches::kTestChildProcess, "NSSDecrypterChildProcess"); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set env variable needed for FF encryption libs to load. 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // See "chrome/utility/importer/nss_decryptor_mac.mm" for an explanation of 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // why we need this. 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::LaunchOptions options; 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) options.environ["DYLD_FALLBACK_LIBRARY_PATH"] = nss_path.value(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD ipcfd(channel->TakeClientFileDescriptor()); 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!ipcfd.is_valid()) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::FileHandleMappingVector fds_to_map; 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fds_to_map.push_back(std::pair<int,int>(ipcfd.get(), 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.fds_to_remap = &fds_to_map; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::LaunchProcess(cl.argv(), options, handle); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------- Server -------------------- 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class to communicate on the server side of the IPC Channel. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Method calls are sent over IPC and replies are read back into class 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// variables. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class needs to be called on a single thread. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FFDecryptorServerChannelListener : public IPC::Listener { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FFDecryptorServerChannelListener() 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : got_result(false), sender_(NULL) {} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetSender(IPC::Sender* sender) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender_ = sender; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnInitDecryptorResponse(bool result) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!got_result); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_bool = result; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_result = true; 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void OnDecryptedTextResponse(const base::string16& decrypted_text) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!got_result); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_string = decrypted_text; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_result = true; 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void OnParseSignonsResponse( 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::vector<autofill::PasswordForm>& parsed_vector) { 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!got_result); 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result_vector = parsed_vector; 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) got_result = true; 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->Quit(); 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void QuitClient() { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender_) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender_->Send(new Msg_Decryptor_Quit()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(FFDecryptorServerChannelListener, msg) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(Msg_Decryptor_InitReturnCode, OnInitDecryptorResponse) 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IPC_MESSAGE_HANDLER(Msg_Decryptor_Response, OnDecryptedTextResponse) 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IPC_MESSAGE_HANDLER(Msg_ParseSignons_Response, OnParseSignonsResponse) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If an error occured, just kill the message Loop. 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnChannelError() OVERRIDE { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_result = false; 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Results of IPC calls. 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 result_string; 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<autofill::PasswordForm> result_vector; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result_bool; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if IPC call succeeded and data in above variables is valid. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool got_result; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Sender* sender_; // weak 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FFUnitTestDecryptorProxy::FFUnitTestDecryptorProxy() 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : child_process_(0) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FFUnitTestDecryptorProxy::Setup(const base::FilePath& nss_path) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a new message loop and spawn the child process. 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) message_loop_.reset(new base::MessageLoopForIO()); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_.reset(new FFDecryptorServerChannelListener()); 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) channel_ = IPC::Channel::CreateServer(kTestChannelID, listener_.get()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(channel_->Connect()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->SetSender(channel_.get()); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spawn child and set up sync IPC connection. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = LaunchNSSDecrypterChildProcess(nss_path, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_.get(), 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &child_process_); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret && (child_process_ != 0); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FFUnitTestDecryptorProxy::~FFUnitTestDecryptorProxy() { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->QuitClient(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->Close(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child_process_) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitForSingleProcess(child_process_, base::TimeDelta::FromSeconds(5)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CloseProcessHandle(child_process_); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A message_loop task that quits the message loop when invoked, setting cancel 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// causes the task to do nothing when invoked. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CancellableQuitMsgLoop : public base::RefCounted<CancellableQuitMsgLoop> { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancellableQuitMsgLoop() : cancelled_(false) {} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void QuitNow() { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cancelled_) 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool cancelled_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<CancellableQuitMsgLoop>; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~CancellableQuitMsgLoop() {} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Spin until either a client response arrives or a timeout occurs. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FFUnitTestDecryptorProxy::WaitForClientResponse() { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // What we're trying to do here is to wait for an RPC message to go over the 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wire and the client to reply. If the client does not reply by a given 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout we kill the message loop. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The way we do this is to post a CancellableQuitMsgLoop for 3 seconds in 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the future and cancel it if an RPC message comes back earlier. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This relies on the IPC listener class to quit the message loop itself when 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a message comes in. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<CancellableQuitMsgLoop> quit_task( 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CancellableQuitMsgLoop()); 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CancellableQuitMsgLoop::QuitNow, quit_task.get()), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTimeouts::action_max_timeout()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_->Run(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = !quit_task->cancelled_; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_task->cancelled_ = false; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FFUnitTestDecryptorProxy::DecryptorInit(const base::FilePath& dll_path, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& db_path) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->Send(new Msg_Decryptor_Init(dll_path, db_path)); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ok = WaitForClientResponse(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ok && listener_->got_result) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->got_result = false; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return listener_->result_bool; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 FFUnitTestDecryptorProxy::Decrypt(const std::string& crypt) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->Send(new Msg_Decrypt(crypt)); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ok = WaitForClientResponse(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ok && listener_->got_result) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->got_result = false; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return listener_->result_string; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::string16(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::vector<autofill::PasswordForm> FFUnitTestDecryptorProxy::ParseSignons( 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const base::FilePath& signons_path) { 225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) channel_->Send(new Msg_ParseSignons(signons_path)); 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ok = WaitForClientResponse(); 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (ok && listener_->got_result) { 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) listener_->got_result = false; 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return listener_->result_vector; 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return std::vector<autofill::PasswordForm>(); 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//---------------------------- Child Process ----------------------- 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class to listen on the client side of the ipc channel, it calls through 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the NSSDecryptor and sends back a reply. 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FFDecryptorClientChannelListener : public IPC::Listener { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FFDecryptorClientChannelListener() 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : sender_(NULL) {} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetSender(IPC::Sender* sender) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender_ = sender; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnDecryptor_Init(base::FilePath dll_path, base::FilePath db_path) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = decryptor_.Init(dll_path, db_path); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender_->Send(new Msg_Decryptor_InitReturnCode(ret)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDecrypt(std::string crypt) { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 unencrypted_str = decryptor_.Decrypt(crypt); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender_->Send(new Msg_Decryptor_Response(unencrypted_str)); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void OnParseSignons(base::FilePath signons_path) { 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<autofill::PasswordForm> forms; 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) decryptor_.ReadAndParseSignons(signons_path, &forms); 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new Msg_ParseSignons_Response(forms)); 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnQuitRequest() { 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(FFDecryptorClientChannelListener, msg) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(Msg_Decryptor_Init, OnDecryptor_Init) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(Msg_Decrypt, OnDecrypt) 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IPC_MESSAGE_HANDLER(Msg_ParseSignons, OnParseSignons) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(Msg_Decryptor_Quit, OnQuitRequest) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnChannelError() OVERRIDE { 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSSDecryptor decryptor_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Sender* sender_; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Entry function in child process. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MULTIPROCESS_IPC_TEST_MAIN(NSSDecrypterChildProcess) { 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO main_message_loop; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FFDecryptorClientChannelListener listener; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<IPC::Channel> channel = IPC::Channel::CreateClient( 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kTestChannelID, &listener); 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(channel->Connect()); 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) listener.SetSender(channel.get()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // run message loop 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 303