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