| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // TODO(ukai): code is similar with http_network_transaction.cc. We should | 5 // TODO(ukai): code is similar with http_network_transaction.cc. We should |
| 6 // think about ways to share code, if possible. | 6 // think about ways to share code, if possible. |
| 7 | 7 |
| 8 #include "net/socket_stream/socket_stream.h" | 8 #include "net/socket_stream/socket_stream.h" |
| 9 | 9 |
| 10 #include <set> | 10 #include <set> |
| 11 #include <string> | 11 #include <string> |
| 12 | 12 |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
| 18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
| 19 #include "net/base/auth.h" | 19 #include "net/base/auth.h" |
| 20 #include "net/base/host_resolver.h" | 20 #include "net/base/host_resolver.h" |
| 21 #include "net/base/io_buffer.h" | 21 #include "net/base/io_buffer.h" |
| 22 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 23 #include "net/base/net_util.h" | 23 #include "net/base/net_util.h" |
| 24 #include "net/base/ssl_cert_request_info.h" |
| 24 #include "net/http/http_auth_handler_factory.h" | 25 #include "net/http/http_auth_handler_factory.h" |
| 26 #include "net/http/http_network_session.h" |
| 25 #include "net/http/http_request_info.h" | 27 #include "net/http/http_request_info.h" |
| 26 #include "net/http/http_response_headers.h" | 28 #include "net/http/http_response_headers.h" |
| 29 #include "net/http/http_transaction_factory.h" |
| 27 #include "net/http/http_util.h" | 30 #include "net/http/http_util.h" |
| 28 #include "net/socket/client_socket_factory.h" | 31 #include "net/socket/client_socket_factory.h" |
| 29 #include "net/socket/socks5_client_socket.h" | 32 #include "net/socket/socks5_client_socket.h" |
| 30 #include "net/socket/socks_client_socket.h" | 33 #include "net/socket/socks_client_socket.h" |
| 31 #include "net/socket/ssl_client_socket.h" | 34 #include "net/socket/ssl_client_socket.h" |
| 32 #include "net/socket/tcp_client_socket.h" | 35 #include "net/socket/tcp_client_socket.h" |
| 33 #include "net/socket_stream/socket_stream_metrics.h" | 36 #include "net/socket_stream/socket_stream_metrics.h" |
| 34 #include "net/url_request/url_request.h" | 37 #include "net/url_request/url_request.h" |
| 35 | 38 |
| 36 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. | 39 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 origin_bound_cert_service_ = context_->origin_bound_cert_service(); | 128 origin_bound_cert_service_ = context_->origin_bound_cert_service(); |
| 126 http_auth_handler_factory_ = context_->http_auth_handler_factory(); | 129 http_auth_handler_factory_ = context_->http_auth_handler_factory(); |
| 127 } | 130 } |
| 128 } | 131 } |
| 129 | 132 |
| 130 void SocketStream::Connect() { | 133 void SocketStream::Connect() { |
| 131 DCHECK(MessageLoop::current()) << | 134 DCHECK(MessageLoop::current()) << |
| 132 "The current MessageLoop must exist"; | 135 "The current MessageLoop must exist"; |
| 133 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 136 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
| 134 "The current MessageLoop must be TYPE_IO"; | 137 "The current MessageLoop must be TYPE_IO"; |
| 135 if (context_) | 138 if (context_) { |
| 136 ssl_config_service()->GetSSLConfig(&ssl_config_); | 139 ssl_config_service()->GetSSLConfig(&server_ssl_config_); |
| 140 proxy_ssl_config_ = server_ssl_config_; |
| 141 } |
| 137 DCHECK_EQ(next_state_, STATE_NONE); | 142 DCHECK_EQ(next_state_, STATE_NONE); |
| 138 | 143 |
| 139 AddRef(); // Released in Finish() | 144 AddRef(); // Released in Finish() |
| 140 // Open a connection asynchronously, so that delegate won't be called | 145 // Open a connection asynchronously, so that delegate won't be called |
| 141 // back before returning Connect(). | 146 // back before returning Connect(). |
| 142 next_state_ = STATE_RESOLVE_PROXY; | 147 next_state_ = STATE_RESOLVE_PROXY; |
| 143 net_log_.BeginEvent( | 148 net_log_.BeginEvent( |
| 144 NetLog::TYPE_SOCKET_STREAM_CONNECT, | 149 NetLog::TYPE_SOCKET_STREAM_CONNECT, |
| 145 make_scoped_refptr( | 150 make_scoped_refptr( |
| 146 new NetLogStringParameter("url", url_.possibly_invalid_spec()))); | 151 new NetLogStringParameter("url", url_.possibly_invalid_spec()))); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 Delegate* delegate = delegate_; | 302 Delegate* delegate = delegate_; |
| 298 delegate_ = NULL; | 303 delegate_ = NULL; |
| 299 if (delegate) { | 304 if (delegate) { |
| 300 delegate->OnError(this, result); | 305 delegate->OnError(this, result); |
| 301 if (result != ERR_PROTOCOL_SWITCHED) | 306 if (result != ERR_PROTOCOL_SWITCHED) |
| 302 delegate->OnClose(this); | 307 delegate->OnClose(this); |
| 303 } | 308 } |
| 304 Release(); | 309 Release(); |
| 305 } | 310 } |
| 306 | 311 |
| 307 int SocketStream::DidEstablishSSL(int result) { | 312 int SocketStream::DidEstablishSSL(int result, SSLConfig* ssl_config) { |
| 313 DCHECK(ssl_config); |
| 308 if (IsCertificateError(result)) { | 314 if (IsCertificateError(result)) { |
| 309 if (socket_->IsConnectedAndIdle()) { | 315 if (socket_->IsConnectedAndIdle()) { |
| 310 result = HandleCertificateError(result); | 316 result = HandleCertificateError(result); |
| 311 } else { | 317 } else { |
| 312 // SSLClientSocket for Mac will report socket is not connected, | 318 // SSLClientSocket for Mac will report socket is not connected, |
| 313 // if it returns cert verification error. It didn't perform | 319 // if it returns cert verification error. It didn't perform |
| 314 // SSLHandshake yet. | 320 // SSLHandshake yet. |
| 315 // So, we should restart establishing connection with the | 321 // So, we should restart establishing connection with the |
| 316 // certificate in allowed bad certificates in |ssl_config_|. | 322 // certificate in allowed bad certificates in |ssl_config|. |
| 317 // See also net/http/http_network_transaction.cc | 323 // See also net/http/http_network_transaction.cc |
| 318 // HandleCertificateError() and RestartIgnoringLastError(). | 324 // HandleCertificateError() and RestartIgnoringLastError(). |
| 319 SSLClientSocket* ssl_socket = | 325 SSLClientSocket* ssl_socket = |
| 320 reinterpret_cast<SSLClientSocket*>(socket_.get()); | 326 static_cast<SSLClientSocket*>(socket_.get()); |
| 321 SSLInfo ssl_info; | 327 SSLInfo ssl_info; |
| 322 ssl_socket->GetSSLInfo(&ssl_info); | 328 ssl_socket->GetSSLInfo(&ssl_info); |
| 323 if (ssl_info.cert == NULL || | 329 if (ssl_info.cert == NULL || |
| 324 ssl_config_.IsAllowedBadCert(ssl_info.cert, NULL)) { | 330 ssl_config->IsAllowedBadCert(ssl_info.cert, NULL)) { |
| 325 // If we already have the certificate in the set of allowed bad | 331 // If we already have the certificate in the set of allowed bad |
| 326 // certificates, we did try it and failed again, so we should not | 332 // certificates, we did try it and failed again, so we should not |
| 327 // retry again: the connection should fail at last. | 333 // retry again: the connection should fail at last. |
| 328 next_state_ = STATE_CLOSE; | 334 next_state_ = STATE_CLOSE; |
| 329 return result; | 335 return result; |
| 330 } | 336 } |
| 331 // Add the bad certificate to the set of allowed certificates in the | 337 // Add the bad certificate to the set of allowed certificates in the |
| 332 // SSL config object. | 338 // SSL config object. |
| 333 SSLConfig::CertAndStatus bad_cert; | 339 SSLConfig::CertAndStatus bad_cert; |
| 334 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) { | 340 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) { |
| 335 next_state_ = STATE_CLOSE; | 341 next_state_ = STATE_CLOSE; |
| 336 return result; | 342 return result; |
| 337 } | 343 } |
| 338 bad_cert.cert_status = ssl_info.cert_status; | 344 bad_cert.cert_status = ssl_info.cert_status; |
| 339 ssl_config_.allowed_bad_certs.push_back(bad_cert); | 345 ssl_config->allowed_bad_certs.push_back(bad_cert); |
| 340 // Restart connection ignoring the bad certificate. | 346 // Restart connection ignoring the bad certificate. |
| 341 socket_->Disconnect(); | 347 socket_->Disconnect(); |
| 342 socket_.reset(); | 348 socket_.reset(); |
| 343 next_state_ = STATE_TCP_CONNECT; | 349 next_state_ = STATE_TCP_CONNECT; |
| 344 return OK; | 350 return OK; |
| 345 } | 351 } |
| 346 } | 352 } |
| 347 return result; | 353 return result; |
| 348 } | 354 } |
| 349 | 355 |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 | 909 |
| 904 int SocketStream::DoSecureProxyConnect() { | 910 int SocketStream::DoSecureProxyConnect() { |
| 905 DCHECK(factory_); | 911 DCHECK(factory_); |
| 906 SSLClientSocketContext ssl_context; | 912 SSLClientSocketContext ssl_context; |
| 907 ssl_context.cert_verifier = cert_verifier_; | 913 ssl_context.cert_verifier = cert_verifier_; |
| 908 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; | 914 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; |
| 909 // TODO(agl): look into plumbing SSLHostInfo here. | 915 // TODO(agl): look into plumbing SSLHostInfo here. |
| 910 socket_.reset(factory_->CreateSSLClientSocket( | 916 socket_.reset(factory_->CreateSSLClientSocket( |
| 911 socket_.release(), | 917 socket_.release(), |
| 912 proxy_info_.proxy_server().host_port_pair(), | 918 proxy_info_.proxy_server().host_port_pair(), |
| 913 ssl_config_, | 919 proxy_ssl_config_, |
| 914 NULL /* ssl_host_info */, | 920 NULL /* ssl_host_info */, |
| 915 ssl_context)); | 921 ssl_context)); |
| 916 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE; | 922 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE; |
| 917 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION); | 923 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION); |
| 918 return socket_->Connect(&io_callback_); | 924 return socket_->Connect(&io_callback_); |
| 919 } | 925 } |
| 920 | 926 |
| 921 int SocketStream::DoSecureProxyConnectComplete(int result) { | 927 int SocketStream::DoSecureProxyConnectComplete(int result) { |
| 922 DCHECK_EQ(STATE_NONE, next_state_); | 928 DCHECK_EQ(STATE_NONE, next_state_); |
| 923 result = DidEstablishSSL(result); | 929 result = DidEstablishSSL(result, &proxy_ssl_config_); |
| 924 if (next_state_ != STATE_NONE) | 930 if (next_state_ != STATE_NONE) |
| 925 return result; | 931 return result; |
| 932 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) |
| 933 return HandleCertificateRequest(result); |
| 926 if (result == OK) | 934 if (result == OK) |
| 927 next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 935 next_state_ = STATE_WRITE_TUNNEL_HEADERS; |
| 928 else | 936 else |
| 929 next_state_ = STATE_CLOSE; | 937 next_state_ = STATE_CLOSE; |
| 930 return result; | 938 return result; |
| 931 } | 939 } |
| 932 | 940 |
| 933 int SocketStream::DoSSLConnect() { | 941 int SocketStream::DoSSLConnect() { |
| 934 DCHECK(factory_); | 942 DCHECK(factory_); |
| 935 SSLClientSocketContext ssl_context; | 943 SSLClientSocketContext ssl_context; |
| 936 ssl_context.cert_verifier = cert_verifier_; | 944 ssl_context.cert_verifier = cert_verifier_; |
| 937 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; | 945 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; |
| 938 // TODO(agl): look into plumbing SSLHostInfo here. | 946 // TODO(agl): look into plumbing SSLHostInfo here. |
| 939 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), | 947 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), |
| 940 HostPortPair::FromURL(url_), | 948 HostPortPair::FromURL(url_), |
| 941 ssl_config_, | 949 server_ssl_config_, |
| 942 NULL /* ssl_host_info */, | 950 NULL /* ssl_host_info */, |
| 943 ssl_context)); | 951 ssl_context)); |
| 944 next_state_ = STATE_SSL_CONNECT_COMPLETE; | 952 next_state_ = STATE_SSL_CONNECT_COMPLETE; |
| 945 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); | 953 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); |
| 946 return socket_->Connect(&io_callback_); | 954 return socket_->Connect(&io_callback_); |
| 947 } | 955 } |
| 948 | 956 |
| 949 int SocketStream::DoSSLConnectComplete(int result) { | 957 int SocketStream::DoSSLConnectComplete(int result) { |
| 950 DCHECK_EQ(STATE_NONE, next_state_); | 958 DCHECK_EQ(STATE_NONE, next_state_); |
| 951 result = DidEstablishSSL(result); | 959 result = DidEstablishSSL(result, &server_ssl_config_); |
| 952 if (next_state_ != STATE_NONE) | 960 if (next_state_ != STATE_NONE) |
| 953 return result; | 961 return result; |
| 954 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. | 962 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. |
| 955 // If we use HTTPS and this is the first connection to the SPDY server, | 963 // If we use HTTPS and this is the first connection to the SPDY server, |
| 956 // we should take care of TLS NPN extension here. | 964 // we should take care of TLS NPN extension here. |
| 957 | 965 |
| 958 if (result == OK) | 966 if (result == OK) |
| 959 result = DidEstablishConnection(); | 967 result = DidEstablishConnection(); |
| 960 else | 968 else |
| 961 next_state_ = STATE_CLOSE; | 969 next_state_ = STATE_CLOSE; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 auth_identity_.password = entry->password(); | 1089 auth_identity_.password = entry->password(); |
| 1082 // Restart with auth info. | 1090 // Restart with auth info. |
| 1083 } | 1091 } |
| 1084 return ERR_PROXY_AUTH_UNSUPPORTED; | 1092 return ERR_PROXY_AUTH_UNSUPPORTED; |
| 1085 } else { | 1093 } else { |
| 1086 auth_identity_.invalid = false; | 1094 auth_identity_.invalid = false; |
| 1087 } | 1095 } |
| 1088 return ERR_TUNNEL_CONNECTION_FAILED; | 1096 return ERR_TUNNEL_CONNECTION_FAILED; |
| 1089 } | 1097 } |
| 1090 | 1098 |
| 1099 int SocketStream::HandleCertificateRequest(int result) { |
| 1100 // TODO(toyoshim): We must support SSL client authentication for not only |
| 1101 // secure proxy but also secure server. |
| 1102 |
| 1103 if (proxy_ssl_config_.send_client_cert) |
| 1104 // We already have performed SSL client authentication once and failed. |
| 1105 return result; |
| 1106 |
| 1107 DCHECK(socket_.get()); |
| 1108 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; |
| 1109 SSLClientSocket* ssl_socket = |
| 1110 static_cast<SSLClientSocket*>(socket_.get()); |
| 1111 ssl_socket->GetSSLCertRequestInfo(cert_request_info); |
| 1112 |
| 1113 HttpTransactionFactory* factory = context_->http_transaction_factory(); |
| 1114 if (!factory) |
| 1115 return result; |
| 1116 scoped_refptr<HttpNetworkSession> session = factory->GetSession(); |
| 1117 if (!session.get()) |
| 1118 return result; |
| 1119 |
| 1120 scoped_refptr<X509Certificate> client_cert; |
| 1121 bool found_cached_cert = session->ssl_client_auth_cache()->Lookup( |
| 1122 cert_request_info->host_and_port, &client_cert); |
| 1123 if (!found_cached_cert) |
| 1124 return result; |
| 1125 if (!client_cert) |
| 1126 return result; |
| 1127 |
| 1128 const std::vector<scoped_refptr<X509Certificate> >& client_certs = |
| 1129 cert_request_info->client_certs; |
| 1130 bool cert_still_valid = false; |
| 1131 for (size_t i = 0; i < client_certs.size(); ++i) { |
| 1132 if (client_cert->Equals(client_certs[i])) { |
| 1133 cert_still_valid = true; |
| 1134 break; |
| 1135 } |
| 1136 } |
| 1137 if (!cert_still_valid) |
| 1138 return result; |
| 1139 |
| 1140 proxy_ssl_config_.send_client_cert = true; |
| 1141 proxy_ssl_config_.client_cert = client_cert; |
| 1142 next_state_ = STATE_TCP_CONNECT; |
| 1143 return OK; |
| 1144 } |
| 1145 |
| 1091 void SocketStream::DoAuthRequired() { | 1146 void SocketStream::DoAuthRequired() { |
| 1092 if (delegate_ && auth_info_.get()) | 1147 if (delegate_ && auth_info_.get()) |
| 1093 delegate_->OnAuthRequired(this, auth_info_.get()); | 1148 delegate_->OnAuthRequired(this, auth_info_.get()); |
| 1094 else | 1149 else |
| 1095 DoLoop(ERR_UNEXPECTED); | 1150 DoLoop(ERR_UNEXPECTED); |
| 1096 } | 1151 } |
| 1097 | 1152 |
| 1098 void SocketStream::DoRestartWithAuth() { | 1153 void SocketStream::DoRestartWithAuth() { |
| 1099 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); | 1154 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); |
| 1100 auth_cache_.Add(ProxyAuthOrigin(), | 1155 auth_cache_.Add(ProxyAuthOrigin(), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1131 | 1186 |
| 1132 SSLConfigService* SocketStream::ssl_config_service() const { | 1187 SSLConfigService* SocketStream::ssl_config_service() const { |
| 1133 return context_->ssl_config_service(); | 1188 return context_->ssl_config_service(); |
| 1134 } | 1189 } |
| 1135 | 1190 |
| 1136 ProxyService* SocketStream::proxy_service() const { | 1191 ProxyService* SocketStream::proxy_service() const { |
| 1137 return context_->proxy_service(); | 1192 return context_->proxy_service(); |
| 1138 } | 1193 } |
| 1139 | 1194 |
| 1140 } // namespace net | 1195 } // namespace net |
| OLD | NEW |