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

Side by Side Diff: content/browser/ssl/ssl_client_auth_handler.cc

Issue 795773002: Un-refcount SSLClientAuthHandler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mmenke comments Created 6 years 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
OLDNEW
1 // Copyright (c) 2012 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 "content/browser/ssl/ssl_client_auth_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/logging.h"
9 #include "content/public/browser/browser_thread.h" 9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/content_browser_client.h" 10 #include "content/public/browser/content_browser_client.h"
11 #include "content/public/browser/resource_request_info.h" 11 #include "content/public/browser/resource_request_info.h"
12 #include "net/cert/x509_certificate.h"
12 #include "net/ssl/client_cert_store.h" 13 #include "net/ssl/client_cert_store.h"
13 #include "net/url_request/url_request.h" 14 #include "net/url_request/url_request.h"
14 15
15 namespace content { 16 namespace content {
16 17
18 namespace {
19
20 void CertificateSelectedOnUIThread(
21 const SSLClientAuthHandler::CertificateCallback& io_thread_callback,
22 net::X509Certificate* cert) {
23 DCHECK_CURRENTLY_ON(BrowserThread::UI);
24
25 BrowserThread::PostTask(
26 BrowserThread::IO, FROM_HERE,
27 base::Bind(io_thread_callback, make_scoped_refptr(cert)));
28 }
29
30 void SelectCertificateOnUIThread(
31 int render_process_host_id,
32 int render_frame_host_id,
33 net::SSLCertRequestInfo* cert_request_info,
34 const SSLClientAuthHandler::CertificateCallback& io_thread_callback) {
35 DCHECK_CURRENTLY_ON(BrowserThread::UI);
36
37 GetContentClient()->browser()->SelectClientCertificate(
38 render_process_host_id, render_frame_host_id, cert_request_info,
39 base::Bind(&CertificateSelectedOnUIThread, io_thread_callback));
40 }
41
42 } // namespace
43
44 // A reference-counted core to allow the ClientCertStore and SSLCertRequestInfo
45 // to outlive SSLClientAuthHandler if needbe.
46 class SSLClientAuthHandler::Core : public base::RefCountedThreadSafe<Core> {
47 public:
48 Core(const base::WeakPtr<SSLClientAuthHandler>& handler,
49 scoped_ptr<net::ClientCertStore> client_cert_store,
50 net::SSLCertRequestInfo* cert_request_info)
51 : handler_(handler),
52 client_cert_store_(client_cert_store.Pass()),
53 cert_request_info_(cert_request_info) {}
54
55 bool has_client_cert_store() const { return client_cert_store_; }
56
57 void GetClientCerts() {
58 if (client_cert_store_) {
59 client_cert_store_->GetClientCerts(
60 *cert_request_info_, &cert_request_info_->client_certs,
61 base::Bind(&SSLClientAuthHandler::Core::DidGetClientCerts, this));
pneubeck (no reviews) 2014/12/14 16:45:12 this seems still to be a rather weird ownership:
davidben 2015/01/23 21:05:35 Agreed. It's still the same issue that we had befo
62 } else {
63 DidGetClientCerts();
64 }
65 }
66
67 private:
68 friend class base::RefCountedThreadSafe<Core>;
69
70 ~Core() {}
71
72 // Called when |client_cert_store_| is done retrieving the cert list.
73 void DidGetClientCerts() {
74 if (handler_)
75 handler_->DidGetClientCerts();
76 }
77
78 base::WeakPtr<SSLClientAuthHandler> handler_;
79 scoped_ptr<net::ClientCertStore> client_cert_store_;
80 scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;
81 };
82
17 SSLClientAuthHandler::SSLClientAuthHandler( 83 SSLClientAuthHandler::SSLClientAuthHandler(
18 scoped_ptr<net::ClientCertStore> client_cert_store, 84 scoped_ptr<net::ClientCertStore> client_cert_store,
19 net::URLRequest* request, 85 net::URLRequest* request,
20 net::SSLCertRequestInfo* cert_request_info, 86 net::SSLCertRequestInfo* cert_request_info,
21 const SSLClientAuthHandler::CertificateCallback& callback) 87 const SSLClientAuthHandler::CertificateCallback& callback)
22 : request_(request), 88 : core_(nullptr),
pneubeck (no reviews) 2014/12/14 16:45:12 not required?
davidben 2015/01/23 21:05:35 Done.
89 request_(request),
23 cert_request_info_(cert_request_info), 90 cert_request_info_(cert_request_info),
24 client_cert_store_(client_cert_store.Pass()), 91 callback_(callback),
25 callback_(callback) { 92 weak_factory_(this) {
26 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 93 DCHECK_CURRENTLY_ON(BrowserThread::IO);
94
95 core_ = new Core(weak_factory_.GetWeakPtr(), client_cert_store.Pass(),
96 cert_request_info_.get());
27 } 97 }
28 98
29 SSLClientAuthHandler::~SSLClientAuthHandler() { 99 SSLClientAuthHandler::~SSLClientAuthHandler() {
pneubeck (no reviews) 2014/12/14 16:45:12 this should still somehow trigger a "shutdown" of
davidben 2015/01/23 21:05:35 I think this is also blocking on sorting out GetCl
30 // If we were simply dropped, then act as if we selected no certificate.
31 DoCertificateSelected(NULL);
32 }
33
34 void SSLClientAuthHandler::OnRequestCancelled() {
35 request_ = NULL;
36 callback_.Reset();
37 } 100 }
38 101
39 void SSLClientAuthHandler::SelectCertificate() { 102 void SSLClientAuthHandler::SelectCertificate() {
40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 103 DCHECK_CURRENTLY_ON(BrowserThread::IO);
41 DCHECK(request_);
42 104
43 if (client_cert_store_) { 105 // |core_| will call DidGetClientCerts when done.
44 client_cert_store_->GetClientCerts( 106 core_->GetClientCerts();
45 *cert_request_info_,
46 &cert_request_info_->client_certs,
47 base::Bind(&SSLClientAuthHandler::DidGetClientCerts, this));
48 } else {
49 DidGetClientCerts();
50 }
51 }
52
53 void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
55
56 DVLOG(1) << this << " CertificateSelected " << cert;
57 BrowserThread::PostTask(
58 BrowserThread::IO, FROM_HERE,
59 base::Bind(
60 &SSLClientAuthHandler::DoCertificateSelected, this,
61 make_scoped_refptr(cert)));
62 } 107 }
63 108
64 void SSLClientAuthHandler::DidGetClientCerts() { 109 void SSLClientAuthHandler::DidGetClientCerts() {
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 110 DCHECK_CURRENTLY_ON(BrowserThread::IO);
66 // Request may have cancelled while we were getting client certs.
67 if (!request_)
68 return;
69 111
70 // Note that if |client_cert_store_| is NULL, we intentionally fall through to 112 // Note that if |client_cert_store_| is NULL, we intentionally fall through to
71 // DoCertificateSelected. This is for platforms where the client cert matching 113 // DoCertificateSelected. This is for platforms where the client cert matching
72 // is not performed by Chrome, the platform can handle the cert matching 114 // is not performed by Chrome. Those platforms handle the cert matching before
73 // before showing the dialog. 115 // showing the dialog.
74 if (client_cert_store_ && cert_request_info_->client_certs.empty()) { 116 if (core_->has_client_cert_store() &&
117 cert_request_info_->client_certs.empty()) {
75 // No need to query the user if there are no certs to choose from. 118 // No need to query the user if there are no certs to choose from.
76 DoCertificateSelected(NULL); 119 CertificateSelected(NULL);
77 return; 120 return;
78 } 121 }
79 122
80 int render_process_host_id; 123 int render_process_host_id;
81 int render_frame_host_id; 124 int render_frame_host_id;
82 if (!ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame( 125 if (!ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame(
83 &render_process_host_id, 126 &render_process_host_id, &render_frame_host_id)) {
84 &render_frame_host_id))
85 NOTREACHED(); 127 NOTREACHED();
128 CertificateSelected(NULL);
129 return;
130 }
86 131
87 // If the RVH does not exist by the time this task gets run, then the task
88 // will be dropped and the scoped_refptr to SSLClientAuthHandler will go
89 // away, so we do not leak anything. The destructor takes care of ensuring
90 // the net::URLRequest always gets a response.
91 BrowserThread::PostTask( 132 BrowserThread::PostTask(
92 BrowserThread::UI, FROM_HERE, 133 BrowserThread::UI, FROM_HERE,
93 base::Bind( 134 base::Bind(&SelectCertificateOnUIThread, render_process_host_id,
94 &SSLClientAuthHandler::DoSelectCertificate, this, 135 render_frame_host_id, cert_request_info_,
95 render_process_host_id, render_frame_host_id)); 136 base::Bind(&SSLClientAuthHandler::CertificateSelected,
137 weak_factory_.GetWeakPtr())));
96 } 138 }
97 139
98 void SSLClientAuthHandler::DoCertificateSelected(net::X509Certificate* cert) { 140 void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) {
99 DVLOG(1) << this << " DoCertificateSelected " << cert; 141 DVLOG(1) << this << " DoCertificateSelected " << cert;
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 142 DCHECK_CURRENTLY_ON(BrowserThread::IO);
101 // request_ could have been NULLed if the request was cancelled while the
102 // user was choosing a cert, or because we have already responded to the
103 // certificate.
104 if (request_) {
105 request_ = NULL;
106 DCHECK(!callback_.is_null());
107 base::ResetAndReturn(&callback_).Run(cert);
108 }
109 }
110 143
111 void SSLClientAuthHandler::DoSelectCertificate( 144 callback_.Run(cert);
mmenke 2014/12/14 21:04:51 Think this should use reset and return on the call
davidben 2015/01/23 21:05:35 Hrm. Does it need to be? SelectCertificate should
112 int render_process_host_id, int render_frame_host_id) { 145 // |this| may be deleted at this point.
pneubeck (no reviews) 2014/12/14 16:45:13 ^^ shouldn't the implementor of the callback preve
mmenke 2014/12/14 21:04:51 In general, I think deletion tasks are uglier. De
pneubeck (no reviews) 2014/12/15 21:11:44 There also several definitions available that you
davidben 2015/01/23 21:05:35 That actually doesn't do the same thing. If you're
113 GetContentClient()->browser()->SelectClientCertificate(
114 render_process_host_id,
115 render_frame_host_id,
116 cert_request_info_.get(),
117 base::Bind(&SSLClientAuthHandler::CertificateSelected, this));
118 } 146 }
119 147
120 } // namespace content 148 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698