OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "net/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
12 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/metrics/stats_counters.h" | 14 #include "base/metrics/stats_counters.h" |
15 #include "base/scoped_ptr.h" | 15 #include "base/scoped_ptr.h" |
16 #include "base/stl_util-inl.h" | 16 #include "base/stl_util-inl.h" |
17 #include "base/string_number_conversions.h" | 17 #include "base/string_number_conversions.h" |
18 #include "base/string_util.h" | 18 #include "base/string_util.h" |
19 #include "base/stringprintf.h" | 19 #include "base/stringprintf.h" |
| 20 #include "base/utf_string_conversions.h" |
20 #include "build/build_config.h" | 21 #include "build/build_config.h" |
21 #include "googleurl/src/gurl.h" | 22 #include "googleurl/src/gurl.h" |
22 #include "net/base/auth.h" | 23 #include "net/base/auth.h" |
23 #include "net/base/io_buffer.h" | 24 #include "net/base/io_buffer.h" |
24 #include "net/base/load_flags.h" | 25 #include "net/base/load_flags.h" |
25 #include "net/base/net_errors.h" | 26 #include "net/base/net_errors.h" |
26 #include "net/base/net_util.h" | 27 #include "net/base/net_util.h" |
27 #include "net/base/ssl_cert_request_info.h" | 28 #include "net/base/ssl_cert_request_info.h" |
28 #include "net/base/ssl_connection_status_flags.h" | 29 #include "net/base/ssl_connection_status_flags.h" |
29 #include "net/base/upload_data_stream.h" | 30 #include "net/base/upload_data_stream.h" |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 // Reset the other member variables. | 191 // Reset the other member variables. |
191 // Note: this is necessary only with SSL renegotiation. | 192 // Note: this is necessary only with SSL renegotiation. |
192 ResetStateForRestart(); | 193 ResetStateForRestart(); |
193 next_state_ = STATE_CREATE_STREAM; | 194 next_state_ = STATE_CREATE_STREAM; |
194 int rv = DoLoop(OK); | 195 int rv = DoLoop(OK); |
195 if (rv == ERR_IO_PENDING) | 196 if (rv == ERR_IO_PENDING) |
196 user_callback_ = callback; | 197 user_callback_ = callback; |
197 return rv; | 198 return rv; |
198 } | 199 } |
199 | 200 |
| 201 void HttpNetworkTransaction::SetTLSLoginAuthData(AuthData* auth_data) { |
| 202 DCHECK(!stream_request_.get()) << "Can't set TLS login on existing stream"; |
| 203 DCHECK(!stream_.get()); |
| 204 DCHECK_EQ(STATE_NONE, next_state_); |
| 205 |
| 206 DCHECK(!auth_data->username.empty()); |
| 207 DCHECK(!auth_data->password.empty()); |
| 208 |
| 209 tls_auth_data_ = auth_data; |
| 210 ssl_config_.tls_username = UTF16ToUTF8(auth_data->username); |
| 211 ssl_config_.tls_password = UTF16ToUTF8(auth_data->password); |
| 212 ssl_config_.use_tls_auth = true; |
| 213 ssl_config_.ssl3_enabled = false; |
| 214 ssl_config_.tls1_enabled = true; |
| 215 } |
| 216 |
| 217 int HttpNetworkTransaction::RestartWithTLSLogin(CompletionCallback* callback) { |
| 218 DCHECK(!stream_request_.get()); |
| 219 DCHECK(!stream_.get()); |
| 220 DCHECK_EQ(STATE_NONE, next_state_); |
| 221 |
| 222 DCHECK(!ssl_config_.tls_username.empty()); |
| 223 DCHECK(!ssl_config_.tls_password.empty()); |
| 224 DCHECK(ssl_config_.use_tls_auth); |
| 225 DCHECK(ssl_config_.tls1_enabled); |
| 226 DCHECK(!ssl_config_.ssl3_enabled); |
| 227 |
| 228 DCHECK(response_.login_request_info.get()); |
| 229 DCHECK(tls_auth_data_.get()); |
| 230 session_->tls_client_login_cache()->Add( |
| 231 WideToUTF8(response_.login_request_info->host_and_port), |
| 232 tls_auth_data_); |
| 233 |
| 234 // Reset the other member variables. |
| 235 // Note: this is necessary only with SSL renegotiation. |
| 236 ResetStateForRestart(); |
| 237 next_state_ = STATE_CREATE_STREAM; |
| 238 int rv = DoLoop(OK); |
| 239 if (rv == ERR_IO_PENDING) |
| 240 user_callback_ = callback; |
| 241 return rv; |
| 242 } |
| 243 |
200 int HttpNetworkTransaction::RestartWithAuth( | 244 int HttpNetworkTransaction::RestartWithAuth( |
201 const string16& username, | 245 const string16& username, |
202 const string16& password, | 246 const string16& password, |
203 CompletionCallback* callback) { | 247 CompletionCallback* callback) { |
204 HttpAuth::Target target = pending_auth_target_; | 248 HttpAuth::Target target = pending_auth_target_; |
205 if (target == HttpAuth::AUTH_NONE) { | 249 if (target == HttpAuth::AUTH_NONE) { |
206 NOTREACHED(); | 250 NOTREACHED(); |
207 return ERR_UNEXPECTED; | 251 return ERR_UNEXPECTED; |
208 } | 252 } |
209 pending_auth_target_ = HttpAuth::AUTH_NONE; | 253 pending_auth_target_ = HttpAuth::AUTH_NONE; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 367 |
324 next_state_ = next_state; | 368 next_state_ = next_state; |
325 int rv = DoLoop(OK); | 369 int rv = DoLoop(OK); |
326 if (rv == ERR_IO_PENDING) | 370 if (rv == ERR_IO_PENDING) |
327 user_callback_ = callback; | 371 user_callback_ = callback; |
328 return rv; | 372 return rv; |
329 } | 373 } |
330 | 374 |
331 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { | 375 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { |
332 return ((headers_valid_ && response_.headers) || response_.ssl_info.cert || | 376 return ((headers_valid_ && response_.headers) || response_.ssl_info.cert || |
333 response_.cert_request_info) ? &response_ : NULL; | 377 !response_.ssl_info.tls_username.empty() || |
| 378 response_.cert_request_info || response_.login_request_info) ? |
| 379 &response_ : NULL; |
334 } | 380 } |
335 | 381 |
336 LoadState HttpNetworkTransaction::GetLoadState() const { | 382 LoadState HttpNetworkTransaction::GetLoadState() const { |
337 // TODO(wtc): Define a new LoadState value for the | 383 // TODO(wtc): Define a new LoadState value for the |
338 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. | 384 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. |
339 switch (next_state_) { | 385 switch (next_state_) { |
340 case STATE_CREATE_STREAM_COMPLETE: | 386 case STATE_CREATE_STREAM_COMPLETE: |
341 return stream_request_->GetLoadState(); | 387 return stream_request_->GetLoadState(); |
342 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: | 388 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: |
343 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE: | 389 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE: |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } | 464 } |
419 | 465 |
420 void HttpNetworkTransaction::OnNeedsClientAuth( | 466 void HttpNetworkTransaction::OnNeedsClientAuth( |
421 SSLCertRequestInfo* cert_info) { | 467 SSLCertRequestInfo* cert_info) { |
422 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | 468 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
423 | 469 |
424 response_.cert_request_info = cert_info; | 470 response_.cert_request_info = cert_info; |
425 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | 471 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); |
426 } | 472 } |
427 | 473 |
| 474 void HttpNetworkTransaction::OnNeedsTLSLogin( |
| 475 AuthChallengeInfo* login_info) { |
| 476 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
| 477 |
| 478 response_.login_request_info = login_info; |
| 479 OnIOComplete(ERR_TLS_CLIENT_LOGIN_NEEDED); |
| 480 } |
| 481 |
428 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( | 482 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( |
429 const HttpResponseInfo& response_info, | 483 const HttpResponseInfo& response_info, |
430 HttpStream* stream) { | 484 HttpStream* stream) { |
431 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | 485 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
432 | 486 |
433 headers_valid_ = true; | 487 headers_valid_ = true; |
434 response_ = response_info; | 488 response_ = response_info; |
435 stream_.reset(stream); | 489 stream_.reset(stream); |
436 stream_request_.reset(); // we're done with the stream request | 490 stream_request_.reset(); // we're done with the stream request |
437 OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); | 491 OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 NOTREACHED() << "bad state"; | 589 NOTREACHED() << "bad state"; |
536 rv = ERR_FAILED; | 590 rv = ERR_FAILED; |
537 break; | 591 break; |
538 } | 592 } |
539 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 593 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
540 | 594 |
541 return rv; | 595 return rv; |
542 } | 596 } |
543 | 597 |
544 int HttpNetworkTransaction::DoCreateStream() { | 598 int HttpNetworkTransaction::DoCreateStream() { |
| 599 DCHECK(request_); |
| 600 |
| 601 // Set TLS login, if available. |
| 602 if (ssl_config_.use_tls_auth) { |
| 603 // TODO(sqs): implement some way of forcing TLS auth (as right below) |
| 604 // if (...) ssl_config_.require_tls_auth = true; |
| 605 if (ssl_config_.tls_username.empty()) { |
| 606 scoped_refptr<AuthData> tls_auth_data; |
| 607 bool found_login = session_->tls_client_login_cache()->Lookup( |
| 608 net::GetHostAndPort(request_->url), |
| 609 &tls_auth_data); |
| 610 if (found_login) { |
| 611 LOG(INFO) << "Got TLS login from cache"; |
| 612 SetTLSLoginAuthData(tls_auth_data); |
| 613 DCHECK(!ssl_config_.tls_username.empty()); |
| 614 DCHECK(!ssl_config_.tls_password.empty()); |
| 615 } else if (ssl_config_.require_tls_auth) { |
| 616 response_.login_request_info = new AuthChallengeInfo; |
| 617 response_.login_request_info->host_and_port = |
| 618 UTF8ToWide(net::GetHostAndPort(request_->url)); |
| 619 response_.login_request_info->scheme = ASCIIToWide(net::kTLSSRPScheme); |
| 620 response_.login_request_info->over_protocol = AUTH_OVER_TLS; |
| 621 return ERR_TLS_CLIENT_LOGIN_NEEDED; |
| 622 } |
| 623 } |
| 624 } |
| 625 |
545 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 626 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
546 | 627 |
547 stream_request_.reset( | 628 stream_request_.reset( |
548 session_->http_stream_factory()->RequestStream( | 629 session_->http_stream_factory()->RequestStream( |
549 request_, | 630 request_, |
550 &ssl_config_, | 631 &ssl_config_, |
551 &proxy_info_, | 632 &proxy_info_, |
552 session_, | 633 session_, |
553 this, | 634 this, |
554 net_log_)); | 635 net_log_)); |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 // by the endpoint host, request_->url, rather than considering if they were | 1111 // by the endpoint host, request_->url, rather than considering if they were |
1031 // generated by the SSL proxy. http://crbug.com/69329 | 1112 // generated by the SSL proxy. http://crbug.com/69329 |
1032 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { | 1113 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { |
1033 DCHECK(request_); | 1114 DCHECK(request_); |
1034 if (ssl_config_.send_client_cert && | 1115 if (ssl_config_.send_client_cert && |
1035 (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) { | 1116 (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) { |
1036 session_->ssl_client_auth_cache()->Remove( | 1117 session_->ssl_client_auth_cache()->Remove( |
1037 GetHostAndPort(request_->url)); | 1118 GetHostAndPort(request_->url)); |
1038 } | 1119 } |
1039 | 1120 |
| 1121 // Check for TLS-SRP-related errors. |
| 1122 if (ssl_config_.use_tls_auth) { |
| 1123 if (ssl_config_.tls_username.empty() && ssl_config_.tls_password.empty()) { |
| 1124 if (error == ERR_SSL_UNKNOWN_PSK_IDENTITY_ALERT) { |
| 1125 // RFC 5054 unknown_psk_identity idiom: The Client Hello contained no |
| 1126 // SRP username, but the server wishes to connect using an SRP cipher |
| 1127 // suite. |
| 1128 error = ERR_TLS_CLIENT_LOGIN_NEEDED; |
| 1129 } |
| 1130 } else if (!ssl_config_.tls_username.empty() && |
| 1131 ssl_config_.tls_password.empty()) { |
| 1132 LOG(WARNING) << "SSL handshake error: empty TLS password"; |
| 1133 } else if (!ssl_config_.tls_username.empty() && |
| 1134 !ssl_config_.tls_password.empty()) { |
| 1135 if (error == ERR_SSL_BAD_RECORD_MAC_ALERT || |
| 1136 error == ERR_SSL_UNKNOWN_PSK_IDENTITY_ALERT) { |
| 1137 // The TLS-SRP login probably failed. |
| 1138 // TODO(sqs): also verify that we did attempt to use an SRP cipher suite |
| 1139 error = ERR_TLS_CLIENT_LOGIN_FAILED; |
| 1140 } |
| 1141 } |
| 1142 |
| 1143 if (error == ERR_TLS_CLIENT_LOGIN_FAILED) |
| 1144 session_->tls_client_login_cache()->Remove(GetHostAndPort(request_->url)); |
| 1145 |
| 1146 // Handle TLS-SRP errors now. |
| 1147 if (error == ERR_TLS_CLIENT_LOGIN_FAILED || |
| 1148 error == ERR_TLS_CLIENT_LOGIN_NEEDED) { |
| 1149 DCHECK(!response_.login_request_info.get()); |
| 1150 response_.login_request_info = new AuthChallengeInfo; |
| 1151 response_.login_request_info->host_and_port = |
| 1152 UTF8ToWide(GetHostAndPort(request_->url)); |
| 1153 response_.login_request_info->scheme = ASCIIToWide(net::kTLSSRPScheme); |
| 1154 response_.login_request_info->over_protocol = AUTH_OVER_TLS; |
| 1155 return error; |
| 1156 } |
| 1157 } |
| 1158 |
1040 switch (error) { | 1159 switch (error) { |
1041 case ERR_SSL_PROTOCOL_ERROR: | 1160 case ERR_SSL_PROTOCOL_ERROR: |
1042 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: | 1161 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: |
1043 case ERR_SSL_DECOMPRESSION_FAILURE_ALERT: | 1162 case ERR_SSL_DECOMPRESSION_FAILURE_ALERT: |
1044 case ERR_SSL_BAD_RECORD_MAC_ALERT: | 1163 case ERR_SSL_BAD_RECORD_MAC_ALERT: |
1045 if (ssl_config_.tls1_enabled && | 1164 if (ssl_config_.tls1_enabled && |
1046 !SSLConfigService::IsKnownStrictTLSServer(request_->url.host())) { | 1165 !SSLConfigService::IsKnownStrictTLSServer(request_->url.host()) && |
| 1166 !ssl_config_.require_tls_auth) { |
1047 // This could be a TLS-intolerant server, an SSL 3.0 server that | 1167 // This could be a TLS-intolerant server, an SSL 3.0 server that |
1048 // chose a TLS-only cipher suite or a server with buggy DEFLATE | 1168 // chose a TLS-only cipher suite or a server with buggy DEFLATE |
1049 // support. Turn off TLS 1.0, DEFLATE support and retry. | 1169 // support. Turn off TLS 1.0, DEFLATE support and retry. |
| 1170 LOG(WARNING) << "Set server TLS intolerant: " << request_->url; |
1050 session_->http_stream_factory()->AddTLSIntolerantServer(request_->url); | 1171 session_->http_stream_factory()->AddTLSIntolerantServer(request_->url); |
1051 ResetConnectionAndRequestForResend(); | 1172 ResetConnectionAndRequestForResend(); |
1052 error = OK; | 1173 error = OK; |
1053 } | 1174 } |
1054 break; | 1175 break; |
1055 case ERR_SSL_SNAP_START_NPN_MISPREDICTION: | 1176 case ERR_SSL_SNAP_START_NPN_MISPREDICTION: |
1056 // This means that we tried to Snap Start a connection, but we | 1177 // This means that we tried to Snap Start a connection, but we |
1057 // mispredicted the NPN result. This isn't a problem from the point of | 1178 // mispredicted the NPN result. This isn't a problem from the point of |
1058 // view of the SSL layer because the server will ignore the application | 1179 // view of the SSL layer because the server will ignore the application |
1059 // data in the Snap Start extension. However, at the HTTP layer, we have | 1180 // data in the Snap Start extension. However, at the HTTP layer, we have |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 1349 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, |
1229 state); | 1350 state); |
1230 break; | 1351 break; |
1231 } | 1352 } |
1232 return description; | 1353 return description; |
1233 } | 1354 } |
1234 | 1355 |
1235 #undef STATE_CASE | 1356 #undef STATE_CASE |
1236 | 1357 |
1237 } // namespace net | 1358 } // namespace net |
OLD | NEW |