This source file includes following definitions.
- ShouldShowDialog
- retry_
- Start
- GotPassword
- Done
- UnlockSlotsIfNecessary
- UnlockCertSlotIfNecessary
#include "chrome/browser/ui/crypto_module_password_dialog_nss.h"
#include <pk11pub.h>
#include "base/bind.h"
#include "base/logging.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/crypto_module.h"
#include "net/cert/x509_certificate.h"
using content::BrowserThread;
namespace {
bool ShouldShowDialog(const net::CryptoModule* module) {
return (PK11_NeedLogin(module->os_module_handle()) &&
!PK11_IsLoggedIn(module->os_module_handle(), NULL ));
}
class SlotUnlocker {
public:
SlotUnlocker(const net::CryptoModuleList& modules,
chrome::CryptoModulePasswordReason reason,
const net::HostPortPair& server,
gfx::NativeWindow parent,
const base::Closure& callback);
void Start();
private:
void GotPassword(const std::string& password);
void Done();
size_t current_;
net::CryptoModuleList modules_;
chrome::CryptoModulePasswordReason reason_;
net::HostPortPair server_;
gfx::NativeWindow parent_;
base::Closure callback_;
PRBool retry_;
};
SlotUnlocker::SlotUnlocker(const net::CryptoModuleList& modules,
chrome::CryptoModulePasswordReason reason,
const net::HostPortPair& server,
gfx::NativeWindow parent,
const base::Closure& callback)
: current_(0),
modules_(modules),
reason_(reason),
server_(server),
parent_(parent),
callback_(callback),
retry_(PR_FALSE) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
void SlotUnlocker::Start() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (; current_ < modules_.size(); ++current_) {
if (ShouldShowDialog(modules_[current_].get())) {
ShowCryptoModulePasswordDialog(
modules_[current_]->GetTokenName(),
retry_,
reason_,
server_.host(),
parent_,
base::Bind(&SlotUnlocker::GotPassword, base::Unretained(this)));
return;
}
}
Done();
}
void SlotUnlocker::GotPassword(const std::string& password) {
if (password.empty()) {
++current_;
Start();
return;
}
SECStatus rv = PK11_CheckUserPassword(modules_[current_]->os_module_handle(),
password.c_str());
if (rv == SECWouldBlock) {
retry_ = PR_TRUE;
Start();
return;
}
++current_;
Start();
}
void SlotUnlocker::Done() {
DCHECK_EQ(current_, modules_.size());
callback_.Run();
delete this;
}
}
namespace chrome {
void UnlockSlotsIfNecessary(const net::CryptoModuleList& modules,
chrome::CryptoModulePasswordReason reason,
const net::HostPortPair& server,
gfx::NativeWindow parent,
const base::Closure& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (size_t i = 0; i < modules.size(); ++i) {
if (ShouldShowDialog(modules[i].get())) {
(new SlotUnlocker(modules, reason, server, parent, callback))->Start();
return;
}
}
callback.Run();
}
void UnlockCertSlotIfNecessary(net::X509Certificate* cert,
chrome::CryptoModulePasswordReason reason,
const net::HostPortPair& server,
gfx::NativeWindow parent,
const base::Closure& callback) {
net::CryptoModuleList modules;
modules.push_back(net::CryptoModule::CreateFromHandle(
cert->os_cert_handle()->slot));
UnlockSlotsIfNecessary(modules, reason, server, parent, callback);
}
}