diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-13 21:19:40 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-13 21:19:40 +0000 |
commit | 7a593db3f93fc3ca3bb51d96ba32694b8568a0df (patch) | |
tree | 46f6f091ed336d593e84d1a018ff12d49e0ec3bd | |
parent | a2a220bbd154837c4f9e6eaf3e715cbe2ba9362c (diff) | |
download | chromium_src-7a593db3f93fc3ca3bb51d96ba32694b8568a0df.zip chromium_src-7a593db3f93fc3ca3bb51d96ba32694b8568a0df.tar.gz chromium_src-7a593db3f93fc3ca3bb51d96ba32694b8568a0df.tar.bz2 |
Remove knowledge about SSLClientAuthHandler from chrome. Instead a callback is given to the embedder to be run when the certificate is available.
BUG=98716
Review URL: https://chromiumcodereview.appspot.com/9384014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121733 0039d316-1c4b-4281-b951-d872f2087c98
35 files changed, 459 insertions, 478 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 1c131df..b415599 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -97,8 +97,6 @@ include_rules = [ "+content/browser/renderer_host/test_render_view_host.h", "+content/browser/speech/speech_input_manager.h", "+content/browser/speech/speech_recognizer.h", - "+content/browser/ssl/ssl_client_auth_handler.h", - "+content/browser/ssl/ssl_client_auth_handler_mock.h", "+content/browser/tab_contents/popup_menu_helper_mac.h", "+content/browser/tab_contents/provisional_load_details.h", "+content/browser/tab_contents/tab_contents_view_android.h", diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9a360de..7ce16a0 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -67,7 +67,6 @@ #include "chrome/common/url_constants.h" #include "content/browser/browser_url_handler.h" #include "content/browser/renderer_host/render_view_host.h" -#include "content/browser/ssl/ssl_client_auth_handler.h" #include "content/public/browser/browser_main_parts.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/render_process_host.h" @@ -79,6 +78,7 @@ #include "grit/ui_resources.h" #include "net/base/cookie_monster.h" #include "net/base/cookie_options.h" +#include "net/base/ssl_cert_request_info.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "webkit/glue/webpreferences.h" @@ -892,7 +892,9 @@ void ChromeContentBrowserClient::AllowCertificateError( void ChromeContentBrowserClient::SelectClientCertificate( int render_process_id, int render_view_id, - SSLClientAuthHandler* handler) { + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) { WebContents* tab = tab_util::GetWebContentsByID( render_process_id, render_view_id); if (!tab) { @@ -900,13 +902,11 @@ void ChromeContentBrowserClient::SelectClientCertificate( return; } - net::SSLCertRequestInfo* cert_request_info = handler->cert_request_info(); GURL requesting_url("https://" + cert_request_info->host_and_port); DCHECK(requesting_url.is_valid()) << "Invalid URL string: https://" << cert_request_info->host_and_port; Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); - DCHECK(profile); scoped_ptr<Value> filter( profile->GetHostContentSettingsMap()->GetWebsiteSetting( requesting_url, @@ -925,7 +925,7 @@ void ChromeContentBrowserClient::SelectClientCertificate( for (size_t i = 0; i < all_client_certs.size(); ++i) { if (CertMatchesFilter(*all_client_certs[i], *filter_dict)) { // Use the first certificate that is matched by the filter. - handler->CertificateSelected(all_client_certs[i]); + callback.Run(all_client_certs[i]); return; } } @@ -940,10 +940,11 @@ void ChromeContentBrowserClient::SelectClientCertificate( // If there is no TabContentsWrapper for the given WebContents then we can't // show the user a dialog to select a client certificate. So we simply // proceed with no client certificate. - handler->CertificateSelected(NULL); + callback.Run(NULL); return; } - wrapper->ssl_helper()->ShowClientCertificateRequestDialog(handler); + wrapper->ssl_helper()->ShowClientCertificateRequestDialog( + network_session, cert_request_info, callback); } void ChromeContentBrowserClient::AddNewCertificate( diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 9169d3d..a4638e8 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -89,7 +89,9 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { virtual void SelectClientCertificate( int render_process_id, int render_view_id, - SSLClientAuthHandler* handler) OVERRIDE; + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE; virtual void AddNewCertificate( net::URLRequest* request, net::X509Certificate* cert, diff --git a/chrome/browser/ssl/ssl_client_auth_observer.cc b/chrome/browser/ssl/ssl_client_auth_observer.cc new file mode 100644 index 0000000..3365641 --- /dev/null +++ b/chrome/browser/ssl/ssl_client_auth_observer.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2012 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/ssl/ssl_client_auth_observer.h" + +#include <utility> + +#include "base/bind.h" +#include "base/logging.h" +#include "chrome/common/chrome_notification_types.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/notification_service.h" +#include "net/base/ssl_cert_request_info.h" +#include "net/base/x509_certificate.h" + +using content::BrowserThread; + +typedef std::pair<net::SSLCertRequestInfo*, net::X509Certificate*> CertDetails; + +SSLClientAuthObserver::SSLClientAuthObserver( + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) + : network_session_(network_session), + cert_request_info_(cert_request_info), + callback_(callback) { +} + +SSLClientAuthObserver::~SSLClientAuthObserver() { +} + +void SSLClientAuthObserver::CertificateSelected( + net::X509Certificate* certificate) { + if (callback_.is_null()) + return; + + // Stop listening right away so we don't get our own notification. + StopObserving(); + + CertDetails details; + details.first = cert_request_info_; + details.second = certificate; + content::NotificationService* service = + content::NotificationService::current(); + service->Notify(chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, + content::Source<net::HttpNetworkSession>(network_session_), + content::Details<CertDetails>(&details)); + + callback_.Run(certificate); + callback_.Reset(); +} + +void SSLClientAuthObserver::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + VLOG(1) << "SSLClientAuthObserver::Observe " << this; + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(type == chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED); + + CertDetails* cert_details = content::Details<CertDetails>(details).ptr(); + if (cert_details->first->host_and_port != cert_request_info_->host_and_port) + return; + + VLOG(1) << this << " got matching notification and selecting cert " + << cert_details->second; + StopObserving(); + callback_.Run(cert_details->second); + callback_.Reset(); + OnCertSelectedByNotification(); +} + +void SSLClientAuthObserver::StartObserving() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + notification_registrar_.Add( + this, chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, + content::Source<net::HttpNetworkSession>(network_session_)); +} + +void SSLClientAuthObserver::StopObserving() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + notification_registrar_.RemoveAll(); +} diff --git a/chrome/browser/ssl/ssl_client_auth_observer.h b/chrome/browser/ssl/ssl_client_auth_observer.h new file mode 100644 index 0000000..637e998 --- /dev/null +++ b/chrome/browser/ssl/ssl_client_auth_observer.h @@ -0,0 +1,64 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_OBSERVER_H_ +#define CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_OBSERVER_H_ +#pragma once + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +namespace net { +class HttpNetworkSession; +class SSLCertRequestInfo; +class X509Certificate; +} + +class SSLClientAuthObserver : public content::NotificationObserver { + public: + SSLClientAuthObserver( + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback); + virtual ~SSLClientAuthObserver(); + + // UI should implement this to close the dialog. + virtual void OnCertSelectedByNotification() = 0; + + // Send content the certificate. Can also call with NULL if the user + // cancelled. Derived classes must use this instead of caching the callback + // and calling it directly. + void CertificateSelected(net::X509Certificate* cert); + + // Begins observing notifications from other SSLClientAuthHandler instances. + // If another instance chooses a cert for a matching SSLCertRequestInfo, we + // will also use the same cert and OnCertSelectedByNotification will be called + // so that the cert selection UI can be closed. + void StartObserving(); + + // Stops observing notifications. We will no longer act on client auth + // notifications. + void StopObserving(); + + net::SSLCertRequestInfo* cert_request_info() const { + return cert_request_info_; + } + + private: + // content::NotificationObserver implementation: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + const net::HttpNetworkSession* network_session_; + scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; + base::Callback<void(net::X509Certificate*)> callback_; + content::NotificationRegistrar notification_registrar_; + + DISALLOW_COPY_AND_ASSIGN(SSLClientAuthObserver); +}; + +#endif // CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_OBSERVER_H_ diff --git a/chrome/browser/ssl/ssl_client_auth_requestor_mock.h b/chrome/browser/ssl/ssl_client_auth_requestor_mock.h new file mode 100644 index 0000000..fb487a4 --- /dev/null +++ b/chrome/browser/ssl/ssl_client_auth_requestor_mock.h @@ -0,0 +1,40 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_REQUESTOR_MOCK_H_ +#define CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_REQUESTOR_MOCK_H_ +#pragma once + +#include "base/memory/ref_counted.h" +#include "net/http/http_transaction_factory.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace net { +class SSLCertRequestInfo; +class X509Certificate; +} + +class SSLClientAuthRequestorMock + : public base::RefCountedThreadSafe<SSLClientAuthRequestorMock> { + public: + SSLClientAuthRequestorMock( + net::URLRequest* request, + net::SSLCertRequestInfo* cert_request_info) + : cert_request_info_(cert_request_info), + http_network_session_( + request->context()->http_transaction_factory()->GetSession()) { + } + // NOTE: we need a vtable or else gmock blows up. + virtual ~SSLClientAuthRequestorMock() { + } + + MOCK_METHOD1(CertificateSelected, void(net::X509Certificate* cert)); + + net::SSLCertRequestInfo* cert_request_info_; + net::HttpNetworkSession* http_network_session_; +}; + +#endif // CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_REQUESTOR_MOCK_H_ diff --git a/chrome/browser/ssl_client_certificate_selector.h b/chrome/browser/ssl_client_certificate_selector.h index 7f8e374..1a73b8a 100644 --- a/chrome/browser/ssl_client_certificate_selector.h +++ b/chrome/browser/ssl_client_certificate_selector.h @@ -6,24 +6,28 @@ #define CHROME_BROWSER_SSL_CLIENT_CERTIFICATE_SELECTOR_H_ #pragma once -class SSLClientAuthHandler; +#include "base/callback_forward.h" + class TabContentsWrapper; namespace net { +class HttpNetworkSession; class SSLCertRequestInfo; +class X509Certificate; } namespace browser { // Opens a constrained SSL client certificate selection dialog under |parent|, // offering certificates from |cert_request_info|. When the user has made a -// selection, the dialog will report back to |delegate|. |delegate| is notified +// selection, the dialog will report back to |callback|. |callback| is notified // when the dialog closes in call cases; if the user cancels the dialog, we call // with a NULL certificate. void ShowSSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate); + const base::Callback<void(net::X509Certificate*)>& callback); // Same as above, but doesn't check the UseMoreWebUI flag. It just calls the // native implementation. This lets us have both the WebUI implementation and @@ -31,8 +35,9 @@ void ShowSSLClientCertificateSelector( // a run-time flag. void ShowNativeSSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate); + const base::Callback<void(net::X509Certificate*)>& callback); } // namespace browser diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc index bf2ee29..6558b31 100644 --- a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc +++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc @@ -24,7 +24,6 @@ #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" -#include "content/browser/ssl/ssl_client_auth_handler.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" @@ -191,9 +190,11 @@ TabContentsSSLHelper::~TabContentsSSLHelper() { } void TabContentsSSLHelper::ShowClientCertificateRequestDialog( - scoped_refptr<SSLClientAuthHandler> handler) { + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) { browser::ShowSSLClientCertificateSelector( - tab_contents_, handler->cert_request_info(), handler); + tab_contents_, network_session, cert_request_info, callback); } void TabContentsSSLHelper::OnVerifyClientCertificateError( diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.h b/chrome/browser/tab_contents/tab_contents_ssl_helper.h index 6755deb..e250eae 100644 --- a/chrome/browser/tab_contents/tab_contents_ssl_helper.h +++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.h @@ -8,14 +8,20 @@ #include <map> +#include "base/callback_forward.h" #include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "content/public/browser/render_view_host_delegate.h" class SSLAddCertHandler; -class SSLClientAuthHandler; class TabContentsWrapper; +namespace net { +class HttpNetworkSession; +class SSLCertRequestInfo; +class X509Certificate; +} + class TabContentsSSLHelper { public: explicit TabContentsSSLHelper(TabContentsWrapper* tab_contents); @@ -50,7 +56,9 @@ class TabContentsSSLHelper { // Displays a dialog for selecting a client certificate and returns it to // the |handler|. void ShowClientCertificateRequestDialog( - scoped_refptr<SSLClientAuthHandler> handler); + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback); private: TabContentsWrapper* tab_contents_; diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm index e5367be..7a06059 100644 --- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm +++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm @@ -14,11 +14,12 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/ssl/ssl_client_auth_observer.h" #import "chrome/browser/ui/cocoa/constrained_window_mac.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "content/browser/ssl/ssl_client_auth_handler.h" #include "content/public/browser/browser_thread.h" #include "grit/generated_resources.h" +#include "net/base/ssl_cert_request_info.h" #include "net/base/x509_certificate.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -38,10 +39,6 @@ class NotificationProxy; @interface SSLClientCertificateSelectorCocoa : NSObject { @private - // The handler to report back to. - scoped_refptr<SSLClientAuthHandler> handler_; - // The certificate request we serve. - scoped_refptr<net::SSLCertRequestInfo> certRequestInfo_; // The list of identities offered to the user. scoped_nsobject<NSMutableArray> identities_; // The corresponding list of certificates. @@ -52,8 +49,9 @@ class NotificationProxy; scoped_ptr<NotificationProxy> observer_; } -- (id)initWithHandler:(SSLClientAuthHandler*)handler - certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo; +- (id)initWithObserver:(const net::HttpNetworkSession*)networkSession + certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo + callback:(const base::Callback<void(net::X509Certificate*)>&)callback; - (void)onNotification; - (void)displayDialog:(TabContentsWrapper*)wrapper; @end @@ -113,10 +111,11 @@ class ConstrainedSFChooseIdentityPanel class NotificationProxy : public SSLClientAuthObserver { public: - NotificationProxy(net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* handler, + NotificationProxy(const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback, SSLClientCertificateSelectorCocoa* controller) - : SSLClientAuthObserver(cert_request_info, handler), + : SSLClientAuthObserver(network_session, cert_request_info, callback), controller_(controller) { } @@ -135,13 +134,15 @@ namespace browser { void ShowSSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { + const base::Callback<void(net::X509Certificate*)>& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); SSLClientCertificateSelectorCocoa* selector = [[[SSLClientCertificateSelectorCocoa alloc] - initWithHandler:delegate - certRequestInfo:cert_request_info] autorelease]; + initWithObserver:network_session + certRequestInfo:cert_request_info + callback:callback] autorelease]; [selector displayDialog:wrapper]; } @@ -149,15 +150,15 @@ void ShowSSLClientCertificateSelector( @implementation SSLClientCertificateSelectorCocoa -- (id)initWithHandler:(SSLClientAuthHandler*)handler - certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo { - DCHECK(handler); +- (id)initWithObserver:(const net::HttpNetworkSession*)networkSession + certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo + callback:(const base::Callback<void(net::X509Certificate*)>&)callback { + DCHECK(networkSession); DCHECK(certRequestInfo); if ((self = [super init])) { - handler_ = handler; - certRequestInfo_ = certRequestInfo; window_ = NULL; - observer_.reset(new NotificationProxy(certRequestInfo, handler, self)); + observer_.reset(new NotificationProxy( + networkSession, certRequestInfo, callback, self)); } return self; } @@ -179,33 +180,29 @@ void ShowSSLClientCertificateSelector( // Finally, tell the backend which identity (or none) the user selected. observer_->StopObserving(); - if (handler_) { - handler_->CertificateSelected(cert); - handler_ = NULL; - } + observer_->CertificateSelected(cert); // Close the constrained window. DCHECK(window_); window_->CloseConstrainedWindow(); } - (void)onNotification { - handler_ = NULL; window_->CloseConstrainedWindow(); } - (void)displayDialog:(TabContentsWrapper*)wrapper { DCHECK(!window_); // Create an array of CFIdentityRefs for the certificates: - size_t numCerts = certRequestInfo_->client_certs.size(); + size_t numCerts = observer_->cert_request_info()->client_certs.size(); identities_.reset([[NSMutableArray alloc] initWithCapacity:numCerts]); for (size_t i = 0; i < numCerts; ++i) { SecCertificateRef cert; - cert = certRequestInfo_->client_certs[i]->os_cert_handle(); + cert = observer_->cert_request_info()->client_certs[i]->os_cert_handle(); SecIdentityRef identity; if (SecIdentityCreateWithCertificate(NULL, cert, &identity) == noErr) { [identities_ addObject:(id)identity]; CFRelease(identity); - certificates_.push_back(certRequestInfo_->client_certs[i]); + certificates_.push_back(observer_->cert_request_info()->client_certs[i]); } } @@ -213,7 +210,7 @@ void ShowSSLClientCertificateSelector( NSString* title = l10n_util::GetNSString(IDS_CLIENT_CERT_DIALOG_TITLE); NSString* message = l10n_util::GetNSStringF( IDS_CLIENT_CERT_DIALOG_TEXT, - ASCIIToUTF16(certRequestInfo_->host_and_port)); + ASCIIToUTF16(observer_->cert_request_info()->host_and_port)); // Create and set up a system choose-identity panel. SFChooseIdentityPanel* panel = [[SFChooseIdentityPanel alloc] init]; diff --git a/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc b/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc index bf130af..e578a26 100644 --- a/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc +++ b/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc @@ -14,14 +14,15 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" #include "chrome/browser/certificate_viewer.h" +#include "chrome/browser/ssl/ssl_client_auth_observer.h" #include "chrome/browser/ui/crypto_module_password_dialog.h" #include "chrome/browser/ui/gtk/constrained_window_gtk.h" #include "chrome/browser/ui/gtk/gtk_util.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/net/x509_certificate_model.h" -#include "content/browser/ssl/ssl_client_auth_handler.h" #include "content/public/browser/browser_thread.h" #include "grit/generated_resources.h" +#include "net/base/ssl_cert_request_info.h" #include "net/base/x509_certificate.h" #include "ui/base/gtk/gtk_compat.h" #include "ui/base/gtk/gtk_hig_constants.h" @@ -46,8 +47,9 @@ class SSLClientCertificateSelector : public SSLClientAuthObserver, public: explicit SSLClientCertificateSelector( TabContentsWrapper* parent, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate); + const base::Callback<void(net::X509Certificate*)>& callback); ~SSLClientCertificateSelector(); void Show(); @@ -81,15 +83,11 @@ class SSLClientCertificateSelector : public SSLClientAuthObserver, CHROMEGTK_CALLBACK_1(SSLClientCertificateSelector, void, OnPromptShown, GtkWidget*); - scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; - std::vector<std::string> details_strings_; GtkWidget* cert_combo_box_; GtkTextBuffer* cert_details_buffer_; - scoped_refptr<SSLClientAuthHandler> delegate_; - ui::OwnedWidgetGtk root_widget_; // Hold on to the select button to focus it. GtkWidget* select_button_; @@ -102,11 +100,10 @@ class SSLClientCertificateSelector : public SSLClientAuthObserver, SSLClientCertificateSelector::SSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) - : SSLClientAuthObserver(cert_request_info, delegate), - cert_request_info_(cert_request_info), - delegate_(delegate), + const base::Callback<void(net::X509Certificate*)>& callback) + : SSLClientAuthObserver(network_session, cert_request_info, callback), wrapper_(wrapper), window_(NULL) { root_widget_.Own(gtk_vbox_new(FALSE, ui::kControlSpacing)); @@ -204,7 +201,6 @@ void SSLClientCertificateSelector::Show() { } void SSLClientCertificateSelector::OnCertSelectedByNotification() { - delegate_ = NULL; DCHECK(window_); window_->CloseConstrainedWindow(); } @@ -214,28 +210,26 @@ GtkWidget* SSLClientCertificateSelector::GetFocusWidget() { } void SSLClientCertificateSelector::DeleteDelegate() { - if (delegate_) { - // The dialog was closed by escape key. - StopObserving(); - delegate_->CertificateSelected(NULL); - } + // The dialog was closed by escape key. + StopObserving(); + CertificateSelected(NULL); delete this; } void SSLClientCertificateSelector::PopulateCerts() { std::vector<std::string> nicknames; x509_certificate_model::GetNicknameStringsFromCertList( - cert_request_info_->client_certs, + cert_request_info()->client_certs, l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_EXPIRED), l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_NOT_YET_VALID), &nicknames); DCHECK_EQ(nicknames.size(), - cert_request_info_->client_certs.size()); + cert_request_info()->client_certs.size()); - for (size_t i = 0; i < cert_request_info_->client_certs.size(); ++i) { + for (size_t i = 0; i < cert_request_info()->client_certs.size(); ++i) { net::X509Certificate::OSCertHandle cert = - cert_request_info_->client_certs[i]->os_cert_handle(); + cert_request_info()->client_certs[i]->os_cert_handle(); details_strings_.push_back(FormatDetailsText(cert)); @@ -252,8 +246,8 @@ net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() { int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(cert_combo_box_)); if (selected >= 0 && selected < static_cast<int>( - cert_request_info_->client_certs.size())) - return cert_request_info_->client_certs[selected]; + cert_request_info()->client_certs.size())) + return cert_request_info()->client_certs[selected]; return NULL; } @@ -332,8 +326,7 @@ std::string SSLClientCertificateSelector::FormatDetailsText( void SSLClientCertificateSelector::Unlocked() { // TODO(mattm): refactor so we don't need to call GetSelectedCert again. net::X509Certificate* cert = GetSelectedCert(); - delegate_->CertificateSelected(cert); - delegate_ = NULL; + CertificateSelected(cert); DCHECK(window_); window_->CloseConstrainedWindow(); } @@ -357,9 +350,7 @@ void SSLClientCertificateSelector::OnViewClicked(GtkWidget* button) { } void SSLClientCertificateSelector::OnCancelClicked(GtkWidget* button) { - StopObserving(); - delegate_->CertificateSelected(NULL); - delegate_ = NULL; + CertificateSelected(NULL); DCHECK(window_); window_->CloseConstrainedWindow(); } @@ -375,7 +366,7 @@ void SSLClientCertificateSelector::OnOkClicked(GtkWidget* button) { browser::UnlockCertSlotIfNecessary( cert, browser::kCryptoModulePasswordClientAuth, - cert_request_info_->host_and_port, + cert_request_info()->host_and_port, base::Bind(&SSLClientCertificateSelector::Unlocked, base::Unretained(this))); } @@ -398,12 +389,12 @@ namespace browser { void ShowNativeSSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { + const base::Callback<void(net::X509Certificate*)>& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - (new SSLClientCertificateSelector(wrapper, - cert_request_info, - delegate))->Show(); + (new SSLClientCertificateSelector( + wrapper, network_session, cert_request_info, callback))->Show(); } } // namespace browser diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.cc b/chrome/browser/ui/views/ssl_client_certificate_selector.cc index a6ed87c..a70d769 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector.cc +++ b/chrome/browser/ui/views/ssl_client_certificate_selector.cc @@ -15,6 +15,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" #include "grit/generated_resources.h" +#include "net/base/ssl_cert_request_info.h" #include "net/base/x509_certificate.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/table_model.h" @@ -88,11 +89,10 @@ void CertificateSelectorTableModel::SetObserver( SSLClientCertificateSelector::SSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) - : SSLClientAuthObserver(cert_request_info, delegate), - cert_request_info_(cert_request_info), - delegate_(delegate), + const base::Callback<void(net::X509Certificate*)>& callback) + : SSLClientAuthObserver(network_session, cert_request_info, callback), model_(new CertificateSelectorTableModel(cert_request_info)), wrapper_(wrapper), window_(NULL), @@ -119,7 +119,7 @@ void SSLClientCertificateSelector::Init() { layout->StartRow(0, column_set_id); string16 text = l10n_util::GetStringFUTF16( IDS_CLIENT_CERT_DIALOG_TEXT, - ASCIIToUTF16(cert_request_info_->host_and_port)); + ASCIIToUTF16(cert_request_info()->host_and_port)); views::Label* label = new views::Label(text); label->SetMultiLine(true); label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); @@ -151,8 +151,8 @@ net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() const { int selected = table_->FirstSelectedRow(); if (selected >= 0 && selected < static_cast<int>( - cert_request_info_->client_certs.size())) - return cert_request_info_->client_certs[selected]; + cert_request_info()->client_certs.size())) + return cert_request_info()->client_certs[selected]; return NULL; } @@ -161,7 +161,6 @@ net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() const { void SSLClientCertificateSelector::OnCertSelectedByNotification() { DVLOG(1) << __FUNCTION__; - delegate_ = NULL; DCHECK(window_); window_->CloseConstrainedWindow(); } @@ -192,10 +191,7 @@ bool SSLClientCertificateSelector::IsDialogButtonEnabled( bool SSLClientCertificateSelector::Cancel() { DVLOG(1) << __FUNCTION__; StopObserving(); - if (delegate_) { - delegate_->CertificateSelected(NULL); - delegate_ = NULL; - } + CertificateSelected(NULL); return true; } @@ -205,9 +201,7 @@ bool SSLClientCertificateSelector::Accept() { net::X509Certificate* cert = GetSelectedCert(); if (cert) { StopObserving(); - delegate_->CertificateSelected(GetSelectedCert()); - delegate_ = NULL; - + CertificateSelected(cert); return true; } @@ -291,13 +285,13 @@ namespace browser { void ShowNativeSSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { + const base::Callback<void(net::X509Certificate*)>& callback) { DVLOG(1) << __FUNCTION__ << " " << wrapper; DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - (new SSLClientCertificateSelector(wrapper, - cert_request_info, - delegate))->Init(); + (new SSLClientCertificateSelector( + wrapper, network_session, cert_request_info, callback))->Init(); } #if !defined(USE_NSS) && !defined(USE_OPENSSL) @@ -305,9 +299,11 @@ void ShowNativeSSLClientCertificateSelector( // under these conditions. Add stub implementation for the required method. void ShowSSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { - ShowNativeSSLClientCertificateSelector(wrapper, cert_request_info, delegate); + const base::Callback<void(net::X509Certificate*)>& callback) { + ShowNativeSSLClientCertificateSelector( + wrapper, network_session, cert_request_info, callback); } #endif diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.h b/chrome/browser/ui/views/ssl_client_certificate_selector.h index d06ee45..58f96af 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector.h +++ b/chrome/browser/ui/views/ssl_client_certificate_selector.h @@ -12,7 +12,7 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/string16.h" -#include "content/browser/ssl/ssl_client_auth_handler.h" +#include "chrome/browser/ssl/ssl_client_auth_observer.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/table/table_view_observer.h" #include "ui/views/view.h" @@ -22,6 +22,11 @@ // certificate selector only through the cross-platform interface // chrome/browser/ssl_client_certificate_selector.h. +namespace net { +class SSLCertRequestInfo; +class X509Certificate; +} + namespace views { class TableView; class TextButton; @@ -38,8 +43,9 @@ class SSLClientCertificateSelector : public SSLClientAuthObserver, public: SSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate); + const base::Callback<void(net::X509Certificate*)>& callback); virtual ~SSLClientCertificateSelector(); void Init(); @@ -72,10 +78,6 @@ class SSLClientCertificateSelector : public SSLClientAuthObserver, void CreateCertTable(); void CreateViewCertButton(); - scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; - - scoped_refptr<SSLClientAuthHandler> delegate_; - scoped_ptr<CertificateSelectorTableModel> model_; TabContentsWrapper* wrapper_; diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc b/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc index 45e1e1a..bba2828 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc +++ b/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc @@ -6,18 +6,19 @@ #include "base/file_path.h" #include "base/synchronization/waitable_event.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ssl/ssl_client_auth_requestor_mock.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/ssl_client_certificate_selector.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "content/browser/ssl/ssl_client_auth_handler_mock.h" #include "content/public/browser/web_contents.h" #include "net/base/cert_test_util.h" +#include "net/base/ssl_cert_request_info.h" #include "net/base/x509_certificate.h" +#include "net/http/http_transaction_factory.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using ::testing::Mock; @@ -62,8 +63,10 @@ class SSLClientCertificateSelectorTest : public InProcessBrowserTest { ui_test_utils::WaitForLoadStop(browser()->GetSelectedWebContents()); selector_ = new SSLClientCertificateSelector( browser()->GetSelectedTabContentsWrapper(), - cert_request_info_, - auth_handler_); + auth_requestor_->http_network_session_, + auth_requestor_->cert_request_info_, + base::Bind(&SSLClientAuthRequestorMock::CertificateSelected, + auth_requestor_)); selector_->Init(); EXPECT_EQ(mit_davidben_cert_.get(), selector_->GetSelectedCert()); @@ -72,7 +75,7 @@ class SSLClientCertificateSelectorTest : public InProcessBrowserTest { virtual void SetUpOnIOThread() { url_request_ = MakeURLRequest(url_request_context_getter_); - auth_handler_ = new StrictMock<SSLClientAuthHandlerMock>( + auth_requestor_ = new StrictMock<SSLClientAuthRequestorMock>( url_request_, cert_request_info_); @@ -88,7 +91,7 @@ class SSLClientCertificateSelectorTest : public InProcessBrowserTest { io_loop_finished_event_.Wait(); - auth_handler_ = NULL; + auth_requestor_ = NULL; } virtual void CleanUpOnIOThread() { @@ -114,7 +117,7 @@ class SSLClientCertificateSelectorTest : public InProcessBrowserTest { scoped_refptr<net::X509Certificate> mit_davidben_cert_; scoped_refptr<net::X509Certificate> foaf_me_chromium_test_cert_; scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; - scoped_refptr<StrictMock<SSLClientAuthHandlerMock> > auth_handler_; + scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_; // The selector will be deleted when a cert is selected or the tab is closed. SSLClientCertificateSelector* selector_; }; @@ -150,13 +153,17 @@ class SSLClientCertificateSelectorMultiTabTest selector_1_ = new SSLClientCertificateSelector( browser()->GetTabContentsWrapperAt(1), - cert_request_info_1_, - auth_handler_1_); + auth_requestor_1_->http_network_session_, + auth_requestor_1_->cert_request_info_, + base::Bind(&SSLClientAuthRequestorMock::CertificateSelected, + auth_requestor_1_)); selector_1_->Init(); selector_2_ = new SSLClientCertificateSelector( browser()->GetTabContentsWrapperAt(2), - cert_request_info_2_, - auth_handler_2_); + auth_requestor_2_->http_network_session_, + auth_requestor_2_->cert_request_info_, + base::Bind(&SSLClientAuthRequestorMock::CertificateSelected, + auth_requestor_2_)); selector_2_->Init(); EXPECT_EQ(2, browser()->active_index()); @@ -168,10 +175,10 @@ class SSLClientCertificateSelectorMultiTabTest url_request_1_ = MakeURLRequest(url_request_context_getter_); url_request_2_ = MakeURLRequest(url_request_context_getter_); - auth_handler_1_ = new StrictMock<SSLClientAuthHandlerMock>( + auth_requestor_1_ = new StrictMock<SSLClientAuthRequestorMock>( url_request_1_, cert_request_info_1_); - auth_handler_2_ = new StrictMock<SSLClientAuthHandlerMock>( + auth_requestor_2_ = new StrictMock<SSLClientAuthRequestorMock>( url_request_2_, cert_request_info_2_); @@ -179,8 +186,8 @@ class SSLClientCertificateSelectorMultiTabTest } virtual void CleanUpOnMainThread() { - auth_handler_2_ = NULL; - auth_handler_1_ = NULL; + auth_requestor_2_ = NULL; + auth_requestor_1_ = NULL; SSLClientCertificateSelectorTest::CleanUpOnMainThread(); } @@ -195,8 +202,8 @@ class SSLClientCertificateSelectorMultiTabTest net::URLRequest* url_request_2_; scoped_refptr<net::SSLCertRequestInfo> cert_request_info_1_; scoped_refptr<net::SSLCertRequestInfo> cert_request_info_2_; - scoped_refptr<StrictMock<SSLClientAuthHandlerMock> > auth_handler_1_; - scoped_refptr<StrictMock<SSLClientAuthHandlerMock> > auth_handler_2_; + scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_1_; + scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_2_; SSLClientCertificateSelector* selector_1_; SSLClientCertificateSelector* selector_2_; }; @@ -222,8 +229,10 @@ class SSLClientCertificateSelectorMultiProfileTest selector_1_ = new SSLClientCertificateSelector( browser_1_->GetSelectedTabContentsWrapper(), - cert_request_info_1_, - auth_handler_1_); + auth_requestor_1_->http_network_session_, + auth_requestor_1_->cert_request_info_, + base::Bind(&SSLClientAuthRequestorMock::CertificateSelected, + auth_requestor_1_)); selector_1_->Init(); EXPECT_EQ(mit_davidben_cert_.get(), selector_1_->GetSelectedCert()); @@ -232,7 +241,7 @@ class SSLClientCertificateSelectorMultiProfileTest virtual void SetUpOnIOThread() { url_request_1_ = MakeURLRequest(url_request_context_getter_1_); - auth_handler_1_ = new StrictMock<SSLClientAuthHandlerMock>( + auth_requestor_1_ = new StrictMock<SSLClientAuthRequestorMock>( url_request_1_, cert_request_info_1_); @@ -240,7 +249,7 @@ class SSLClientCertificateSelectorMultiProfileTest } virtual void CleanUpOnMainThread() { - auth_handler_1_ = NULL; + auth_requestor_1_ = NULL; SSLClientCertificateSelectorTest::CleanUpOnMainThread(); } @@ -254,62 +263,61 @@ class SSLClientCertificateSelectorMultiProfileTest scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_1_; net::URLRequest* url_request_1_; scoped_refptr<net::SSLCertRequestInfo> cert_request_info_1_; - scoped_refptr<StrictMock<SSLClientAuthHandlerMock> > auth_handler_1_; + scoped_refptr<StrictMock<SSLClientAuthRequestorMock> > auth_requestor_1_; SSLClientCertificateSelector* selector_1_; }; IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, SelectNone) { - EXPECT_CALL(*auth_handler_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL)); // Let the mock get checked on destruction. } IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, Escape) { - EXPECT_CALL(*auth_handler_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL)); EXPECT_TRUE(ui_test_utils::SendKeyPressSync( browser(), ui::VKEY_ESCAPE, false, false, false, false)); - Mock::VerifyAndClear(auth_handler_); + Mock::VerifyAndClear(auth_requestor_.get()); } IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorTest, SelectDefault) { - EXPECT_CALL(*auth_handler_, - CertificateSelectedNoNotify(mit_davidben_cert_.get())); + EXPECT_CALL(*auth_requestor_, CertificateSelected(mit_davidben_cert_.get())); EXPECT_TRUE(ui_test_utils::SendKeyPressSync( browser(), ui::VKEY_RETURN, false, false, false, false)); - Mock::VerifyAndClear(auth_handler_); + Mock::VerifyAndClear(auth_requestor_.get()); } IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiTabTest, Escape) { - // auth_handler_1_ should get selected automatically by the + // auth_requestor_1_ should get selected automatically by the // SSLClientAuthObserver when selector_2_ is accepted, since both 1 & 2 have // the same host:port. - EXPECT_CALL(*auth_handler_1_, CertificateSelectedNoNotify(NULL)); - EXPECT_CALL(*auth_handler_2_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_1_, CertificateSelected(NULL)); + EXPECT_CALL(*auth_requestor_2_, CertificateSelected(NULL)); EXPECT_TRUE(ui_test_utils::SendKeyPressSync( browser(), ui::VKEY_ESCAPE, false, false, false, false)); - Mock::VerifyAndClear(auth_handler_); - Mock::VerifyAndClear(auth_handler_1_); - Mock::VerifyAndClear(auth_handler_2_); + Mock::VerifyAndClear(auth_requestor_.get()); + Mock::VerifyAndClear(auth_requestor_1_.get()); + Mock::VerifyAndClear(auth_requestor_2_.get()); - // Now let the default selection for auth_handler_ mock get checked on + // Now let the default selection for auth_requestor_ mock get checked on // destruction. - EXPECT_CALL(*auth_handler_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL)); } IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiTabTest, SelectSecond) { - // auth_handler_1_ should get selected automatically by the + // auth_requestor_1_ should get selected automatically by the // SSLClientAuthObserver when selector_2_ is accepted, since both 1 & 2 have // the same host:port. - EXPECT_CALL(*auth_handler_1_, - CertificateSelectedNoNotify(foaf_me_chromium_test_cert_.get())); - EXPECT_CALL(*auth_handler_2_, - CertificateSelectedNoNotify(foaf_me_chromium_test_cert_.get())); + EXPECT_CALL(*auth_requestor_1_, + CertificateSelected(foaf_me_chromium_test_cert_.get())); + EXPECT_CALL(*auth_requestor_2_, + CertificateSelected(foaf_me_chromium_test_cert_.get())); EXPECT_TRUE(ui_test_utils::SendKeyPressSync( browser(), ui::VKEY_DOWN, false, false, false, false)); @@ -321,44 +329,44 @@ IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiTabTest, SelectSecond) { EXPECT_TRUE(ui_test_utils::SendKeyPressSync( browser(), ui::VKEY_RETURN, false, false, false, false)); - Mock::VerifyAndClear(auth_handler_); - Mock::VerifyAndClear(auth_handler_1_); - Mock::VerifyAndClear(auth_handler_2_); + Mock::VerifyAndClear(auth_requestor_.get()); + Mock::VerifyAndClear(auth_requestor_1_.get()); + Mock::VerifyAndClear(auth_requestor_2_.get()); - // Now let the default selection for auth_handler_ mock get checked on + // Now let the default selection for auth_requestor_ mock get checked on // destruction. - EXPECT_CALL(*auth_handler_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL)); } // http://crbug.com/103529 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiProfileTest, FLAKY_Escape) { - EXPECT_CALL(*auth_handler_1_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_1_, CertificateSelected(NULL)); EXPECT_TRUE(ui_test_utils::SendKeyPressSync( browser_1_, ui::VKEY_ESCAPE, false, false, false, false)); - Mock::VerifyAndClear(auth_handler_); - Mock::VerifyAndClear(auth_handler_1_); + Mock::VerifyAndClear(auth_requestor_.get()); + Mock::VerifyAndClear(auth_requestor_1_.get()); - // Now let the default selection for auth_handler_ mock get checked on + // Now let the default selection for auth_requestor_ mock get checked on // destruction. - EXPECT_CALL(*auth_handler_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL)); } // http://crbug.com/103534 IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMultiProfileTest, FLAKY_SelectDefault) { - EXPECT_CALL(*auth_handler_1_, - CertificateSelectedNoNotify(mit_davidben_cert_.get())); + EXPECT_CALL(*auth_requestor_1_, + CertificateSelected(mit_davidben_cert_.get())); EXPECT_TRUE(ui_test_utils::SendKeyPressSync( browser_1_, ui::VKEY_RETURN, false, false, false, false)); - Mock::VerifyAndClear(auth_handler_); - Mock::VerifyAndClear(auth_handler_1_); + Mock::VerifyAndClear(auth_requestor_.get()); + Mock::VerifyAndClear(auth_requestor_1_.get()); - // Now let the default selection for auth_handler_ mock get checked on + // Now let the default selection for auth_requestor_ mock get checked on // destruction. - EXPECT_CALL(*auth_handler_, CertificateSelectedNoNotify(NULL)); + EXPECT_CALL(*auth_requestor_, CertificateSelected(NULL)); } diff --git a/chrome/browser/ui/views/stubs_aura.cc b/chrome/browser/ui/views/stubs_aura.cc index 9f2c1ed..bcdb09e 100644 --- a/chrome/browser/ui/views/stubs_aura.cc +++ b/chrome/browser/ui/views/stubs_aura.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/callback.h" #include "base/logging.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" @@ -25,6 +26,7 @@ class TabContents; class TabContentsWrapper; namespace net { +class HttpNetworkSession; class SSLCertRequestInfo; class X509Certificate; } @@ -37,8 +39,9 @@ namespace browser { #if defined(OS_WIN) void ShowSSLClientCertificateSelector( TabContentsWrapper* parent, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { + const base::Callback<void(net::X509Certificate*)>& callback) { // TODO(beng): NOTIMPLEMENTED(); } diff --git a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.cc b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.cc index 1940a0c..2c5d86c 100644 --- a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.cc +++ b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.cc @@ -115,23 +115,25 @@ std::string FormatComboBoxText( void SSLClientCertificateSelectorWebUI::ShowDialog( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { + const base::Callback<void(net::X509Certificate*)>& callback) { SSLClientCertificateSelectorWebUI* ui = new SSLClientCertificateSelectorWebUI(wrapper, + network_session, cert_request_info, - delegate); + callback); Profile* profile = wrapper->profile(); ConstrainedHtmlUI::CreateConstrainedHtmlDialog(profile, ui, NULL, wrapper); } SSLClientCertificateSelectorWebUI::SSLClientCertificateSelectorWebUI( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) - : wrapper_(wrapper), - cert_request_info_(cert_request_info), - delegate_(delegate) { + const base::Callback<void(net::X509Certificate*)>& callback) + : SSLClientAuthObserver(network_session, cert_request_info, callback), + wrapper_(wrapper) { ChromeWebUIDataSource* source = new ChromeWebUIDataSource( chrome::kChromeUISSLClientCertificateSelectorHost); @@ -164,6 +166,10 @@ SSLClientCertificateSelectorWebUI::SSLClientCertificateSelectorWebUI( SSLClientCertificateSelectorWebUI::~SSLClientCertificateSelectorWebUI() { } +void SSLClientCertificateSelectorWebUI::OnCertSelectedByNotification() { + NOTIMPLEMENTED(); +} + // HtmlDialogUIDelegate methods ui::ModalType SSLClientCertificateSelectorWebUI::GetDialogModalType() const { return ui::MODAL_TYPE_WINDOW; @@ -199,29 +205,21 @@ void SSLClientCertificateSelectorWebUI::OnDialogClosed( list->GetDouble(0, &value)) { // User selected a certificate. size_t index = (size_t) value; - if (index < cert_request_info_->client_certs.size()) { + if (index < cert_request_info()->client_certs.size()) { scoped_refptr<net::X509Certificate> selected_cert( - cert_request_info_->client_certs[index]); + cert_request_info()->client_certs[index]); browser::UnlockCertSlotIfNecessary( selected_cert, browser::kCryptoModulePasswordClientAuth, - cert_request_info_->host_and_port, - base::Bind(&SSLClientCertificateSelectorWebUI::Unlocked, - delegate_, - selected_cert)); + cert_request_info()->host_and_port, + base::Bind(&SSLClientCertificateSelectorWebUI::CertificateSelected, + base::Unretained(this), selected_cert)); return; } } // Anything else constitutes a cancel. - delegate_->CertificateSelected(NULL); - delegate_ = NULL; -} - -// static -void SSLClientCertificateSelectorWebUI::Unlocked(SSLClientAuthHandler* delegate, - net::X509Certificate* selected_cert) { - delegate->CertificateSelected(selected_cert); + CertificateSelected(NULL); } @@ -249,20 +247,20 @@ void SSLClientCertificateSelectorWebUI::RequestDetails( const base::ListValue* args) { std::vector<std::string> nicknames; x509_certificate_model::GetNicknameStringsFromCertList( - cert_request_info_->client_certs, + cert_request_info()->client_certs, l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_EXPIRED), l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_NOT_YET_VALID), &nicknames); - DCHECK_EQ(nicknames.size(), cert_request_info_->client_certs.size()); + DCHECK_EQ(nicknames.size(), cert_request_info()->client_certs.size()); DictionaryValue dict; - dict.SetString("site", cert_request_info_->host_and_port.c_str()); + dict.SetString("site", cert_request_info()->host_and_port.c_str()); ListValue* certificates = new ListValue(); ListValue* details = new ListValue(); - for (size_t i = 0; i < cert_request_info_->client_certs.size(); ++i) { + for (size_t i = 0; i < cert_request_info()->client_certs.size(); ++i) { net::X509Certificate::OSCertHandle cert = - cert_request_info_->client_certs[i]->os_cert_handle(); + cert_request_info()->client_certs[i]->os_cert_handle(); certificates->Append(new StringValue( FormatComboBoxText(cert, nicknames[i]))); @@ -282,8 +280,8 @@ void SSLClientCertificateSelectorWebUI::ViewCertificate( double value = 0; if (args && args->GetDouble(0, &value)) { size_t index = (size_t) value; - if (index < cert_request_info_->client_certs.size()) - ShowCertificateViewer(NULL, cert_request_info_->client_certs[index]); + if (index < cert_request_info()->client_certs.size()) + ShowCertificateViewer(NULL, cert_request_info()->client_certs[index]); } } @@ -294,29 +292,27 @@ namespace browser { void ShowSSLClientCertificateSelector( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { + const base::Callback<void(net::X509Certificate*)>& callback) { // TODO(jhawkins): move this into a non-webui location. #if defined(USE_AURA) - ShowNativeSSLClientCertificateSelector(wrapper, - cert_request_info, - delegate); + ShowNativeSSLClientCertificateSelector( + wrapper, network_session, cert_request_info, callback); #elif defined(OS_CHROMEOS) - SSLClientCertificateSelectorWebUI::ShowDialog(wrapper, - cert_request_info, - delegate); + SSLClientCertificateSelectorWebUI::ShowDialog( + wrapper, network_session, cert_request_info, callback); #else // TODO(rbyers): Remove the IsMoreWebUI check and (ideally) all #ifdefs onnce // we can select exactly one version of this dialog to use for each platform // at build time. http://crbug.com/102775 - if (chrome_web_ui::IsMoreWebUI()) - SSLClientCertificateSelectorWebUI::ShowDialog(wrapper, - cert_request_info, - delegate); - else - ShowNativeSSLClientCertificateSelector(wrapper, - cert_request_info, - delegate); + if (chrome_web_ui::IsMoreWebUI()) { + SSLClientCertificateSelectorWebUI::ShowDialog( + wrapper, network_session, cert_request_info, callback); + } else { + ShowNativeSSLClientCertificateSelector( + wrapper, network_session, cert_request_info, callback); + } #endif } diff --git a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.h b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.h index c647a85..9170213 100644 --- a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.h +++ b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui.h @@ -10,29 +10,33 @@ #include <string> #include "chrome/browser/ui/webui/html_dialog_ui.h" -#include "net/base/ssl_cert_request_info.h" -#include "content/browser/ssl/ssl_client_auth_handler.h" +#include "chrome/browser/ssl/ssl_client_auth_observer.h" #include "content/public/browser/web_ui_message_handler.h" +#include "net/base/ssl_cert_request_info.h" class TabContentsWrapper; -class SSLClientCertificateSelectorWebUI : public HtmlDialogUIDelegate, +class SSLClientCertificateSelectorWebUI : public SSLClientAuthObserver, + public HtmlDialogUIDelegate, content::WebUIMessageHandler { public: // Static factory method. static void ShowDialog( TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate); + const base::Callback<void(net::X509Certificate*)>& callback); private: - SSLClientCertificateSelectorWebUI(TabContentsWrapper* wrapper, - net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate); + SSLClientCertificateSelectorWebUI( + TabContentsWrapper* wrapper, + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback); virtual ~SSLClientCertificateSelectorWebUI(); - // Shows the dialog - void ShowDialog(); + // SSLClientAuthObserver methods + virtual void OnCertSelectedByNotification() OVERRIDE; // HtmlDialogUIDelegate methods virtual ui::ModalType GetDialogModalType() const OVERRIDE; @@ -59,13 +63,7 @@ class SSLClientCertificateSelectorWebUI : public HtmlDialogUIDelegate, // Called by JavaScript to show a certificate. void ViewCertificate(const base::ListValue* args); - // Callback for unlocking of the certificate when processing OK button. - static void Unlocked(SSLClientAuthHandler* delegate, - net::X509Certificate* selected_cert); - TabContentsWrapper* wrapper_; - scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; - scoped_refptr<SSLClientAuthHandler> delegate_; DISALLOW_COPY_AND_ASSIGN(SSLClientCertificateSelectorWebUI); }; diff --git a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.cc b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.cc index e4ed9fc..26fb9b6 100644 --- a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.cc +++ b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.cc @@ -4,12 +4,13 @@ #include "chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.h" +#include "base/bind.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ssl/ssl_client_auth_requestor_mock.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/webui/chrome_web_ui.h" #include "chrome/browser/ui/webui/ssl_client_certificate_selector_webui.h" #include "chrome/test/base/test_html_dialog_observer.h" -#include "content/browser/ssl/ssl_client_auth_handler_mock.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" @@ -36,12 +37,13 @@ void SSLClientCertificateSelectorUITest::ShowSSLClientCertificateSelector() { // Show the SSL client certificate selector. SSLClientCertificateSelectorWebUI::ShowDialog( - browser()->GetSelectedTabContentsWrapper(), - cert_request_info_, - auth_handler_ - ); + browser()->GetSelectedTabContentsWrapper(), + auth_requestor_->http_network_session_, + auth_requestor_->cert_request_info_, + base::Bind(&SSLClientAuthRequestorMock::CertificateSelected, + auth_requestor_)); - EXPECT_CALL(*auth_handler_, CertificateSelectedNoNotify(::testing::_)); + EXPECT_CALL(*auth_requestor_, CertificateSelected(::testing::_)); // Tell the test which WebUI instance we are dealing with and complete // initialization of this test. @@ -55,7 +57,7 @@ void SSLClientCertificateSelectorUITest::CleanUpOnMainThread() { base::Bind(&SSLClientCertificateSelectorUITest::CleanUpOnIOThread, this)); io_loop_finished_event_.Wait(); - auth_handler_ = NULL; + auth_requestor_ = NULL; WebUIBrowserTest::CleanUpOnMainThread(); } @@ -63,7 +65,7 @@ void SSLClientCertificateSelectorUITest::SetUpOnIOThread() { url_request_ = new net::URLRequest(GURL("https://example"), NULL); url_request_->set_context(url_request_context_getter_-> GetURLRequestContext()); - auth_handler_ = new testing::StrictMock<SSLClientAuthHandlerMock>( + auth_requestor_ = new testing::StrictMock<SSLClientAuthRequestorMock>( url_request_, cert_request_info_); io_loop_finished_event_.Signal(); diff --git a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.h b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.h index 230ff16..99b9e65 100644 --- a/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.h +++ b/chrome/browser/ui/webui/ssl_client_certificate_selector_webui_browsertest.h @@ -16,7 +16,7 @@ class URLRequestContextGetter; class SSLCertRequestInfo; } -class SSLClientAuthHandlerMock; +class SSLClientAuthRequestorMock; namespace testing { template<class T> class StrictMock; @@ -46,8 +46,8 @@ class SSLClientCertificateSelectorUITest : public WebUIBrowserTest { scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; net::URLRequest* url_request_; scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; - scoped_refptr<testing::StrictMock<SSLClientAuthHandlerMock> > - auth_handler_; + scoped_refptr<testing::StrictMock<SSLClientAuthRequestorMock> > + auth_requestor_; DISALLOW_COPY_AND_ASSIGN(SSLClientCertificateSelectorUITest); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 4c82a96..4d51814 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2277,6 +2277,8 @@ 'browser/ssl/ssl_add_cert_handler_mac.mm', 'browser/ssl/ssl_blocking_page.cc', 'browser/ssl/ssl_blocking_page.h', + 'browser/ssl/ssl_client_auth_observer.cc', + 'browser/ssl/ssl_client_auth_observer.h', 'browser/ssl/ssl_error_info.cc', 'browser/ssl/ssl_error_info.h', 'browser/ssl_client_certificate_selector.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3de725c..8298061 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -158,6 +158,7 @@ 'browser/search_engines/template_url_service_test_util.h', 'browser/sessions/session_service_test_helper.cc', 'browser/sessions/session_service_test_helper.h', + 'browser/ssl/ssl_client_auth_requestor_mock.h', 'browser/sync/profile_sync_service_mock.cc', 'browser/sync/profile_sync_service_mock.h', 'browser/sync/syncable/syncable_mock.cc', @@ -253,8 +254,6 @@ # production code code in libbrowser (in chrome.gyp). #'../content/browser/net/url_request_mock_http_job.cc', #'../content/browser/net/url_request_mock_http_job.h', - '../content/browser/ssl/ssl_client_auth_handler_mock.cc', - '../content/browser/ssl/ssl_client_auth_handler_mock.h', '../content/test/notification_observer_mock.cc', '../content/test/notification_observer_mock.h', '../ui/gfx/image/image_unittest_util.h', diff --git a/chrome/common/chrome_notification_types.h b/chrome/common/chrome_notification_types.h index b1bed0d..1109cc0 100644 --- a/chrome/common/chrome_notification_types.h +++ b/chrome/common/chrome_notification_types.h @@ -1012,6 +1012,11 @@ enum NotificationType { // BrowsingDataRemove::Remove was called. NOTIFICATION_BROWSING_DATA_REMOVED, + // The user accepted or dismissed a SSL client authentication request. + // The source is a Source<net::HttpNetworkSession>. Details is a + // (std::pair<net::SSLCertRequestInfo*, net::X509Certificate*>). + NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, + // Note:- // Currently only Content and Chrome define and use notifications. // Custom notifications not belonging to Content and Chrome should start diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc index 3d96df6f..f5c2065 100644 --- a/content/browser/mock_content_browser_client.cc +++ b/content/browser/mock_content_browser_client.cc @@ -179,7 +179,9 @@ void MockContentBrowserClient::AllowCertificateError( void MockContentBrowserClient::SelectClientCertificate( int render_process_id, int render_view_id, - SSLClientAuthHandler* handler) { + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) { } void MockContentBrowserClient::AddNewCertificate( diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h index a049ec8..a2380f6 100644 --- a/content/browser/mock_content_browser_client.h +++ b/content/browser/mock_content_browser_client.h @@ -95,7 +95,9 @@ class MockContentBrowserClient : public ContentBrowserClient { virtual void SelectClientCertificate( int render_process_id, int render_view_id, - SSLClientAuthHandler* handler) OVERRIDE; + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE; virtual void AddNewCertificate( net::URLRequest* request, net::X509Certificate* cert, diff --git a/content/browser/ssl/ssl_client_auth_handler.cc b/content/browser/ssl/ssl_client_auth_handler.cc index 03db71a..09e07cb 100644 --- a/content/browser/ssl/ssl_client_auth_handler.cc +++ b/content/browser/ssl/ssl_client_auth_handler.cc @@ -7,10 +7,8 @@ #include "base/bind.h" #include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" -#include "content/browser/ssl/ssl_client_auth_notification_details.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" -#include "content/public/browser/notification_service.h" #include "net/base/x509_certificate.h" #include "net/http/http_transaction_factory.h" #include "net/url_request/url_request.h" @@ -58,27 +56,10 @@ void SSLClientAuthHandler::SelectCertificate() { render_process_host_id, render_view_host_id)); } -// Sends an SSL_CLIENT_AUTH_CERT_SELECTED notification and notifies the IO -// thread that we have selected a cert. void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) { - VLOG(1) << this << " CertificateSelected " << cert; DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - SSLClientAuthNotificationDetails details(cert_request_info_, this, cert); - content::NotificationService* service = - content::NotificationService::current(); - service->Notify(content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, - content::Source<net::HttpNetworkSession>( - http_network_session()), - content::Details<SSLClientAuthNotificationDetails>(&details)); - - CertificateSelectedNoNotify(cert); -} - -// Notifies the IO thread that we have selected a cert. -void SSLClientAuthHandler::CertificateSelectedNoNotify( - net::X509Certificate* cert) { - VLOG(1) << this << " CertificateSelectedNoNotify " << cert; + VLOG(1) << this << " CertificateSelected " << cert; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind( @@ -107,55 +88,7 @@ void SSLClientAuthHandler::DoCertificateSelected(net::X509Certificate* cert) { void SSLClientAuthHandler::DoSelectCertificate( int render_process_host_id, int render_view_host_id) { content::GetContentClient()->browser()->SelectClientCertificate( - render_process_host_id, render_view_host_id, this); -} - -SSLClientAuthObserver::SSLClientAuthObserver( - net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* handler) - : cert_request_info_(cert_request_info), handler_(handler) { -} - -SSLClientAuthObserver::~SSLClientAuthObserver() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); -} - -void SSLClientAuthObserver::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - VLOG(1) << "SSLClientAuthObserver::Observe " << this << " " << handler_.get(); - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(type == content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED); - - SSLClientAuthNotificationDetails* auth_details = - content::Details<SSLClientAuthNotificationDetails>(details).ptr(); - - if (auth_details->IsSameHandler(handler_.get())) { - VLOG(1) << "got notification from ourself " << handler_.get(); - return; - } - - if (!auth_details->IsSameHost(cert_request_info_)) - return; - - VLOG(1) << this << " got matching notification for " - << handler_.get() << ", selecting cert " - << auth_details->selected_cert(); - StopObserving(); - handler_->CertificateSelectedNoNotify(auth_details->selected_cert()); - OnCertSelectedByNotification(); -} - -void SSLClientAuthObserver::StartObserving() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - notification_registrar_.Add( - this, content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, - content::Source<net::HttpNetworkSession>( - handler_->http_network_session())); -} - -void SSLClientAuthObserver::StopObserving() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - notification_registrar_.RemoveAll(); + render_process_host_id, render_view_host_id, http_network_session_, + cert_request_info_, + base::Bind(&SSLClientAuthHandler::CertificateSelected, this)); } diff --git a/content/browser/ssl/ssl_client_auth_handler.h b/content/browser/ssl/ssl_client_auth_handler.h index a5893dc..0461d27 100644 --- a/content/browser/ssl/ssl_client_auth_handler.h +++ b/content/browser/ssl/ssl_client_auth_handler.h @@ -11,8 +11,6 @@ #include "base/message_loop_helpers.h" #include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "net/base/ssl_cert_request_info.h" namespace net { @@ -45,19 +43,6 @@ class CONTENT_EXPORT SSLClientAuthHandler // be long after DoSelectCertificate returns, if the UI is modeless/async.) void CertificateSelected(net::X509Certificate* cert); - // Like CertificateSelected, but does not send SSL_CLIENT_AUTH_CERT_SELECTED - // notification. Used to avoid notification re-spamming when other - // certificate selectors act on a notification matching the same host. - virtual void CertificateSelectedNoNotify(net::X509Certificate* cert); - - // Returns the SSLCertRequestInfo for this handler. - net::SSLCertRequestInfo* cert_request_info() { return cert_request_info_; } - - // Returns the session the URL request is associated with. - const net::HttpNetworkSession* http_network_session() const { - return http_network_session_; - } - protected: virtual ~SSLClientAuthHandler(); @@ -87,39 +72,4 @@ class CONTENT_EXPORT SSLClientAuthHandler DISALLOW_COPY_AND_ASSIGN(SSLClientAuthHandler); }; -class CONTENT_EXPORT SSLClientAuthObserver - : public content::NotificationObserver { - public: - SSLClientAuthObserver(net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* handler); - virtual ~SSLClientAuthObserver(); - - // UI should implement this to close the dialog. - virtual void OnCertSelectedByNotification() = 0; - - // content::NotificationObserver implementation: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE; - - // Begins observing notifications from other SSLClientAuthHandler instances. - // If another instance chooses a cert for a matching SSLCertRequestInfo, we - // will also use the same cert and OnCertSelectedByNotification will be called - // so that the cert selection UI can be closed. - void StartObserving(); - - // Stops observing notifications. We will no longer act on client auth - // notifications. - void StopObserving(); - - private: - scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; - - scoped_refptr<SSLClientAuthHandler> handler_; - - content::NotificationRegistrar notification_registrar_; - - DISALLOW_COPY_AND_ASSIGN(SSLClientAuthObserver); -}; - #endif // CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_H_ diff --git a/content/browser/ssl/ssl_client_auth_handler_mock.cc b/content/browser/ssl/ssl_client_auth_handler_mock.cc deleted file mode 100644 index 4bc41a7..0000000 --- a/content/browser/ssl/ssl_client_auth_handler_mock.cc +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2012 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 "content/browser/ssl/ssl_client_auth_handler_mock.h" - -SSLClientAuthHandlerMock::SSLClientAuthHandlerMock( - net::URLRequest* request, - net::SSLCertRequestInfo* cert_request_info) - : SSLClientAuthHandler(request, cert_request_info) { -} - -SSLClientAuthHandlerMock::~SSLClientAuthHandlerMock() { - // Hack to avoid destructor calling request_->ContinueWithCertificate. - OnRequestCancelled(); -} diff --git a/content/browser/ssl/ssl_client_auth_handler_mock.h b/content/browser/ssl/ssl_client_auth_handler_mock.h deleted file mode 100644 index 33e14ab..0000000 --- a/content/browser/ssl/ssl_client_auth_handler_mock.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_MOCK_H_ -#define CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_MOCK_H_ -#pragma once - -#include "content/browser/ssl/ssl_client_auth_handler.h" -#include "testing/gmock/include/gmock/gmock.h" - -class SSLClientAuthHandlerMock : public SSLClientAuthHandler { - public: - SSLClientAuthHandlerMock( - net::URLRequest* request, - net::SSLCertRequestInfo* cert_request_info); - ~SSLClientAuthHandlerMock(); - - MOCK_METHOD1(CertificateSelectedNoNotify, void(net::X509Certificate* cert)); - - private: - DISALLOW_COPY_AND_ASSIGN(SSLClientAuthHandlerMock); -}; - - -#endif // CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_MOCK_H_ diff --git a/content/browser/ssl/ssl_client_auth_notification_details.cc b/content/browser/ssl/ssl_client_auth_notification_details.cc deleted file mode 100644 index e5f4dc3..0000000 --- a/content/browser/ssl/ssl_client_auth_notification_details.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2011 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 "content/browser/ssl/ssl_client_auth_notification_details.h" - -#include "net/base/ssl_cert_request_info.h" - -SSLClientAuthNotificationDetails::SSLClientAuthNotificationDetails( - const net::SSLCertRequestInfo* cert_request_info, - const SSLClientAuthHandler* handler, - net::X509Certificate* selected_cert) - : cert_request_info_(cert_request_info), - handler_(handler), - selected_cert_(selected_cert) { -} - -bool SSLClientAuthNotificationDetails::IsSameHost( - const net::SSLCertRequestInfo* cert_request_info) const { - // TODO(mattm): should we also compare the DistinguishedNames, or is just - // matching host&port sufficient? - return cert_request_info_->host_and_port == cert_request_info->host_and_port; -} - -bool SSLClientAuthNotificationDetails::IsSameHandler( - const SSLClientAuthHandler* handler) const { - return handler_ == handler; -} diff --git a/content/browser/ssl/ssl_client_auth_notification_details.h b/content/browser/ssl/ssl_client_auth_notification_details.h deleted file mode 100644 index d33bbc0..0000000 --- a/content/browser/ssl/ssl_client_auth_notification_details.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2011 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. - -#ifndef CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_NOTIFICATION_DETAILS_H_ -#define CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_NOTIFICATION_DETAILS_H_ - -#include "base/basictypes.h" - -namespace net { -class X509Certificate; -class SSLCertRequestInfo; -} -class SSLClientAuthHandler; - -class SSLClientAuthNotificationDetails { - public: - SSLClientAuthNotificationDetails( - const net::SSLCertRequestInfo* cert_request_info, - const SSLClientAuthHandler* handler, - net::X509Certificate* selected_cert); - - bool IsSameHost(const net::SSLCertRequestInfo* cert_request_info) const; - bool IsSameHandler(const SSLClientAuthHandler* handler) const; - net::X509Certificate* selected_cert() const { return selected_cert_; } - - private: - // Notifications are synchronous, so we don't need to hold our own references. - const net::SSLCertRequestInfo* cert_request_info_; - const SSLClientAuthHandler* handler_; - net::X509Certificate* selected_cert_; - - DISALLOW_COPY_AND_ASSIGN(SSLClientAuthNotificationDetails); -}; - -#endif // CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_NOTIFICATION_DETAILS_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 418832d..694c666 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -606,8 +606,6 @@ 'browser/ssl/ssl_cert_error_handler.h', 'browser/ssl/ssl_client_auth_handler.cc', 'browser/ssl/ssl_client_auth_handler.h', - 'browser/ssl/ssl_client_auth_notification_details.cc', - 'browser/ssl/ssl_client_auth_notification_details.h', 'browser/ssl/ssl_error_handler.cc', 'browser/ssl/ssl_error_handler.h', 'browser/ssl/ssl_host_state.cc', diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 9be8e58..400599a 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -24,7 +24,6 @@ class PluginProcessHost; class QuotaPermissionContext; class RenderViewHost; class ResourceDispatcherHost; -class SSLClientAuthHandler; class SkBitmap; struct WebPreferences; @@ -46,7 +45,9 @@ class CryptoModuleBlockingPasswordDelegate; namespace net { class CookieList; class CookieOptions; +class HttpNetworkSession; class NetLog; +class SSLCertRequestInfo; class SSLInfo; class URLRequest; class URLRequestContext; @@ -232,12 +233,14 @@ class ContentBrowserClient { const base::Callback<void(bool)>& callback, bool* cancel_request) = 0; - // Selects a SSL client certificate and returns it to the |handler|. If no - // certificate was selected NULL is returned to the |handler|. + // Selects a SSL client certificate and returns it to the |callback|. If no + // certificate was selected NULL is returned to the |callback|. virtual void SelectClientCertificate( int render_process_id, int render_view_id, - SSLClientAuthHandler* handler) = 0; + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) = 0; // Adds a downloaded client cert. The embedder should ensure that there's // a private key for the cert, displays the cert to the user, and adds it upon diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h index f51a926..b7b45ce 100644 --- a/content/public/browser/notification_types.h +++ b/content/public/browser/notification_types.h @@ -153,13 +153,6 @@ enum NotificationType { // controller associated with the state change. NOTIFICATION_SSL_INTERNAL_STATE_CHANGED, - // The user accepted or dismissed a SSL client authentication request. - // The source is a Source<SSLClientAuthHandler>. Details is a - // SSLClientAuthNotificationDetails which records specifies which - // SSLCertRequestInfo the request was for and which X509Certificate was - // selected (if any). - NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, - #if defined(OS_MACOSX) // This message is sent when the application is made active (Mac OS X only // at present). No source or details are passed. diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc index 154fd73..b4c9e43 100644 --- a/content/shell/shell_content_browser_client.cc +++ b/content/shell/shell_content_browser_client.cc @@ -204,7 +204,9 @@ void ShellContentBrowserClient::AllowCertificateError( void ShellContentBrowserClient::SelectClientCertificate( int render_process_id, int render_view_id, - SSLClientAuthHandler* handler) { + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) { } void ShellContentBrowserClient::AddNewCertificate( diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h index defb5f5..158aefb 100644 --- a/content/shell/shell_content_browser_client.h +++ b/content/shell/shell_content_browser_client.h @@ -100,7 +100,9 @@ class ShellContentBrowserClient : public ContentBrowserClient { virtual void SelectClientCertificate( int render_process_id, int render_view_id, - SSLClientAuthHandler* handler) OVERRIDE; + const net::HttpNetworkSession* network_session, + net::SSLCertRequestInfo* cert_request_info, + const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE; virtual void AddNewCertificate( net::URLRequest* request, net::X509Certificate* cert, |