Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: chrome/browser/ssl/ssl_client_auth_observer.cc

Issue 9384014: Remove knowledge about SSLClientAuthHandler from chrome. Instead a callback is given to the embed... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: review comments+sync Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/ssl/ssl_client_auth_handler.h" 5 #include "chrome/browser/ssl/ssl_client_auth_observer.h"
6
7 #include <utility>
6 8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "content/browser/renderer_host/resource_dispatcher_host.h" 10 #include "base/logging.h"
9 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" 11 #include "chrome/common/chrome_notification_types.h"
10 #include "content/browser/ssl/ssl_client_auth_notification_details.h"
11 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/content_browser_client.h"
13 #include "content/public/browser/notification_service.h" 13 #include "content/public/browser/notification_service.h"
14 #include "net/base/ssl_cert_request_info.h"
14 #include "net/base/x509_certificate.h" 15 #include "net/base/x509_certificate.h"
15 #include "net/http/http_transaction_factory.h"
16 #include "net/url_request/url_request.h"
17 #include "net/url_request/url_request_context.h"
18 16
19 using content::BrowserThread; 17 using content::BrowserThread;
20 18
21 SSLClientAuthHandler::SSLClientAuthHandler( 19 typedef std::pair<net::SSLCertRequestInfo*, net::X509Certificate*> CertDetails;
22 net::URLRequest* request,
23 net::SSLCertRequestInfo* cert_request_info)
24 : request_(request),
25 http_network_session_(
26 request_->context()->http_transaction_factory()->GetSession()),
27 cert_request_info_(cert_request_info) {
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
29 }
30
31 SSLClientAuthHandler::~SSLClientAuthHandler() {
32 // If we were simply dropped, then act as if we selected no certificate.
33 DoCertificateSelected(NULL);
34 }
35
36 void SSLClientAuthHandler::OnRequestCancelled() {
37 request_ = NULL;
38 }
39
40 void SSLClientAuthHandler::SelectCertificate() {
41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
42
43 int render_process_host_id;
44 int render_view_host_id;
45 if (!ResourceDispatcherHost::RenderViewForRequest(request_,
46 &render_process_host_id,
47 &render_view_host_id))
48 NOTREACHED();
49
50 // If the RVH does not exist by the time this task gets run, then the task
51 // will be dropped and the scoped_refptr to SSLClientAuthHandler will go
52 // away, so we do not leak anything. The destructor takes care of ensuring
53 // the net::URLRequest always gets a response.
54 BrowserThread::PostTask(
55 BrowserThread::UI, FROM_HERE,
56 base::Bind(
57 &SSLClientAuthHandler::DoSelectCertificate, this,
58 render_process_host_id, render_view_host_id));
59 }
60
61 // Sends an SSL_CLIENT_AUTH_CERT_SELECTED notification and notifies the IO
62 // thread that we have selected a cert.
63 void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) {
64 VLOG(1) << this << " CertificateSelected " << cert;
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
66
67 SSLClientAuthNotificationDetails details(cert_request_info_, this, cert);
68 content::NotificationService* service =
69 content::NotificationService::current();
70 service->Notify(content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED,
71 content::Source<net::HttpNetworkSession>(
72 http_network_session()),
73 content::Details<SSLClientAuthNotificationDetails>(&details));
74
75 CertificateSelectedNoNotify(cert);
76 }
77
78 // Notifies the IO thread that we have selected a cert.
79 void SSLClientAuthHandler::CertificateSelectedNoNotify(
80 net::X509Certificate* cert) {
81 VLOG(1) << this << " CertificateSelectedNoNotify " << cert;
82 BrowserThread::PostTask(
83 BrowserThread::IO, FROM_HERE,
84 base::Bind(
85 &SSLClientAuthHandler::DoCertificateSelected, this,
86 make_scoped_refptr(cert)));
87 }
88
89 void SSLClientAuthHandler::DoCertificateSelected(net::X509Certificate* cert) {
90 VLOG(1) << this << " DoCertificateSelected " << cert;
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
92 // request_ could have been NULLed if the request was cancelled while the
93 // user was choosing a cert, or because we have already responded to the
94 // certificate.
95 if (request_) {
96 request_->ContinueWithCertificate(cert);
97
98 ResourceDispatcherHostRequestInfo* info =
99 ResourceDispatcherHost::InfoForRequest(request_);
100 if (info)
101 info->set_ssl_client_auth_handler(NULL);
102
103 request_ = NULL;
104 }
105 }
106
107 void SSLClientAuthHandler::DoSelectCertificate(
108 int render_process_host_id, int render_view_host_id) {
109 content::GetContentClient()->browser()->SelectClientCertificate(
110 render_process_host_id, render_view_host_id, this);
111 }
112 20
113 SSLClientAuthObserver::SSLClientAuthObserver( 21 SSLClientAuthObserver::SSLClientAuthObserver(
22 const net::HttpNetworkSession* network_session,
114 net::SSLCertRequestInfo* cert_request_info, 23 net::SSLCertRequestInfo* cert_request_info,
115 SSLClientAuthHandler* handler) 24 const base::Callback<void(net::X509Certificate*)>& callback)
116 : cert_request_info_(cert_request_info), handler_(handler) { 25 : network_session_(network_session),
26 cert_request_info_(cert_request_info),
27 callback_(callback) {
117 } 28 }
118 29
119 SSLClientAuthObserver::~SSLClientAuthObserver() { 30 SSLClientAuthObserver::~SSLClientAuthObserver() {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 31 }
32
33 void SSLClientAuthObserver::CertificateSelected(
34 net::X509Certificate* certificate) {
35 if (callback_.is_null())
36 return;
37
38 // Stop listening right away so we don't get our own notification.
39 StopObserving();
40
41 CertDetails details;
42 details.first = cert_request_info_;
43 details.second = certificate;
44 content::NotificationService* service =
45 content::NotificationService::current();
46 service->Notify(chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED,
47 content::Source<net::HttpNetworkSession>(network_session_),
48 content::Details<CertDetails>(&details));
49
50 callback_.Run(certificate);
51 callback_.Reset();
121 } 52 }
122 53
123 void SSLClientAuthObserver::Observe( 54 void SSLClientAuthObserver::Observe(
124 int type, 55 int type,
125 const content::NotificationSource& source, 56 const content::NotificationSource& source,
126 const content::NotificationDetails& details) { 57 const content::NotificationDetails& details) {
127 VLOG(1) << "SSLClientAuthObserver::Observe " << this << " " << handler_.get(); 58 VLOG(1) << "SSLClientAuthObserver::Observe " << this;
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
129 DCHECK(type == content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED); 60 DCHECK(type == chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED);
130 61
131 SSLClientAuthNotificationDetails* auth_details = 62 CertDetails* cert_details = content::Details<CertDetails>(details).ptr();
132 content::Details<SSLClientAuthNotificationDetails>(details).ptr(); 63 if (cert_details->first->host_and_port != cert_request_info_->host_and_port)
133
134 if (auth_details->IsSameHandler(handler_.get())) {
135 VLOG(1) << "got notification from ourself " << handler_.get();
136 return;
137 }
138
139 if (!auth_details->IsSameHost(cert_request_info_))
140 return; 64 return;
141 65
142 VLOG(1) << this << " got matching notification for " 66 VLOG(1) << this << " got matching notification and selecting cert "
143 << handler_.get() << ", selecting cert " 67 << cert_details->second;
144 << auth_details->selected_cert();
145 StopObserving(); 68 StopObserving();
146 handler_->CertificateSelectedNoNotify(auth_details->selected_cert()); 69 callback_.Run(cert_details->second);
70 callback_.Reset();
147 OnCertSelectedByNotification(); 71 OnCertSelectedByNotification();
148 } 72 }
149 73
150 void SSLClientAuthObserver::StartObserving() { 74 void SSLClientAuthObserver::StartObserving() {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152 notification_registrar_.Add( 76 notification_registrar_.Add(
153 this, content::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, 77 this, chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED,
154 content::Source<net::HttpNetworkSession>( 78 content::Source<net::HttpNetworkSession>(network_session_));
155 handler_->http_network_session()));
156 } 79 }
157 80
158 void SSLClientAuthObserver::StopObserving() { 81 void SSLClientAuthObserver::StopObserving() {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
160 notification_registrar_.RemoveAll(); 83 notification_registrar_.RemoveAll();
161 } 84 }
OLDNEW
« no previous file with comments | « chrome/browser/ssl/ssl_client_auth_observer.h ('k') | chrome/browser/ssl/ssl_client_auth_requestor_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698