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

Side by Side Diff: remoting/host/token_validator_base.cc

Issue 165293004: Refactor TokenValidatorImpl into a base class + implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 9 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
« no previous file with comments | « remoting/host/token_validator_base.h ('k') | remoting/host/token_validator_factory_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "remoting/host/token_validator_factory_impl.h" 5 #include "remoting/host/token_validator_base.h"
6
7 #include <set>
8 6
9 #include "base/base64.h" 7 #include "base/base64.h"
10 #include "base/bind.h" 8 #include "base/bind.h"
11 #include "base/callback.h" 9 #include "base/callback.h"
12 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
13 #include "base/location.h"
14 #include "base/logging.h" 11 #include "base/logging.h"
15 #include "base/memory/weak_ptr.h" 12 #include "base/memory/weak_ptr.h"
16 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
18 #include "base/values.h" 15 #include "base/values.h"
19 #include "crypto/random.h"
20 #include "net/base/escape.h" 16 #include "net/base/escape.h"
21 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
22 #include "net/base/request_priority.h" 18 #include "net/base/request_priority.h"
23 #include "net/base/upload_bytes_element_reader.h" 19 #include "net/base/upload_bytes_element_reader.h"
24 #include "net/base/upload_data_stream.h" 20 #include "net/base/upload_data_stream.h"
25 #include "net/ssl/client_cert_store.h" 21 #include "net/ssl/client_cert_store.h"
26 #if defined(USE_NSS) 22 #if defined(USE_NSS)
27 #include "net/ssl/client_cert_store_nss.h" 23 #include "net/ssl/client_cert_store_nss.h"
28 #elif defined(OS_WIN) 24 #elif defined(OS_WIN)
29 #include "net/ssl/client_cert_store_win.h" 25 #include "net/ssl/client_cert_store_win.h"
30 #elif defined(OS_MACOSX) 26 #elif defined(OS_MACOSX)
31 #include "net/ssl/client_cert_store_mac.h" 27 #include "net/ssl/client_cert_store_mac.h"
32 #endif 28 #endif
33 #include "net/ssl/ssl_cert_request_info.h" 29 #include "net/ssl/ssl_cert_request_info.h"
34 #include "net/url_request/url_request.h" 30 #include "net/url_request/url_request.h"
35 #include "net/url_request/url_request_context.h" 31 #include "net/url_request/url_request_context.h"
36 #include "net/url_request/url_request_status.h" 32 #include "net/url_request/url_request_status.h"
37 #include "remoting/base/rsa_key_pair.h"
38 #include "url/gurl.h" 33 #include "url/gurl.h"
39 34
40 namespace { 35 namespace {
41 36
42 // Length in bytes of the cryptographic nonce used to salt the token scope.
43 const size_t kNonceLength = 16; // 128 bits.
44 const int kBufferSize = 4096; 37 const int kBufferSize = 4096;
45 const char kCertIssuerWildCard[] = "*"; 38 const char kCertIssuerWildCard[] = "*";
46 39
47 } // namespace 40 } // namespace
48 41
49 namespace remoting { 42 namespace remoting {
50 43
51 class TokenValidatorImpl 44 TokenValidatorBase::TokenValidatorBase(
52 : public net::URLRequest::Delegate,
53 public protocol::ThirdPartyHostAuthenticator::TokenValidator {
54 public:
55 TokenValidatorImpl(
56 const ThirdPartyAuthConfig& third_party_auth_config,
57 scoped_refptr<RsaKeyPair> key_pair,
58 const std::string& local_jid,
59 const std::string& remote_jid,
60 scoped_refptr<net::URLRequestContextGetter> request_context_getter);
61 virtual ~TokenValidatorImpl();
62
63 // TokenValidator interface.
64 virtual const GURL& token_url() const OVERRIDE;
65 virtual const std::string& token_scope() const OVERRIDE;
66 virtual void ValidateThirdPartyToken(
67 const std::string& token,
68 const base::Callback<void(
69 const std::string& shared_secret)>& on_token_validated) OVERRIDE;
70
71 // URLFetcherDelegate interface.
72 virtual void OnResponseStarted(net::URLRequest* source) OVERRIDE;
73 virtual void OnReadCompleted(net::URLRequest* source,
74 int bytes_read) OVERRIDE;
75 virtual void OnCertificateRequested(
76 net::URLRequest* source,
77 net::SSLCertRequestInfo* cert_request_info) OVERRIDE;
78
79 private:
80 static std::string CreateScope(const std::string& local_jid,
81 const std::string& remote_jid);
82
83 void OnCertificatesSelected(net::CertificateList* selected_certs,
84 net::ClientCertStore* unused);
85 bool IsValidScope(const std::string& token_scope);
86 std::string ProcessResponse();
87
88 std::string post_body_;
89 scoped_ptr<net::URLRequest> request_;
90 scoped_refptr<net::IOBuffer> buffer_;
91 std::string data_;
92 ThirdPartyAuthConfig third_party_auth_config_;
93 scoped_refptr<RsaKeyPair> key_pair_;
94 std::string token_scope_;
95 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
96 base::Callback<void(const std::string& shared_secret)> on_token_validated_;
97
98 base::WeakPtrFactory<TokenValidatorImpl> weak_factory_;
99
100 DISALLOW_COPY_AND_ASSIGN(TokenValidatorImpl);
101 };
102
103 TokenValidatorImpl::TokenValidatorImpl(
104 const ThirdPartyAuthConfig& third_party_auth_config, 45 const ThirdPartyAuthConfig& third_party_auth_config,
105 scoped_refptr<RsaKeyPair> key_pair, 46 const std::string& token_scope,
106 const std::string& local_jid,
107 const std::string& remote_jid,
108 scoped_refptr<net::URLRequestContextGetter> request_context_getter) 47 scoped_refptr<net::URLRequestContextGetter> request_context_getter)
109 : buffer_(new net::IOBuffer(kBufferSize)), 48 : third_party_auth_config_(third_party_auth_config),
110 third_party_auth_config_(third_party_auth_config), 49 token_scope_(token_scope),
111 key_pair_(key_pair),
112 request_context_getter_(request_context_getter), 50 request_context_getter_(request_context_getter),
51 buffer_(new net::IOBuffer(kBufferSize)),
113 weak_factory_(this) { 52 weak_factory_(this) {
114 DCHECK(third_party_auth_config_.token_url.is_valid()); 53 DCHECK(third_party_auth_config_.token_url.is_valid());
115 DCHECK(third_party_auth_config_.token_validation_url.is_valid()); 54 DCHECK(third_party_auth_config_.token_validation_url.is_valid());
116 DCHECK(key_pair_.get());
117 token_scope_ = CreateScope(local_jid, remote_jid);
118 } 55 }
119 56
120 TokenValidatorImpl::~TokenValidatorImpl() { 57 TokenValidatorBase::~TokenValidatorBase() {
121 } 58 }
122 59
123 // TokenValidator interface. 60 // TokenValidator interface.
124 void TokenValidatorImpl::ValidateThirdPartyToken( 61 void TokenValidatorBase::ValidateThirdPartyToken(
125 const std::string& token, 62 const std::string& token,
126 const base::Callback<void( 63 const base::Callback<void(
127 const std::string& shared_secret)>& on_token_validated) { 64 const std::string& shared_secret)>& on_token_validated) {
128 DCHECK(!request_); 65 DCHECK(!request_);
129 DCHECK(!on_token_validated.is_null()); 66 DCHECK(!on_token_validated.is_null());
130 67
131 on_token_validated_ = on_token_validated; 68 on_token_validated_ = on_token_validated;
132 69
133 post_body_ = "code=" + net::EscapeUrlEncodedData(token, true) + 70 StartValidateRequest(token);
134 "&client_id=" + net::EscapeUrlEncodedData(
135 key_pair_->GetPublicKey(), true) +
136 "&client_secret=" + net::EscapeUrlEncodedData(
137 key_pair_->SignMessage(token), true) +
138 "&grant_type=authorization_code";
139
140 request_ = request_context_getter_->GetURLRequestContext()->CreateRequest(
141 third_party_auth_config_.token_validation_url, net::DEFAULT_PRIORITY,
142 this);
143 request_->SetExtraRequestHeaderByName(
144 net::HttpRequestHeaders::kContentType,
145 "application/x-www-form-urlencoded", true);
146 request_->set_method("POST");
147 scoped_ptr<net::UploadElementReader> reader(
148 new net::UploadBytesElementReader(
149 post_body_.data(), post_body_.size()));
150 request_->set_upload(make_scoped_ptr(
151 net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
152 request_->Start();
153 } 71 }
154 72
155 const GURL& TokenValidatorImpl::token_url() const { 73 const GURL& TokenValidatorBase::token_url() const {
156 return third_party_auth_config_.token_url; 74 return third_party_auth_config_.token_url;
157 } 75 }
158 76
159 const std::string& TokenValidatorImpl::token_scope() const { 77 const std::string& TokenValidatorBase::token_scope() const {
160 return token_scope_; 78 return token_scope_;
161 } 79 }
162 80
163 // URLFetcherDelegate interface. 81 // URLFetcherDelegate interface.
164 void TokenValidatorImpl::OnResponseStarted(net::URLRequest* source) { 82 void TokenValidatorBase::OnResponseStarted(net::URLRequest* source) {
165 DCHECK_EQ(request_.get(), source); 83 DCHECK_EQ(request_.get(), source);
166 84
167 int bytes_read = 0; 85 int bytes_read = 0;
168 request_->Read(buffer_.get(), kBufferSize, &bytes_read); 86 request_->Read(buffer_.get(), kBufferSize, &bytes_read);
169 OnReadCompleted(request_.get(), bytes_read); 87 OnReadCompleted(request_.get(), bytes_read);
170 } 88 }
171 89
172 void TokenValidatorImpl::OnReadCompleted(net::URLRequest* source, 90 void TokenValidatorBase::OnReadCompleted(net::URLRequest* source,
173 int bytes_read) { 91 int bytes_read) {
174 DCHECK_EQ(request_.get(), source); 92 DCHECK_EQ(request_.get(), source);
175 93
176 do { 94 do {
177 if (!request_->status().is_success() || bytes_read <= 0) 95 if (!request_->status().is_success() || bytes_read <= 0)
178 break; 96 break;
179 97
180 data_.append(buffer_->data(), bytes_read); 98 data_.append(buffer_->data(), bytes_read);
181 } while (request_->Read(buffer_.get(), kBufferSize, &bytes_read)); 99 } while (request_->Read(buffer_.get(), kBufferSize, &bytes_read));
182 100
183 const net::URLRequestStatus status = request_->status(); 101 const net::URLRequestStatus status = request_->status();
184 102
185 if (!status.is_io_pending()) { 103 if (!status.is_io_pending()) {
186 std::string shared_token = ProcessResponse(); 104 std::string shared_token = ProcessResponse();
187 request_.reset(); 105 request_.reset();
188 on_token_validated_.Run(shared_token); 106 on_token_validated_.Run(shared_token);
189 } 107 }
190 } 108 }
191 109
192 void TokenValidatorImpl::OnCertificateRequested( 110 void TokenValidatorBase::OnCertificateRequested(
193 net::URLRequest* source, 111 net::URLRequest* source,
194 net::SSLCertRequestInfo* cert_request_info) { 112 net::SSLCertRequestInfo* cert_request_info) {
195 DCHECK_EQ(request_.get(), source); 113 DCHECK_EQ(request_.get(), source);
196 114
197 net::ClientCertStore* client_cert_store; 115 net::ClientCertStore* client_cert_store;
198 #if defined(USE_NSS) 116 #if defined(USE_NSS)
199 client_cert_store = new net::ClientCertStoreNSS( 117 client_cert_store = new net::ClientCertStoreNSS(
200 net::ClientCertStoreNSS::PasswordDelegateFactory()); 118 net::ClientCertStoreNSS::PasswordDelegateFactory());
201 #elif defined(OS_WIN) 119 #elif defined(OS_WIN)
202 client_cert_store = new net::ClientCertStoreWin(); 120 client_cert_store = new net::ClientCertStoreWin();
203 #elif defined(OS_MACOSX) 121 #elif defined(OS_MACOSX)
204 client_cert_store = new net::ClientCertStoreMac(); 122 client_cert_store = new net::ClientCertStoreMac();
205 #else 123 #else
206 #error Unknown platform. 124 #error Unknown platform.
207 #endif 125 #endif
208 // The callback is uncancellable, and GetClientCert requires selected_certs 126 // The callback is uncancellable, and GetClientCert requires selected_certs
209 // and client_cert_store to stay alive until the callback is called. So we 127 // and client_cert_store to stay alive until the callback is called. So we
210 // must give it a WeakPtr for |this|, and ownership of the other parameters. 128 // must give it a WeakPtr for |this|, and ownership of the other parameters.
211 net::CertificateList* selected_certs(new net::CertificateList()); 129 net::CertificateList* selected_certs(new net::CertificateList());
212 client_cert_store->GetClientCerts( 130 client_cert_store->GetClientCerts(
213 *cert_request_info, selected_certs, 131 *cert_request_info, selected_certs,
214 base::Bind(&TokenValidatorImpl::OnCertificatesSelected, 132 base::Bind(&TokenValidatorBase::OnCertificatesSelected,
215 weak_factory_.GetWeakPtr(), base::Owned(selected_certs), 133 weak_factory_.GetWeakPtr(), base::Owned(selected_certs),
216 base::Owned(client_cert_store))); 134 base::Owned(client_cert_store)));
217 } 135 }
218 136
219 void TokenValidatorImpl::OnCertificatesSelected( 137 void TokenValidatorBase::OnCertificatesSelected(
220 net::CertificateList* selected_certs, 138 net::CertificateList* selected_certs,
221 net::ClientCertStore* unused) { 139 net::ClientCertStore* unused) {
222 const std::string& issuer = 140 const std::string& issuer =
223 third_party_auth_config_.token_validation_cert_issuer; 141 third_party_auth_config_.token_validation_cert_issuer;
224 if (request_) { 142 if (request_) {
225 for (size_t i = 0; i < selected_certs->size(); ++i) { 143 for (size_t i = 0; i < selected_certs->size(); ++i) {
226 if (issuer == kCertIssuerWildCard || 144 if (issuer == kCertIssuerWildCard ||
227 issuer == (*selected_certs)[i]->issuer().common_name) { 145 issuer == (*selected_certs)[i]->issuer().common_name) {
228 request_->ContinueWithCertificate((*selected_certs)[i]); 146 request_->ContinueWithCertificate((*selected_certs)[i]);
229 return; 147 return;
230 } 148 }
231 } 149 }
232 request_->ContinueWithCertificate(NULL); 150 request_->ContinueWithCertificate(NULL);
233 } 151 }
234 } 152 }
235 153
236 bool TokenValidatorImpl::IsValidScope(const std::string& token_scope) { 154 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) {
237 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. 155 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc.
238 return token_scope == token_scope_; 156 return token_scope == token_scope_;
239 } 157 }
240 158
241 std::string TokenValidatorImpl::CreateScope( 159 std::string TokenValidatorBase::ProcessResponse() {
242 const std::string& local_jid,
243 const std::string& remote_jid) {
244 std::string nonce_bytes;
245 crypto::RandBytes(WriteInto(&nonce_bytes, kNonceLength + 1), kNonceLength);
246 std::string nonce;
247 base::Base64Encode(nonce_bytes, &nonce);
248 return "client:" + remote_jid + " host:" + local_jid + " nonce:" + nonce;
249 }
250
251 std::string TokenValidatorImpl::ProcessResponse() {
252 // Verify that we got a successful response. 160 // Verify that we got a successful response.
253 net::URLRequestStatus status = request_->status(); 161 net::URLRequestStatus status = request_->status();
254 if (!status.is_success()) { 162 if (!status.is_success()) {
255 LOG(ERROR) << "Error validating token, status=" << status.status() 163 LOG(ERROR) << "Error validating token, status=" << status.status()
256 << " err=" << status.error(); 164 << " err=" << status.error();
257 return std::string(); 165 return std::string();
258 } 166 }
259 167
260 int response = request_->GetResponseCode(); 168 int response = request_->GetResponseCode();
261 if (response != 200) { 169 if (response != 200) {
(...skipping 18 matching lines...) Expand all
280 << "', expected: '" << token_scope_ <<"'."; 188 << "', expected: '" << token_scope_ <<"'.";
281 return std::string(); 189 return std::string();
282 } 190 }
283 191
284 std::string shared_secret; 192 std::string shared_secret;
285 // Everything is valid, so return the shared secret to the caller. 193 // Everything is valid, so return the shared secret to the caller.
286 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); 194 dict->GetStringWithoutPathExpansion("access_token", &shared_secret);
287 return shared_secret; 195 return shared_secret;
288 } 196 }
289 197
290 TokenValidatorFactoryImpl::TokenValidatorFactoryImpl(
291 const ThirdPartyAuthConfig& third_party_auth_config,
292 scoped_refptr<RsaKeyPair> key_pair,
293 scoped_refptr<net::URLRequestContextGetter> request_context_getter)
294 : third_party_auth_config_(third_party_auth_config),
295 key_pair_(key_pair),
296 request_context_getter_(request_context_getter) {
297 }
298
299 TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() {
300 }
301
302 scoped_ptr<protocol::ThirdPartyHostAuthenticator::TokenValidator>
303 TokenValidatorFactoryImpl::CreateTokenValidator(
304 const std::string& local_jid,
305 const std::string& remote_jid) {
306 return scoped_ptr<protocol::ThirdPartyHostAuthenticator::TokenValidator>(
307 new TokenValidatorImpl(third_party_auth_config_,
308 key_pair_, local_jid, remote_jid,
309 request_context_getter_));
310 }
311
312 } // namespace remoting 198 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/token_validator_base.h ('k') | remoting/host/token_validator_factory_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698