| OLD | NEW |
| 1 // Copyright (c) 2010 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 "jingle/notifier/base/fake_ssl_client_socket.h" | 5 #include "jingle/notifier/base/fake_ssl_client_socket.h" |
| 6 | 6 |
| 7 #include <cstdlib> | 7 #include <cstdlib> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
| 13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 14 #include "net/socket/client_socket_handle.h" |
| 14 | 15 |
| 15 namespace notifier { | 16 namespace notifier { |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 // The constants below were taken from libjingle's socketadapters.cc. | 20 // The constants below were taken from libjingle's socketadapters.cc. |
| 20 // Basically, we do a "fake" SSL handshake to fool proxies into | 21 // Basically, we do a "fake" SSL handshake to fool proxies into |
| 21 // thinking this is a real SSL connection. | 22 // thinking this is a real SSL connection. |
| 22 | 23 |
| 23 // This is a SSL v2 CLIENT_HELLO message. | 24 // This is a SSL v2 CLIENT_HELLO message. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 return base::StringPiece(reinterpret_cast<const char*>(kSslClientHello), | 71 return base::StringPiece(reinterpret_cast<const char*>(kSslClientHello), |
| 71 arraysize(kSslClientHello)); | 72 arraysize(kSslClientHello)); |
| 72 } | 73 } |
| 73 | 74 |
| 74 base::StringPiece FakeSSLClientSocket::GetSslServerHello() { | 75 base::StringPiece FakeSSLClientSocket::GetSslServerHello() { |
| 75 return base::StringPiece(reinterpret_cast<const char*>(kSslServerHello), | 76 return base::StringPiece(reinterpret_cast<const char*>(kSslServerHello), |
| 76 arraysize(kSslServerHello)); | 77 arraysize(kSslServerHello)); |
| 77 } | 78 } |
| 78 | 79 |
| 79 FakeSSLClientSocket::FakeSSLClientSocket( | 80 FakeSSLClientSocket::FakeSSLClientSocket( |
| 80 net::ClientSocket* transport_socket) | 81 net::ClientSocketHandle* transport_socket) |
| 81 : connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 82 : connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 82 &FakeSSLClientSocket::OnConnectDone), | 83 &FakeSSLClientSocket::OnConnectDone), |
| 83 send_client_hello_callback_( | 84 send_client_hello_callback_( |
| 84 ALLOW_THIS_IN_INITIALIZER_LIST(this), | 85 ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 85 &FakeSSLClientSocket::OnSendClientHelloDone), | 86 &FakeSSLClientSocket::OnSendClientHelloDone), |
| 86 verify_server_hello_callback_( | 87 verify_server_hello_callback_( |
| 87 ALLOW_THIS_IN_INITIALIZER_LIST(this), | 88 ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 88 &FakeSSLClientSocket::OnVerifyServerHelloDone), | 89 &FakeSSLClientSocket::OnVerifyServerHelloDone), |
| 89 transport_socket_(transport_socket), | 90 transport_(transport_socket), |
| 90 next_handshake_state_(STATE_NONE), | 91 next_handshake_state_(STATE_NONE), |
| 91 handshake_completed_(false), | 92 handshake_completed_(false), |
| 92 user_connect_callback_(NULL), | 93 user_connect_callback_(NULL), |
| 93 write_buf_(NewDrainableIOBufferWithSize(arraysize(kSslClientHello))), | 94 write_buf_(NewDrainableIOBufferWithSize(arraysize(kSslClientHello))), |
| 94 read_buf_(NewDrainableIOBufferWithSize(arraysize(kSslServerHello))) { | 95 read_buf_(NewDrainableIOBufferWithSize(arraysize(kSslServerHello))) { |
| 95 CHECK(transport_socket_.get()); | 96 CHECK(transport_.get()); |
| 96 std::memcpy(write_buf_->data(), kSslClientHello, arraysize(kSslClientHello)); | 97 std::memcpy(write_buf_->data(), kSslClientHello, arraysize(kSslClientHello)); |
| 97 } | 98 } |
| 98 | 99 |
| 99 FakeSSLClientSocket::~FakeSSLClientSocket() {} | 100 FakeSSLClientSocket::~FakeSSLClientSocket() {} |
| 100 | 101 |
| 101 int FakeSSLClientSocket::Read(net::IOBuffer* buf, int buf_len, | 102 int FakeSSLClientSocket::Read(net::IOBuffer* buf, int buf_len, |
| 102 net::CompletionCallback* callback) { | 103 net::CompletionCallback* callback) { |
| 103 DCHECK_EQ(next_handshake_state_, STATE_NONE); | 104 DCHECK_EQ(next_handshake_state_, STATE_NONE); |
| 104 DCHECK(handshake_completed_); | 105 DCHECK(handshake_completed_); |
| 105 return transport_socket_->Read(buf, buf_len, callback); | 106 return transport_->socket()->Read(buf, buf_len, callback); |
| 106 } | 107 } |
| 107 | 108 |
| 108 int FakeSSLClientSocket::Write(net::IOBuffer* buf, int buf_len, | 109 int FakeSSLClientSocket::Write(net::IOBuffer* buf, int buf_len, |
| 109 net::CompletionCallback* callback) { | 110 net::CompletionCallback* callback) { |
| 110 DCHECK_EQ(next_handshake_state_, STATE_NONE); | 111 DCHECK_EQ(next_handshake_state_, STATE_NONE); |
| 111 DCHECK(handshake_completed_); | 112 DCHECK(handshake_completed_); |
| 112 return transport_socket_->Write(buf, buf_len, callback); | 113 return transport_->socket()->Write(buf, buf_len, callback); |
| 113 } | 114 } |
| 114 | 115 |
| 115 bool FakeSSLClientSocket::SetReceiveBufferSize(int32 size) { | 116 bool FakeSSLClientSocket::SetReceiveBufferSize(int32 size) { |
| 116 return transport_socket_->SetReceiveBufferSize(size); | 117 return transport_->socket()->SetReceiveBufferSize(size); |
| 117 } | 118 } |
| 118 | 119 |
| 119 bool FakeSSLClientSocket::SetSendBufferSize(int32 size) { | 120 bool FakeSSLClientSocket::SetSendBufferSize(int32 size) { |
| 120 return transport_socket_->SetSendBufferSize(size); | 121 return transport_->socket()->SetSendBufferSize(size); |
| 121 } | 122 } |
| 122 | 123 |
| 123 int FakeSSLClientSocket::Connect(net::CompletionCallback* callback) { | 124 int FakeSSLClientSocket::Connect(net::CompletionCallback* callback) { |
| 124 // We don't support synchronous operation, even if | 125 // We don't support synchronous operation, even if |
| 125 // |transport_socket_| does. | 126 // |transport_socket_| does. |
| 126 DCHECK(callback); | 127 DCHECK(callback); |
| 127 DCHECK_EQ(next_handshake_state_, STATE_NONE); | 128 DCHECK_EQ(next_handshake_state_, STATE_NONE); |
| 128 DCHECK(!handshake_completed_); | 129 DCHECK(!handshake_completed_); |
| 129 DCHECK(!user_connect_callback_); | 130 DCHECK(!user_connect_callback_); |
| 130 DCHECK_EQ(write_buf_->BytesConsumed(), 0); | 131 DCHECK_EQ(write_buf_->BytesConsumed(), 0); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 } | 174 } |
| 174 | 175 |
| 175 void FakeSSLClientSocket::DoHandshakeLoopWithUserConnectCallback() { | 176 void FakeSSLClientSocket::DoHandshakeLoopWithUserConnectCallback() { |
| 176 int status = DoHandshakeLoop(); | 177 int status = DoHandshakeLoop(); |
| 177 if (status != net::ERR_IO_PENDING) { | 178 if (status != net::ERR_IO_PENDING) { |
| 178 RunUserConnectCallback(status); | 179 RunUserConnectCallback(status); |
| 179 } | 180 } |
| 180 } | 181 } |
| 181 | 182 |
| 182 int FakeSSLClientSocket::DoConnect() { | 183 int FakeSSLClientSocket::DoConnect() { |
| 183 int status = transport_socket_->Connect(&connect_callback_); | 184 // The passed in socket may already be connected. |
| 184 if (status != net::OK) { | 185 int status = net::OK; |
| 186 if (!transport_->socket()->IsConnected()) |
| 187 status = transport_->socket()->Connect(&connect_callback_); |
| 188 |
| 189 if (status != net::OK) |
| 185 return status; | 190 return status; |
| 186 } | 191 |
| 187 ProcessConnectDone(); | 192 ProcessConnectDone(); |
| 188 return net::OK; | 193 return net::OK; |
| 189 } | 194 } |
| 190 | 195 |
| 191 void FakeSSLClientSocket::OnConnectDone(int status) { | 196 void FakeSSLClientSocket::OnConnectDone(int status) { |
| 192 DCHECK_NE(status, net::ERR_IO_PENDING); | 197 DCHECK_NE(status, net::ERR_IO_PENDING); |
| 193 DCHECK_LE(status, net::OK); | 198 DCHECK_LE(status, net::OK); |
| 194 DCHECK(user_connect_callback_); | 199 DCHECK(user_connect_callback_); |
| 195 if (status != net::OK) { | 200 if (status != net::OK) { |
| 196 RunUserConnectCallback(status); | 201 RunUserConnectCallback(status); |
| 197 return; | 202 return; |
| 198 } | 203 } |
| 199 ProcessConnectDone(); | 204 ProcessConnectDone(); |
| 200 DoHandshakeLoopWithUserConnectCallback(); | 205 DoHandshakeLoopWithUserConnectCallback(); |
| 201 } | 206 } |
| 202 | 207 |
| 203 void FakeSSLClientSocket::ProcessConnectDone() { | 208 void FakeSSLClientSocket::ProcessConnectDone() { |
| 204 DCHECK_EQ(write_buf_->BytesConsumed(), 0); | 209 DCHECK_EQ(write_buf_->BytesConsumed(), 0); |
| 205 DCHECK_EQ(read_buf_->BytesConsumed(), 0); | 210 DCHECK_EQ(read_buf_->BytesConsumed(), 0); |
| 206 next_handshake_state_ = STATE_SEND_CLIENT_HELLO; | 211 next_handshake_state_ = STATE_SEND_CLIENT_HELLO; |
| 207 } | 212 } |
| 208 | 213 |
| 209 int FakeSSLClientSocket::DoSendClientHello() { | 214 int FakeSSLClientSocket::DoSendClientHello() { |
| 210 int status = transport_socket_->Write( | 215 int status = transport_->socket()->Write( |
| 211 write_buf_, write_buf_->BytesRemaining(), | 216 write_buf_, write_buf_->BytesRemaining(), |
| 212 &send_client_hello_callback_); | 217 &send_client_hello_callback_); |
| 213 if (status < net::OK) { | 218 if (status < net::OK) { |
| 214 return status; | 219 return status; |
| 215 } | 220 } |
| 216 ProcessSendClientHelloDone(static_cast<size_t>(status)); | 221 ProcessSendClientHelloDone(static_cast<size_t>(status)); |
| 217 return net::OK; | 222 return net::OK; |
| 218 } | 223 } |
| 219 | 224 |
| 220 void FakeSSLClientSocket::OnSendClientHelloDone(int status) { | 225 void FakeSSLClientSocket::OnSendClientHelloDone(int status) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 233 DCHECK_EQ(read_buf_->BytesConsumed(), 0); | 238 DCHECK_EQ(read_buf_->BytesConsumed(), 0); |
| 234 if (written < static_cast<size_t>(write_buf_->BytesRemaining())) { | 239 if (written < static_cast<size_t>(write_buf_->BytesRemaining())) { |
| 235 next_handshake_state_ = STATE_SEND_CLIENT_HELLO; | 240 next_handshake_state_ = STATE_SEND_CLIENT_HELLO; |
| 236 write_buf_->DidConsume(written); | 241 write_buf_->DidConsume(written); |
| 237 } else { | 242 } else { |
| 238 next_handshake_state_ = STATE_VERIFY_SERVER_HELLO; | 243 next_handshake_state_ = STATE_VERIFY_SERVER_HELLO; |
| 239 } | 244 } |
| 240 } | 245 } |
| 241 | 246 |
| 242 int FakeSSLClientSocket::DoVerifyServerHello() { | 247 int FakeSSLClientSocket::DoVerifyServerHello() { |
| 243 int status = transport_socket_->Read( | 248 int status = transport_->socket()->Read( |
| 244 read_buf_, read_buf_->BytesRemaining(), | 249 read_buf_, read_buf_->BytesRemaining(), |
| 245 &verify_server_hello_callback_); | 250 &verify_server_hello_callback_); |
| 246 if (status < net::OK) { | 251 if (status < net::OK) { |
| 247 return status; | 252 return status; |
| 248 } | 253 } |
| 249 size_t read = static_cast<size_t>(status); | 254 size_t read = static_cast<size_t>(status); |
| 250 return ProcessVerifyServerHelloDone(read); | 255 return ProcessVerifyServerHelloDone(read); |
| 251 } | 256 } |
| 252 | 257 |
| 253 void FakeSSLClientSocket::OnVerifyServerHelloDone(int status) { | 258 void FakeSSLClientSocket::OnVerifyServerHelloDone(int status) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 next_handshake_state_ = STATE_VERIFY_SERVER_HELLO; | 290 next_handshake_state_ = STATE_VERIFY_SERVER_HELLO; |
| 286 read_buf_->DidConsume(read); | 291 read_buf_->DidConsume(read); |
| 287 } else { | 292 } else { |
| 288 next_handshake_state_ = STATE_NONE; | 293 next_handshake_state_ = STATE_NONE; |
| 289 handshake_completed_ = true; | 294 handshake_completed_ = true; |
| 290 } | 295 } |
| 291 return net::OK; | 296 return net::OK; |
| 292 } | 297 } |
| 293 | 298 |
| 294 void FakeSSLClientSocket::Disconnect() { | 299 void FakeSSLClientSocket::Disconnect() { |
| 295 transport_socket_->Disconnect(); | 300 transport_->Reset(); |
| 296 next_handshake_state_ = STATE_NONE; | 301 next_handshake_state_ = STATE_NONE; |
| 297 handshake_completed_ = false; | 302 handshake_completed_ = false; |
| 298 user_connect_callback_ = NULL; | 303 user_connect_callback_ = NULL; |
| 299 write_buf_->SetOffset(0); | 304 write_buf_->SetOffset(0); |
| 300 read_buf_->SetOffset(0); | 305 read_buf_->SetOffset(0); |
| 301 } | 306 } |
| 302 | 307 |
| 303 bool FakeSSLClientSocket::IsConnected() const { | 308 bool FakeSSLClientSocket::IsConnected() const { |
| 304 return handshake_completed_ && transport_socket_->IsConnected(); | 309 return handshake_completed_ && transport_->socket()->IsConnected(); |
| 305 } | 310 } |
| 306 | 311 |
| 307 bool FakeSSLClientSocket::IsConnectedAndIdle() const { | 312 bool FakeSSLClientSocket::IsConnectedAndIdle() const { |
| 308 return handshake_completed_ && transport_socket_->IsConnectedAndIdle(); | 313 return handshake_completed_ && transport_->socket()->IsConnectedAndIdle(); |
| 309 } | 314 } |
| 310 | 315 |
| 311 int FakeSSLClientSocket::GetPeerAddress(net::AddressList* address) const { | 316 int FakeSSLClientSocket::GetPeerAddress(net::AddressList* address) const { |
| 312 return transport_socket_->GetPeerAddress(address); | 317 return transport_->socket()->GetPeerAddress(address); |
| 313 } | 318 } |
| 314 | 319 |
| 315 const net::BoundNetLog& FakeSSLClientSocket::NetLog() const { | 320 const net::BoundNetLog& FakeSSLClientSocket::NetLog() const { |
| 316 return transport_socket_->NetLog(); | 321 return transport_->socket()->NetLog(); |
| 317 } | 322 } |
| 318 | 323 |
| 319 void FakeSSLClientSocket::SetSubresourceSpeculation() { | 324 void FakeSSLClientSocket::SetSubresourceSpeculation() { |
| 320 transport_socket_->SetSubresourceSpeculation(); | 325 transport_->socket()->SetSubresourceSpeculation(); |
| 321 } | 326 } |
| 322 | 327 |
| 323 void FakeSSLClientSocket::SetOmniboxSpeculation() { | 328 void FakeSSLClientSocket::SetOmniboxSpeculation() { |
| 324 transport_socket_->SetOmniboxSpeculation(); | 329 transport_->socket()->SetOmniboxSpeculation(); |
| 325 } | 330 } |
| 326 | 331 |
| 327 bool FakeSSLClientSocket::WasEverUsed() const { | 332 bool FakeSSLClientSocket::WasEverUsed() const { |
| 328 return transport_socket_->WasEverUsed(); | 333 return transport_->socket()->WasEverUsed(); |
| 329 } | 334 } |
| 330 | 335 |
| 331 bool FakeSSLClientSocket::UsingTCPFastOpen() const { | 336 bool FakeSSLClientSocket::UsingTCPFastOpen() const { |
| 332 return transport_socket_->UsingTCPFastOpen(); | 337 return transport_->socket()->UsingTCPFastOpen(); |
| 333 } | 338 } |
| 334 | 339 |
| 335 } // namespace notifier | 340 } // namespace notifier |
| OLD | NEW |