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

Side by Side Diff: net/socket_stream/socket_stream.cc

Issue 7468025: secure proxy support in websocket (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 5 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 | « net/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_metrics.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 (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>
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 Delegate* delegate = delegate_; 295 Delegate* delegate = delegate_;
296 delegate_ = NULL; 296 delegate_ = NULL;
297 if (delegate) { 297 if (delegate) {
298 delegate->OnError(this, result); 298 delegate->OnError(this, result);
299 if (result != ERR_PROTOCOL_SWITCHED) 299 if (result != ERR_PROTOCOL_SWITCHED)
300 delegate->OnClose(this); 300 delegate->OnClose(this);
301 } 301 }
302 Release(); 302 Release();
303 } 303 }
304 304
305 int SocketStream::DidEstablishSSL(int result) {
306 if (IsCertificateError(result)) {
307 if (socket_->IsConnectedAndIdle()) {
308 result = HandleCertificateError(result);
309 } else {
310 // SSLClientSocket for Mac will report socket is not connected,
311 // if it returns cert verification error. It didn't perform
312 // SSLHandshake yet.
313 // So, we should restart establishing connection with the
314 // certificate in allowed bad certificates in |ssl_config_|.
315 // See also net/http/http_network_transaction.cc
316 // HandleCertificateError() and RestartIgnoringLastError().
317 SSLClientSocket* ssl_socket =
318 reinterpret_cast<SSLClientSocket*>(socket_.get());
319 SSLInfo ssl_info;
320 ssl_socket->GetSSLInfo(&ssl_info);
321 if (ssl_info.cert == NULL ||
322 ssl_config_.IsAllowedBadCert(ssl_info.cert, NULL)) {
323 // If we already have the certificate in the set of allowed bad
324 // certificates, we did try it and failed again, so we should not
325 // retry again: the connection should fail at last.
326 next_state_ = STATE_CLOSE;
327 return result;
328 }
329 // Add the bad certificate to the set of allowed certificates in the
330 // SSL config object.
331 SSLConfig::CertAndStatus bad_cert;
332 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) {
333 next_state_ = STATE_CLOSE;
334 return result;
335 }
336 bad_cert.cert_status = ssl_info.cert_status;
337 ssl_config_.allowed_bad_certs.push_back(bad_cert);
338 // Restart connection ignoring the bad certificate.
339 socket_->Disconnect();
340 socket_.reset();
341 next_state_ = STATE_TCP_CONNECT;
342 return OK;
343 }
344 }
345 return result;
346 }
347
305 int SocketStream::DidEstablishConnection() { 348 int SocketStream::DidEstablishConnection() {
306 if (!socket_.get() || !socket_->IsConnected()) { 349 if (!socket_.get() || !socket_->IsConnected()) {
307 next_state_ = STATE_CLOSE; 350 next_state_ = STATE_CLOSE;
308 return ERR_CONNECTION_FAILED; 351 return ERR_CONNECTION_FAILED;
309 } 352 }
310 next_state_ = STATE_READ_WRITE; 353 next_state_ = STATE_READ_WRITE;
311 metrics_->OnConnected(); 354 metrics_->OnConnected();
312 355
313 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); 356 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL);
314 if (delegate_) 357 if (delegate_)
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 case STATE_READ_TUNNEL_HEADERS_COMPLETE: 474 case STATE_READ_TUNNEL_HEADERS_COMPLETE:
432 result = DoReadTunnelHeadersComplete(result); 475 result = DoReadTunnelHeadersComplete(result);
433 break; 476 break;
434 case STATE_SOCKS_CONNECT: 477 case STATE_SOCKS_CONNECT:
435 DCHECK_EQ(OK, result); 478 DCHECK_EQ(OK, result);
436 result = DoSOCKSConnect(); 479 result = DoSOCKSConnect();
437 break; 480 break;
438 case STATE_SOCKS_CONNECT_COMPLETE: 481 case STATE_SOCKS_CONNECT_COMPLETE:
439 result = DoSOCKSConnectComplete(result); 482 result = DoSOCKSConnectComplete(result);
440 break; 483 break;
484 case STATE_SECURE_PROXY_CONNECT:
485 DCHECK_EQ(OK, result);
486 result = DoSecureProxyConnect();
487 break;
488 case STATE_SECURE_PROXY_CONNECT_COMPLETE:
489 result = DoSecureProxyConnectComplete(result);
490 break;
441 case STATE_SSL_CONNECT: 491 case STATE_SSL_CONNECT:
442 DCHECK_EQ(OK, result); 492 DCHECK_EQ(OK, result);
443 result = DoSSLConnect(); 493 result = DoSSLConnect();
444 break; 494 break;
445 case STATE_SSL_CONNECT_COMPLETE: 495 case STATE_SSL_CONNECT_COMPLETE:
446 result = DoSSLConnectComplete(result); 496 result = DoSSLConnectComplete(result);
447 break; 497 break;
448 case STATE_READ_WRITE: 498 case STATE_READ_WRITE:
449 result = DoReadWrite(result); 499 result = DoReadWrite(result);
450 break; 500 break;
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 return socket_->Connect(&io_callback_); 657 return socket_->Connect(&io_callback_);
608 } 658 }
609 659
610 int SocketStream::DoTcpConnectComplete(int result) { 660 int SocketStream::DoTcpConnectComplete(int result) {
611 // TODO(ukai): if error occured, reconsider proxy after error. 661 // TODO(ukai): if error occured, reconsider proxy after error.
612 if (result != OK) { 662 if (result != OK) {
613 next_state_ = STATE_CLOSE; 663 next_state_ = STATE_CLOSE;
614 return result; 664 return result;
615 } 665 }
616 666
617 if (proxy_mode_ == kTunnelProxy) 667 if (proxy_mode_ == kTunnelProxy) {
618 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 668 if (proxy_info_.proxy_server().is_https())
Takashi Toyoshima 2011/07/21 11:37:44 proxy_info_.is_https() is better?
619 else if (proxy_mode_ == kSOCKSProxy) 669 next_state_ = STATE_SECURE_PROXY_CONNECT;
670 else
671 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
672 } else if (proxy_mode_ == kSOCKSProxy) {
620 next_state_ = STATE_SOCKS_CONNECT; 673 next_state_ = STATE_SOCKS_CONNECT;
621 else if (is_secure()) { 674 } else if (is_secure()) {
622 next_state_ = STATE_SSL_CONNECT; 675 next_state_ = STATE_SSL_CONNECT;
623 } else { 676 } else {
624 result = DidEstablishConnection(); 677 result = DidEstablishConnection();
625 } 678 }
626 return result; 679 return result;
627 } 680 }
628 681
629 int SocketStream::DoWriteTunnelHeaders() { 682 int SocketStream::DoWriteTunnelHeaders() {
630 DCHECK_EQ(kTunnelProxy, proxy_mode_); 683 DCHECK_EQ(kTunnelProxy, proxy_mode_);
631 684
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 if (is_secure()) 894 if (is_secure())
842 next_state_ = STATE_SSL_CONNECT; 895 next_state_ = STATE_SSL_CONNECT;
843 else 896 else
844 result = DidEstablishConnection(); 897 result = DidEstablishConnection();
845 } else { 898 } else {
846 next_state_ = STATE_CLOSE; 899 next_state_ = STATE_CLOSE;
847 } 900 }
848 return result; 901 return result;
849 } 902 }
850 903
904 int SocketStream::DoSecureProxyConnect() {
905 DCHECK(factory_);
906 // TODO(agl): look into plumbing SSLHostInfo here.
907 socket_.reset(factory_->CreateSSLClientSocket(
908 socket_.release(),
909 proxy_info_.proxy_server().host_port_pair(),
910 ssl_config_,
911 NULL /* ssl_host_info */,
912 cert_verifier_));
913 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE;
914 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION);
915 return socket_->Connect(&io_callback_);
916 }
917
918 int SocketStream::DoSecureProxyConnectComplete(int result) {
919 DCHECK_EQ(STATE_NONE, next_state_);
920 result = DidEstablishSSL(result);
921 if (next_state_ != STATE_NONE)
922 return result;
923
924 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
925 return result;
926 }
927
851 int SocketStream::DoSSLConnect() { 928 int SocketStream::DoSSLConnect() {
852 DCHECK(factory_); 929 DCHECK(factory_);
853 // TODO(agl): look into plumbing SSLHostInfo here. 930 // TODO(agl): look into plumbing SSLHostInfo here.
854 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), 931 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(),
855 HostPortPair::FromURL(url_), 932 HostPortPair::FromURL(url_),
856 ssl_config_, 933 ssl_config_,
857 NULL /* ssl_host_info */, 934 NULL /* ssl_host_info */,
858 cert_verifier_)); 935 cert_verifier_));
859 next_state_ = STATE_SSL_CONNECT_COMPLETE; 936 next_state_ = STATE_SSL_CONNECT_COMPLETE;
860 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); 937 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION);
861 return socket_->Connect(&io_callback_); 938 return socket_->Connect(&io_callback_);
862 } 939 }
863 940
864 int SocketStream::DoSSLConnectComplete(int result) { 941 int SocketStream::DoSSLConnectComplete(int result) {
865 if (IsCertificateError(result)) { 942 DCHECK_EQ(STATE_NONE, next_state_);
866 if (socket_->IsConnectedAndIdle()) { 943 result = DidEstablishSSL(result);
867 result = HandleCertificateError(result); 944 if (next_state_ != STATE_NONE)
868 } else { 945 return result;
869 // SSLClientSocket for Mac will report socket is not connected,
870 // if it returns cert verification error. It didn't perform
871 // SSLHandshake yet.
872 // So, we should restart establishing connection with the
873 // certificate in allowed bad certificates in |ssl_config_|.
874 // See also net/http/http_network_transaction.cc
875 // HandleCertificateError() and RestartIgnoringLastError().
876 SSLClientSocket* ssl_socket =
877 reinterpret_cast<SSLClientSocket*>(socket_.get());
878 SSLInfo ssl_info;
879 ssl_socket->GetSSLInfo(&ssl_info);
880 if (ssl_info.cert == NULL ||
881 ssl_config_.IsAllowedBadCert(ssl_info.cert, NULL)) {
882 // If we already have the certificate in the set of allowed bad
883 // certificates, we did try it and failed again, so we should not
884 // retry again: the connection should fail at last.
885 next_state_ = STATE_CLOSE;
886 return result;
887 }
888 // Add the bad certificate to the set of allowed certificates in the
889 // SSL config object.
890 SSLConfig::CertAndStatus bad_cert;
891 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) {
892 next_state_ = STATE_CLOSE;
893 return result;
894 }
895 bad_cert.cert_status = ssl_info.cert_status;
896 ssl_config_.allowed_bad_certs.push_back(bad_cert);
897 // Restart connection ignoring the bad certificate.
898 socket_->Disconnect();
899 socket_.reset();
900 next_state_ = STATE_TCP_CONNECT;
901 return OK;
902 }
903 }
904 946
905 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. 947 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible.
906 // If we use HTTPS and this is the first connection to the SPDY server, 948 // If we use HTTPS and this is the first connection to the SPDY server,
907 // we should take care of TLS NPN extension here. 949 // we should take care of TLS NPN extension here.
908 950
909 if (result == OK) 951 if (result == OK)
910 result = DidEstablishConnection(); 952 result = DidEstablishConnection();
911 else 953 else
912 next_state_ = STATE_CLOSE; 954 next_state_ = STATE_CLOSE;
913 return result; 955 return result;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 1124
1083 SSLConfigService* SocketStream::ssl_config_service() const { 1125 SSLConfigService* SocketStream::ssl_config_service() const {
1084 return context_->ssl_config_service(); 1126 return context_->ssl_config_service();
1085 } 1127 }
1086 1128
1087 ProxyService* SocketStream::proxy_service() const { 1129 ProxyService* SocketStream::proxy_service() const {
1088 return context_->proxy_service(); 1130 return context_->proxy_service();
1089 } 1131 }
1090 1132
1091 } // namespace net 1133 } // namespace net
OLDNEW
« no previous file with comments | « net/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_metrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698