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)