Home | History | Annotate | Download | only in ui
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/crypto_module_password_dialog.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/bind.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "base/synchronization/waitable_event.h"
     11 #include "content/public/browser/browser_thread.h"
     12 #include "crypto/crypto_module_blocking_password_delegate.h"
     13 #include "grit/generated_resources.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 #include "url/gurl.h"
     16 
     17 using content::BrowserThread;
     18 
     19 namespace chrome {
     20 
     21 namespace {
     22 
     23 class CryptoModuleBlockingDialogDelegate
     24     : public crypto::CryptoModuleBlockingPasswordDelegate {
     25  public:
     26   CryptoModuleBlockingDialogDelegate(CryptoModulePasswordReason reason,
     27                                      const std::string& server)
     28       : event_(false, false),
     29         reason_(reason),
     30         server_(server),
     31         cancelled_(false) {
     32   }
     33 
     34   virtual ~CryptoModuleBlockingDialogDelegate() {
     35     // Make sure we clear the password in memory.
     36     password_.replace(0, password_.size(), password_.size(), 0);
     37   }
     38 
     39   // crypto::CryptoModuleBlockingDialogDelegate implementation.
     40   virtual std::string RequestPassword(const std::string& slot_name,
     41                                       bool retry,
     42                                       bool* cancelled) OVERRIDE {
     43     DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
     44     DCHECK(!event_.IsSignaled());
     45     event_.Reset();
     46 
     47     if (BrowserThread::PostTask(
     48             BrowserThread::UI, FROM_HERE,
     49             base::Bind(&CryptoModuleBlockingDialogDelegate::ShowDialog,
     50                        // We block on event_ until the task completes, so
     51                        // there's no need to ref-count.
     52                        base::Unretained(this),
     53                        slot_name,
     54                        retry))) {
     55       event_.Wait();
     56     }
     57     *cancelled = cancelled_;
     58     return password_;
     59   }
     60 
     61  private:
     62   void ShowDialog(const std::string& slot_name,
     63                   bool retry) {
     64     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     65     ShowCryptoModulePasswordDialog(
     66         slot_name, retry, reason_, server_,
     67         base::Bind(&CryptoModuleBlockingDialogDelegate::GotPassword,
     68                    // We block on event_ until the task completes, so
     69                    // there's no need to ref-count.
     70                    base::Unretained(this)));
     71   }
     72 
     73   void GotPassword(const char* password) {
     74     if (password)
     75       password_ = password;
     76     else
     77       cancelled_ = true;
     78     event_.Signal();
     79   }
     80 
     81   base::WaitableEvent event_;
     82   CryptoModulePasswordReason reason_;
     83   std::string server_;
     84   std::string password_;
     85   bool cancelled_;
     86 
     87   DISALLOW_COPY_AND_ASSIGN(CryptoModuleBlockingDialogDelegate);
     88 };
     89 
     90 }  // namespace
     91 
     92 crypto::CryptoModuleBlockingPasswordDelegate*
     93     NewCryptoModuleBlockingDialogDelegate(CryptoModulePasswordReason reason,
     94                                           const std::string& server) {
     95   return new CryptoModuleBlockingDialogDelegate(reason, server);
     96 }
     97 
     98 }  // namespace chrome
     99