Chromium Code Reviews| Index: chrome/browser/ui/crypto_module_password_dialog_nss.cc |
| diff --git a/chrome/browser/ui/crypto_module_password_dialog_nss.cc b/chrome/browser/ui/crypto_module_password_dialog_nss.cc |
| index d0b1357dc2c5379033ecbd48e4c91f56555fc6fb..268b08b50a48061308e48658c25ce032ea714955 100644 |
| --- a/chrome/browser/ui/crypto_module_password_dialog_nss.cc |
| +++ b/chrome/browser/ui/crypto_module_password_dialog_nss.cc |
| @@ -13,12 +13,18 @@ |
| namespace { |
| +bool ShouldShowDialog(const net::CryptoModule* module) { |
| + // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. |
| + return (PK11_NeedLogin(module->os_module_handle()) && |
| + !PK11_IsLoggedIn(module->os_module_handle(), NULL /* wincx */)); |
| +} |
| + |
| // Basically an asynchronous implementation of NSS's PK11_DoPassword. |
| // Note: This currently handles only the simple case. See the TODOs in |
| // GotPassword for what is yet unimplemented. |
| class SlotUnlocker { |
| public: |
| - SlotUnlocker(net::CryptoModule* module, |
| + SlotUnlocker(const net::CryptoModuleList& modules, |
| browser::CryptoModulePasswordReason reason, |
| const std::string& host, |
| Callback0::Type* callback); |
| @@ -29,18 +35,20 @@ class SlotUnlocker { |
| void GotPassword(const char* password); |
| void Done(); |
| - scoped_refptr<net::CryptoModule> module_; |
| + size_t cur_; |
|
wtc
2011/03/02 03:33:28
Nit: the Style Guide seems to discourage this kind
mattm
2011/03/05 02:16:32
yeah, changed to current_
|
| + net::CryptoModuleList modules_; |
| browser::CryptoModulePasswordReason reason_; |
| std::string host_; |
| Callback0::Type* callback_; |
| PRBool retry_; |
| }; |
| -SlotUnlocker::SlotUnlocker(net::CryptoModule* module, |
| +SlotUnlocker::SlotUnlocker(const net::CryptoModuleList& modules, |
| browser::CryptoModulePasswordReason reason, |
| const std::string& host, |
| Callback0::Type* callback) |
| - : module_(module), |
| + : cur_(0), |
| + modules_(modules), |
| reason_(reason), |
| host_(host), |
| callback_(callback), |
| @@ -51,12 +59,18 @@ SlotUnlocker::SlotUnlocker(net::CryptoModule* module, |
| void SlotUnlocker::Start() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - ShowCryptoModulePasswordDialog( |
| - module_->GetTokenName(), |
| - retry_, |
| - reason_, |
| - host_, |
| - NewCallback(this, &SlotUnlocker::GotPassword)); |
| + for (; cur_ < modules_.size(); ++cur_) { |
| + if (ShouldShowDialog(modules_[cur_].get())) { |
| + ShowCryptoModulePasswordDialog( |
| + modules_[cur_]->GetTokenName(), |
| + retry_, |
| + reason_, |
| + host_, |
| + NewCallback(this, &SlotUnlocker::GotPassword)); |
| + return; |
| + } |
| + } |
| + Done(); |
| } |
| void SlotUnlocker::GotPassword(const char* password) { |
| @@ -66,12 +80,13 @@ void SlotUnlocker::GotPassword(const char* password) { |
| if (!password) { |
| // User cancelled entering password. Oh well. |
| - Done(); |
| + ++cur_; |
| + Start(); |
| return; |
| } |
| // TODO(mattm): handle protectedAuthPath |
| - SECStatus rv = PK11_CheckUserPassword(module_->os_module_handle(), |
| + SECStatus rv = PK11_CheckUserPassword(modules_[cur_]->os_module_handle(), |
| password); |
| if (rv == SECWouldBlock) { |
| // Incorrect password. Try again. |
| @@ -84,11 +99,13 @@ void SlotUnlocker::GotPassword(const char* password) { |
| // non-friendly slots. How important is that? |
| // Correct password (SECSuccess) or too many attempts/other failure |
| - // (SECFailure). Either way we're done. |
| - Done(); |
| + // (SECFailure). Either way we're done with this slot. |
| + ++cur_; |
| + Start(); |
| } |
| void SlotUnlocker::Done() { |
| + DCHECK_EQ(cur_, modules_.size()); |
| callback_->Run(); |
| delete this; |
| } |
| @@ -97,27 +114,28 @@ void SlotUnlocker::Done() { |
| namespace browser { |
| -void UnlockSlotIfNecessary(net::CryptoModule* module, |
| - browser::CryptoModulePasswordReason reason, |
| - const std::string& host, |
| - Callback0::Type* callback) { |
| +void UnlockSlotsIfNecessary(const net::CryptoModuleList& modules, |
| + browser::CryptoModulePasswordReason reason, |
| + const std::string& host, |
| + Callback0::Type* callback) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. |
| - if (PK11_NeedLogin(module->os_module_handle()) && |
| - !PK11_IsLoggedIn(module->os_module_handle(), NULL /* wincx */)) { |
| - (new SlotUnlocker(module, reason, host, callback))->Start(); |
| - } else { |
| - callback->Run(); |
| + for (size_t i = 0; i < modules.size(); ++i) { |
| + if (ShouldShowDialog(modules[i].get())) { |
| + (new SlotUnlocker(modules, reason, host, callback))->Start(); |
| + return; |
|
wtc
2011/03/02 03:33:28
BUG: this return statement causes us to not unlock
mattm
2011/03/05 02:16:32
The SlotUnlocker will unlock all the slots, this l
|
| + } |
| } |
| + callback->Run(); |
| } |
| void UnlockCertSlotIfNecessary(net::X509Certificate* cert, |
| browser::CryptoModulePasswordReason reason, |
| const std::string& host, |
| Callback0::Type* callback) { |
| - scoped_refptr<net::CryptoModule> module(net::CryptoModule::CreateFromHandle( |
| + net::CryptoModuleList modules; |
| + modules.push_back(net::CryptoModule::CreateFromHandle( |
| cert->os_cert_handle()->slot)); |
| - UnlockSlotIfNecessary(module.get(), reason, host, callback); |
| + UnlockSlotsIfNecessary(modules, reason, host, callback); |
| } |
| } // namespace browser |