summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-20 22:43:42 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-20 22:43:42 +0000
commitfe4fb439589bd710ee5f393a29cf621773fe8d97 (patch)
treede1272293ace7daa8aded076230f42980e20dc3a /content
parent5f75aa7c254ad099e6fab6d31ef0e10989359ea4 (diff)
downloadchromium_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')
-rw-r--r--content/browser/ssl/ssl_client_auth_handler.cc20
-rw-r--r--content/browser/ssl/ssl_client_auth_handler.h9
-rw-r--r--content/browser/ssl/ssl_client_auth_handler_mock.h4
-rw-r--r--content/browser/ssl/ssl_client_auth_notification_details.cc7
-rw-r--r--content/browser/ssl/ssl_client_auth_notification_details.h4
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);