password_store_win.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_win.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/string_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/browser/webdata/web_data_service.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/os_crypt/ie7_password_win.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/password_manager/core/browser/password_manager.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using autofill::PasswordForm;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handles requests to WebDataService.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PasswordStoreWin::DBHandler : public WebDataServiceConsumer {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DBHandler(WebDataService* web_data_service,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PasswordStoreWin* password_store)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : web_data_service_(web_data_service),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        password_store_(password_store) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~DBHandler();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Requests the IE7 login for |form|. This is async. |callback_runner| will be
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // run when complete.
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void GetIE7Login(
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const PasswordForm& form,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const PasswordStoreWin::ConsumerCallbackRunner& callback_runner);
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct RequestInfo {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RequestInfo() {}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RequestInfo(PasswordForm* request_form,
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                const PasswordStoreWin::ConsumerCallbackRunner& runner)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : form(request_form),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback_runner(runner) {}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PasswordForm* form;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PasswordStoreWin::ConsumerCallbackRunner callback_runner;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Holds info associated with in-flight GetIE7Login requests.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<WebDataService::Handle, RequestInfo> PendingRequestMap;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets logins from IE7 if no others are found. Also copies them into
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome's WebDatabase so we don't need to look next time.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<autofill::PasswordForm*> GetIE7Results(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const WDTypedResult* result,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const PasswordForm& form);
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // WebDataServiceConsumer implementation.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWebDataServiceRequestDone(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebDataService::Handle handle,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const WDTypedResult* result) OVERRIDE;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<WebDataService> web_data_service_;
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This creates a cycle between us and PasswordStore. The cycle is broken
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from PasswordStoreWin::Shutdown, which deletes us.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PasswordStoreWin> password_store_;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingRequestMap pending_requests_;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DBHandler);
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStoreWin::DBHandler::~DBHandler() {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (PendingRequestMap::const_iterator i = pending_requests_.begin();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != pending_requests_.end();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_data_service_->CancelRequest(i->first);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete i->second.form;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PasswordStoreWin::DBHandler::GetIE7Login(
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const PasswordForm& form,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PasswordStoreWin::ConsumerCallbackRunner& callback_runner) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IE7PasswordInfo info;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.url_hash =
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ie7_password::GetUrlHash(base::UTF8ToWide(form.origin.spec()));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebDataService::Handle handle = web_data_service_->GetIE7Login(info, this);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_requests_[handle] =
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RequestInfo(new PasswordForm(form), callback_runner);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<PasswordForm*> PasswordStoreWin::DBHandler::GetIE7Results(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WDTypedResult *result,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PasswordForm& form) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<PasswordForm*> matching_forms;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WDResult<IE7PasswordInfo>* r =
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const WDResult<IE7PasswordInfo>*>(result);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IE7PasswordInfo info = r->GetValue();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!info.encrypted_data.empty()) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We got a result.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Delete the entry. If it's good we will add it to the real saved password
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // table.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_data_service_->RemoveIE7Login(info);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<ie7_password::DecryptedCredentials> credentials;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring url = base::ASCIIToWide(form.origin.spec());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ie7_password::DecryptPasswords(url,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       info.encrypted_data,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &credentials)) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t i = 0; i < credentials.size(); ++i) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PasswordForm* autofill = new PasswordForm();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        autofill->username_value = credentials[i].username;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        autofill->password_value = credentials[i].password;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        autofill->signon_realm = form.signon_realm;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        autofill->origin = form.origin;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        autofill->preferred = true;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        autofill->ssl_valid = form.origin.SchemeIsSecure();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        autofill->date_created = info.date_created;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        matching_forms.push_back(autofill);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Add this PasswordForm to the saved password table. We're on the DB
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // thread already, so we use AddLoginImpl.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        password_store_->AddLoginImpl(*autofill);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return matching_forms;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreWin::DBHandler::OnWebDataServiceRequestDone(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebDataService::Handle handle,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WDTypedResult* result) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PendingRequestMap::iterator i = pending_requests_.find(handle);
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(i != pending_requests_.end());
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<PasswordForm> form(i->second.form);
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PasswordStoreWin::ConsumerCallbackRunner callback_runner(
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      i->second.callback_runner);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_requests_.erase(i);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The WDS returns NULL if it is shutting down. Run callback with empty
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // result.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_runner.Run(std::vector<autofill::PasswordForm*>());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(PASSWORD_IE7_RESULT, result->GetType());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<autofill::PasswordForm*> matched_forms =
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetIE7Results(result, *form);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_runner.Run(matched_forms);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStoreWin::PasswordStoreWin(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoginDatabase* login_database,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebDataService* web_data_service)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : PasswordStoreDefault(main_thread_runner,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           db_thread_runner,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           login_database) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_handler_.reset(new DBHandler(web_data_service, this));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStoreWin::~PasswordStoreWin() {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreWin::ShutdownOnDBThread() {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_handler_.reset();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreWin::Shutdown() {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PasswordStoreWin::ShutdownOnDBThread, this));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PasswordStoreDefault::Shutdown();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreWin::GetIE7LoginIfNecessary(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PasswordForm& form,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ConsumerCallbackRunner& callback_runner,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<autofill::PasswordForm*>& matched_forms) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (matched_forms.empty() && db_handler_.get()) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    db_handler_->GetIE7Login(form, callback_runner);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No need to get IE7 login.
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback_runner.Run(matched_forms);
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid PasswordStoreWin::GetLoginsImpl(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PasswordForm& form,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthorizationPromptPolicy prompt_policy,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ConsumerCallbackRunner& callback_runner) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConsumerCallbackRunner get_ie7_login =
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PasswordStoreWin::GetIE7LoginIfNecessary,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this, form, callback_runner);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PasswordStoreDefault::GetLoginsImpl(form, prompt_policy, get_ie7_login);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)