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 |