| Index: chrome/browser/ui/pk11_password_dialog_nss.cc
|
| diff --git a/chrome/browser/ui/pk11_password_dialog_nss.cc b/chrome/browser/ui/pk11_password_dialog_nss.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1eeeff1d929b4b98c7ae062ac67f860b4c05b96d
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/pk11_password_dialog_nss.cc
|
| @@ -0,0 +1,123 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/ui/pk11_password_dialog.h"
|
| +
|
| +#include <pk11pub.h>
|
| +
|
| +#include "base/logging.h"
|
| +#include "chrome/browser/browser_thread.h"
|
| +#include "net/base/crypto_module.h"
|
| +#include "net/base/x509_certificate.h"
|
| +
|
| +namespace {
|
| +
|
| +// 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,
|
| + browser::PK11PasswordReason reason,
|
| + const std::string& host,
|
| + Callback0::Type* callback);
|
| +
|
| + void Start();
|
| +
|
| + private:
|
| + void GotPassword(const char* password);
|
| + void Done();
|
| +
|
| + scoped_refptr<net::CryptoModule> module_;
|
| + browser::PK11PasswordReason reason_;
|
| + std::string host_;
|
| + Callback0::Type* callback_;
|
| + PRBool retry_;
|
| +};
|
| +
|
| +SlotUnlocker::SlotUnlocker(net::CryptoModule* module,
|
| + browser::PK11PasswordReason reason,
|
| + const std::string& host,
|
| + Callback0::Type* callback)
|
| + : module_(module),
|
| + reason_(reason),
|
| + host_(host),
|
| + callback_(callback),
|
| + retry_(PR_FALSE) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +}
|
| +
|
| +void SlotUnlocker::Start() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + ShowPK11PasswordDialog(
|
| + module_->GetTokenName(),
|
| + retry_,
|
| + reason_,
|
| + host_,
|
| + NewCallback(this, &SlotUnlocker::GotPassword));
|
| +}
|
| +
|
| +void SlotUnlocker::GotPassword(const char* password) {
|
| + // TODO(mattm): PK11_DoPassword has something about PK11_Global.verifyPass.
|
| + // Do we need it?
|
| + // http://mxr.mozilla.org/mozilla/source/security/nss/lib/pk11wrap/pk11auth.c#577
|
| +
|
| + if (!password) {
|
| + // User cancelled entering password. Oh well.
|
| + Done();
|
| + return;
|
| + }
|
| +
|
| + // TODO(mattm): handle protectedAuthPath
|
| + SECStatus rv = PK11_CheckUserPassword(module_->os_module_handle(),
|
| + password);
|
| + if (rv == SECWouldBlock) {
|
| + // Incorrect password. Try again.
|
| + retry_ = PR_TRUE;
|
| + Start();
|
| + return;
|
| + }
|
| +
|
| + // TODO(mattm): PK11_DoPassword calls nssTrustDomain_UpdateCachedTokenCerts on
|
| + // non-friendly slots. How important is that?
|
| +
|
| + // Correct password (SECSuccess) or too many attempts/other failure
|
| + // (SECFailure). Either way we're done.
|
| + Done();
|
| +}
|
| +
|
| +void SlotUnlocker::Done() {
|
| + callback_->Run();
|
| + delete this;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace browser {
|
| +
|
| +void UnlockSlotIfNecessary(net::CryptoModule* module,
|
| + browser::PK11PasswordReason 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();
|
| + }
|
| +}
|
| +
|
| +void UnlockCertSlotIfNecessary(net::X509Certificate* cert,
|
| + browser::PK11PasswordReason reason,
|
| + const std::string& host,
|
| + Callback0::Type* callback) {
|
| + scoped_refptr<net::CryptoModule> module(net::CryptoModule::CreateFromHandle(
|
| + cert->os_cert_handle()->slot));
|
| + UnlockSlotIfNecessary(module.get(), reason, host, callback);
|
| +}
|
| +
|
| +} // namespace browser
|
|
|