diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-20 22:43:42 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-20 22:43:42 +0000 |
commit | fe4fb439589bd710ee5f393a29cf621773fe8d97 (patch) | |
tree | de1272293ace7daa8aded076230f42980e20dc3a /content | |
parent | 5f75aa7c254ad099e6fab6d31ef0e10989359ea4 (diff) | |
download | chromium_src-fe4fb439589bd710ee5f393a29cf621773fe8d97.zip chromium_src-fe4fb439589bd710ee5f393a29cf621773fe8d97.tar.gz chromium_src-fe4fb439589bd710ee5f393a29cf621773fe8d97.tar.bz2 |
Fix SSL client auth selector multi-profile handling.
The NotificationSource is changed to be the HttpNetworkSession the request is associated with, so that the observer can watch only NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED notifications from the same session.
BUG=99385
TEST=Open same site in two profiles (or normal and incognito window) and try authenticating. The window(s) for the other profile should be unaffected.
Review URL: http://codereview.chromium.org/8227035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106609 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
5 files changed, 38 insertions, 6 deletions
diff --git a/content/browser/ssl/ssl_client_auth_handler.cc b/content/browser/ssl/ssl_client_auth_handler.cc index f4bfe3d..74e52c5 100644 --- a/content/browser/ssl/ssl_client_auth_handler.cc +++ b/content/browser/ssl/ssl_client_auth_handler.cc @@ -12,13 +12,18 @@ #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" +#include "net/url_request/url_request_context.h" SSLClientAuthHandler::SSLClientAuthHandler( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) : request_(request), + http_network_session_( + request_->context()->http_transaction_factory()->GetSession()), cert_request_info_(cert_request_info) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); } SSLClientAuthHandler::~SSLClientAuthHandler() { @@ -57,11 +62,12 @@ void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) { VLOG(1) << this << " CertificateSelected " << cert; DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - SSLClientAuthNotificationDetails details(cert_request_info_, cert); + SSLClientAuthNotificationDetails details(cert_request_info_, this, cert); content::NotificationService* service = content::NotificationService::current(); service->Notify(content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, - content::Source<SSLClientAuthHandler>(this), + content::Source<net::HttpNetworkSession>( + http_network_session()), content::Details<SSLClientAuthNotificationDetails>(&details)); CertificateSelectedNoNotify(cert); @@ -120,13 +126,14 @@ void SSLClientAuthObserver::Observe( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(type == content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED); - if (content::Source<SSLClientAuthHandler>(source).ptr() == handler_.get()) { + SSLClientAuthNotificationDetails* auth_details = + content::Details<SSLClientAuthNotificationDetails>(details).ptr(); + + if (auth_details->IsSameHandler(handler_.get())) { VLOG(1) << "got notification from ourself " << handler_.get(); return; } - SSLClientAuthNotificationDetails* auth_details = - content::Details<SSLClientAuthNotificationDetails>(details).ptr(); if (!auth_details->IsSameHost(cert_request_info_)) return; @@ -142,7 +149,8 @@ void SSLClientAuthObserver::StartObserving() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); notification_registrar_.Add( this, content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, - content::NotificationService::AllSources()); + content::Source<net::HttpNetworkSession>( + handler_->http_network_session())); } void SSLClientAuthObserver::StopObserving() { diff --git a/content/browser/ssl/ssl_client_auth_handler.h b/content/browser/ssl/ssl_client_auth_handler.h index 3a6468a..f5a0997 100644 --- a/content/browser/ssl/ssl_client_auth_handler.h +++ b/content/browser/ssl/ssl_client_auth_handler.h @@ -15,6 +15,7 @@ #include "net/base/ssl_cert_request_info.h" namespace net { +class HttpNetworkSession; class URLRequest; class X509Certificate; } // namespace net @@ -51,6 +52,11 @@ class CONTENT_EXPORT SSLClientAuthHandler // 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(); @@ -71,6 +77,9 @@ class CONTENT_EXPORT SSLClientAuthHandler // The net::URLRequest that triggered this client auth. net::URLRequest* request_; + // The HttpNetworkSession |request_| is associated with. + const net::HttpNetworkSession* http_network_session_; + // The certs to choose from. scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; diff --git a/content/browser/ssl/ssl_client_auth_handler_mock.h b/content/browser/ssl/ssl_client_auth_handler_mock.h index 4ebb6f0..26b6387 100644 --- a/content/browser/ssl/ssl_client_auth_handler_mock.h +++ b/content/browser/ssl/ssl_client_auth_handler_mock.h @@ -16,6 +16,10 @@ class SSLClientAuthHandlerMock : public SSLClientAuthHandler { net::SSLCertRequestInfo* cert_request_info) : SSLClientAuthHandler(request, cert_request_info) { } + ~SSLClientAuthHandlerMock() { + // Hack to avoid destructor calling request_->ContinueWithCertificate. + OnRequestCancelled(); + } MOCK_METHOD1(CertificateSelectedNoNotify, void(net::X509Certificate* cert)); }; diff --git a/content/browser/ssl/ssl_client_auth_notification_details.cc b/content/browser/ssl/ssl_client_auth_notification_details.cc index 237c909..e5f4dc3 100644 --- a/content/browser/ssl/ssl_client_auth_notification_details.cc +++ b/content/browser/ssl/ssl_client_auth_notification_details.cc @@ -8,8 +8,10 @@ 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) { } @@ -19,3 +21,8 @@ bool SSLClientAuthNotificationDetails::IsSameHost( // 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 index eea3d25..d33bbc0 100644 --- a/content/browser/ssl/ssl_client_auth_notification_details.h +++ b/content/browser/ssl/ssl_client_auth_notification_details.h @@ -11,19 +11,23 @@ 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); |