| 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 |