| 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 #include "remoting/protocol/jingle_stream_connector.h" | 5 #include "remoting/protocol/jingle_stream_connector.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "jingle/glue/channel_socket_adapter.h" | 8 #include "jingle/glue/channel_socket_adapter.h" |
| 9 #include "jingle/glue/pseudotcp_adapter.h" | 9 #include "jingle/glue/pseudotcp_adapter.h" |
| 10 #include "net/base/cert_status_flags.h" | 10 #include "net/base/cert_status_flags.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 | 25 |
| 26 // Value is choosen to balance the extra latency against the reduced | 26 // Value is choosen to balance the extra latency against the reduced |
| 27 // load due to ACK traffic. | 27 // load due to ACK traffic. |
| 28 const int kTcpAckDelayMilliseconds = 10; | 28 const int kTcpAckDelayMilliseconds = 10; |
| 29 | 29 |
| 30 // Values for the TCP send and receive buffer size. This should be tuned to | 30 // Values for the TCP send and receive buffer size. This should be tuned to |
| 31 // accomodate high latency network but not backlog the decoding pipeline. | 31 // accomodate high latency network but not backlog the decoding pipeline. |
| 32 const int kTcpReceiveBufferSize = 256 * 1024; | 32 const int kTcpReceiveBufferSize = 256 * 1024; |
| 33 const int kTcpSendBufferSize = kTcpReceiveBufferSize + 30 * 1024; | 33 const int kTcpSendBufferSize = kTcpReceiveBufferSize + 30 * 1024; |
| 34 | 34 |
| 35 // Helper method to create a SSL client socket. | |
| 36 net::SSLClientSocket* CreateSSLClientSocket( | |
| 37 net::StreamSocket* socket, const std::string& der_cert, | |
| 38 net::CertVerifier* cert_verifier) { | |
| 39 net::SSLConfig ssl_config; | |
| 40 | |
| 41 // Certificate provided by the host doesn't need authority. | |
| 42 net::SSLConfig::CertAndStatus cert_and_status; | |
| 43 cert_and_status.cert_status = net::CERT_STATUS_AUTHORITY_INVALID; | |
| 44 cert_and_status.der_cert = der_cert; | |
| 45 ssl_config.allowed_bad_certs.push_back(cert_and_status); | |
| 46 | |
| 47 // Revocation checking is not needed because we use self-signed | |
| 48 // certs. Disable it so that SSL layer doesn't try to initialize | |
| 49 // OCSP (OCSP works only on IO thread). | |
| 50 ssl_config.rev_checking_enabled = false; | |
| 51 | |
| 52 // SSLClientSocket takes ownership of the adapter. | |
| 53 net::HostPortPair host_and_port( | |
| 54 ContentDescription::kChromotingContentName, 0); | |
| 55 net::SSLClientSocketContext context; | |
| 56 context.cert_verifier = cert_verifier; | |
| 57 net::SSLClientSocket* ssl_socket = | |
| 58 net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( | |
| 59 socket, host_and_port, ssl_config, NULL, context); | |
| 60 return ssl_socket; | |
| 61 } | |
| 62 | |
| 63 } // namespace | 35 } // namespace |
| 64 | 36 |
| 65 JingleStreamConnector::JingleStreamConnector( | 37 JingleStreamConnector::JingleStreamConnector( |
| 66 JingleSession* session, | 38 JingleSession* session, |
| 67 const std::string& name, | 39 const std::string& name, |
| 68 const Session::StreamChannelCallback& callback) | 40 const Session::StreamChannelCallback& callback) |
| 69 : session_(session), | 41 : session_(session), |
| 70 name_(name), | 42 name_(name), |
| 71 callback_(callback), | 43 callback_(callback), |
| 72 initiator_(false), | |
| 73 local_private_key_(NULL), | |
| 74 raw_channel_(NULL), | 44 raw_channel_(NULL), |
| 75 ALLOW_THIS_IN_INITIALIZER_LIST(tcp_connect_callback_( | 45 ALLOW_THIS_IN_INITIALIZER_LIST(tcp_connect_callback_( |
| 76 this, &JingleStreamConnector::OnTCPConnect)), | 46 this, &JingleStreamConnector::OnTCPConnect)) { |
| 77 ALLOW_THIS_IN_INITIALIZER_LIST(ssl_connect_callback_( | |
| 78 this, &JingleStreamConnector::OnSSLConnect)) { | |
| 79 } | 47 } |
| 80 | 48 |
| 81 JingleStreamConnector::~JingleStreamConnector() { | 49 JingleStreamConnector::~JingleStreamConnector() { |
| 82 } | 50 } |
| 83 | 51 |
| 84 void JingleStreamConnector::Connect(bool initiator, | 52 void JingleStreamConnector::Connect(ChannelAuthenticator* authenticator, |
| 85 const std::string& local_cert, | |
| 86 const std::string& remote_cert, | |
| 87 crypto::RSAPrivateKey* local_private_key, | |
| 88 cricket::TransportChannel* raw_channel) { | 53 cricket::TransportChannel* raw_channel) { |
| 89 DCHECK(CalledOnValidThread()); | 54 DCHECK(CalledOnValidThread()); |
| 90 DCHECK(!raw_channel_); | 55 DCHECK(!raw_channel_); |
| 91 | 56 |
| 92 initiator_ = initiator; | 57 authenticator_.reset(authenticator); |
| 93 local_cert_ = local_cert; | |
| 94 remote_cert_ = remote_cert; | |
| 95 local_private_key_ = local_private_key; | |
| 96 raw_channel_ = raw_channel; | 58 raw_channel_ = raw_channel; |
| 97 | 59 |
| 98 net::Socket* socket = | 60 net::Socket* socket = |
| 99 new jingle_glue::TransportChannelSocketAdapter(raw_channel_); | 61 new jingle_glue::TransportChannelSocketAdapter(raw_channel_); |
| 100 | 62 |
| 101 if (!EstablishTCPConnection(socket)) | 63 if (!EstablishTCPConnection(socket)) |
| 102 NotifyError(); | 64 NotifyError(); |
| 103 } | 65 } |
| 104 | 66 |
| 105 bool JingleStreamConnector::EstablishTCPConnection(net::Socket* socket) { | 67 bool JingleStreamConnector::EstablishTCPConnection(net::Socket* socket) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 125 if (result == net::ERR_IO_PENDING) { | 87 if (result == net::ERR_IO_PENDING) { |
| 126 return true; | 88 return true; |
| 127 } else if (result == net::OK) { | 89 } else if (result == net::OK) { |
| 128 tcp_connect_callback_.Run(result); | 90 tcp_connect_callback_.Run(result); |
| 129 return true; | 91 return true; |
| 130 } | 92 } |
| 131 | 93 |
| 132 return false; | 94 return false; |
| 133 } | 95 } |
| 134 | 96 |
| 135 bool JingleStreamConnector::EstablishSSLConnection() { | |
| 136 DCHECK(tcp_socket_->IsConnected()); | |
| 137 | |
| 138 int result; | |
| 139 if (initiator_) { | |
| 140 cert_verifier_.reset(new net::CertVerifier()); | |
| 141 | |
| 142 // Create client SSL socket. | |
| 143 net::SSLClientSocket* socket = CreateSSLClientSocket( | |
| 144 tcp_socket_.release(), remote_cert_, cert_verifier_.get()); | |
| 145 socket_.reset(socket); | |
| 146 | |
| 147 result = socket->Connect(&ssl_connect_callback_); | |
| 148 } else { | |
| 149 scoped_refptr<net::X509Certificate> cert = | |
| 150 net::X509Certificate::CreateFromBytes( | |
| 151 local_cert_.data(), local_cert_.length()); | |
| 152 if (!cert) { | |
| 153 LOG(ERROR) << "Failed to parse X509Certificate"; | |
| 154 return false; | |
| 155 } | |
| 156 | |
| 157 // Create server SSL socket. | |
| 158 net::SSLConfig ssl_config; | |
| 159 net::SSLServerSocket* socket = net::CreateSSLServerSocket( | |
| 160 tcp_socket_.release(), cert, local_private_key_, ssl_config); | |
| 161 socket_.reset(socket); | |
| 162 | |
| 163 result = socket->Handshake(&ssl_connect_callback_); | |
| 164 } | |
| 165 | |
| 166 if (result == net::ERR_IO_PENDING) { | |
| 167 return true; | |
| 168 } else if (result != net::OK) { | |
| 169 LOG(ERROR) << "Failed to establish SSL connection"; | |
| 170 return false; | |
| 171 } | |
| 172 | |
| 173 // Reach here if net::OK is received. | |
| 174 ssl_connect_callback_.Run(net::OK); | |
| 175 return true; | |
| 176 } | |
| 177 | |
| 178 void JingleStreamConnector::OnTCPConnect(int result) { | 97 void JingleStreamConnector::OnTCPConnect(int result) { |
| 179 DCHECK(CalledOnValidThread()); | 98 DCHECK(CalledOnValidThread()); |
| 180 | 99 |
| 181 if (result != net::OK) { | 100 if (result != net::OK) { |
| 182 LOG(ERROR) << "PseudoTCP connection failed: " << result; | 101 LOG(ERROR) << "PseudoTCP connection failed: " << result; |
| 183 NotifyError(); | 102 NotifyError(); |
| 184 return; | 103 return; |
| 185 } | 104 } |
| 186 | 105 |
| 187 if (!EstablishSSLConnection()) | 106 authenticator_->SecureAndAuthenticate(tcp_socket_.release(), base::Bind( |
| 188 NotifyError(); | |
| 189 } | |
| 190 | |
| 191 void JingleStreamConnector::OnSSLConnect(int result) { | |
| 192 DCHECK(CalledOnValidThread()); | |
| 193 | |
| 194 if (result != net::OK) { | |
| 195 LOG(ERROR) << "Error during SSL connection: " << result; | |
| 196 NotifyError(); | |
| 197 return; | |
| 198 } | |
| 199 | |
| 200 DCHECK(socket_->IsConnected()); | |
| 201 AuthenticateChannel(); | |
| 202 } | |
| 203 | |
| 204 void JingleStreamConnector::AuthenticateChannel() { | |
| 205 if (initiator_) { | |
| 206 authenticator_.reset( | |
| 207 new ClientChannelAuthenticator(session_->shared_secret())); | |
| 208 } else { | |
| 209 authenticator_.reset( | |
| 210 new HostChannelAuthenticator(session_->shared_secret())); | |
| 211 } | |
| 212 authenticator_->Authenticate(socket_.get(), base::Bind( | |
| 213 &JingleStreamConnector::OnAuthenticationDone, base::Unretained(this))); | 107 &JingleStreamConnector::OnAuthenticationDone, base::Unretained(this))); |
| 214 } | 108 } |
| 215 | 109 |
| 216 void JingleStreamConnector::OnAuthenticationDone( | 110 void JingleStreamConnector::OnAuthenticationDone( |
| 217 ChannelAuthenticator::Result result) { | 111 net::Error error, net::StreamSocket* socket) { |
| 218 switch (result) { | 112 if (error != net::OK) { |
| 219 case ChannelAuthenticator::SUCCESS: | 113 NotifyError(); |
| 220 NotifyDone(socket_.release()); | 114 } else { |
| 221 break; | 115 NotifyDone(socket); |
| 222 | |
| 223 case ChannelAuthenticator::FAILURE: | |
| 224 NotifyError(); | |
| 225 break; | |
| 226 } | 116 } |
| 227 } | 117 } |
| 228 | 118 |
| 229 void JingleStreamConnector::NotifyDone(net::StreamSocket* socket) { | 119 void JingleStreamConnector::NotifyDone(net::StreamSocket* socket) { |
| 230 session_->OnChannelConnectorFinished(name_, this); | 120 session_->OnChannelConnectorFinished(name_, this); |
| 231 callback_.Run(socket); | 121 callback_.Run(socket); |
| 232 delete this; | 122 delete this; |
| 233 } | 123 } |
| 234 | 124 |
| 235 void JingleStreamConnector::NotifyError() { | 125 void JingleStreamConnector::NotifyError() { |
| 236 socket_.reset(); | |
| 237 NotifyDone(NULL); | 126 NotifyDone(NULL); |
| 238 } | 127 } |
| 239 | 128 |
| 240 } // namespace protocol | 129 } // namespace protocol |
| 241 } // namespace remoting | 130 } // namespace remoting |
| OLD | NEW |