summaryrefslogtreecommitdiffstats
path: root/remoting/jingle_glue/ssl_socket_adapter.h
blob: 388bd1c06071a1a46d9aac095bf140cdda9712a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_
#define REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_

#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
#include "third_party/libjingle/source/talk/base/asyncsocket.h"
#include "third_party/libjingle/source/talk/base/ssladapter.h"

namespace net {
class CertVerifier;
}  // namespace net

namespace remoting {

class SSLSocketAdapter;

// TODO(sergeyu): Write unittests for this code!

// This class provides a wrapper to libjingle's talk_base::AsyncSocket that
// implements Chromium's net::StreamSocket interface.  It's used by
// SSLSocketAdapter to enable Chromium's SSL implementation to work over
// libjingle's socket class.
class TransportSocket : public net::StreamSocket, public sigslot::has_slots<> {
 public:
  TransportSocket(talk_base::AsyncSocket* socket,
                  SSLSocketAdapter *ssl_adapter);
  virtual ~TransportSocket();

  void set_addr(const talk_base::SocketAddress& addr) {
    addr_ = addr;
  }

  // net::StreamSocket implementation

  virtual int Connect(net::CompletionCallback* callback);
  virtual void Disconnect();
  virtual bool IsConnected() const;
  virtual bool IsConnectedAndIdle() const;
  virtual int GetPeerAddress(net::AddressList* address) const;
  virtual int GetLocalAddress(net::IPEndPoint* address) const;
  virtual const net::BoundNetLog& NetLog() const;
  virtual void SetSubresourceSpeculation();
  virtual void SetOmniboxSpeculation();
  virtual bool WasEverUsed() const;
  virtual bool UsingTCPFastOpen() const;
  virtual int64 NumBytesRead() const;
  virtual base::TimeDelta GetConnectTimeMicros() const;

  // net::Socket implementation

  virtual int Read(net::IOBuffer* buf, int buf_len,
                   net::CompletionCallback* callback);
  virtual int Write(net::IOBuffer* buf, int buf_len,
                    net::CompletionCallback* callback);
  virtual bool SetReceiveBufferSize(int32 size);
  virtual bool SetSendBufferSize(int32 size);

 private:
  friend class SSLSocketAdapter;

  void OnReadEvent(talk_base::AsyncSocket* socket);
  void OnWriteEvent(talk_base::AsyncSocket* socket);

  net::CompletionCallback* read_callback_;
  net::CompletionCallback* write_callback_;

  scoped_refptr<net::IOBuffer> read_buffer_;
  int read_buffer_len_;
  scoped_refptr<net::IOBuffer> write_buffer_;
  int write_buffer_len_;

  net::BoundNetLog net_log_;

  talk_base::AsyncSocket *socket_;
  talk_base::SocketAddress addr_;

  bool was_used_to_convey_data_;

  DISALLOW_COPY_AND_ASSIGN(TransportSocket);
};

// This provides a talk_base::AsyncSocketAdapter interface around Chromium's
// net::SSLClientSocket class.  This allows remoting to use Chromium's SSL
// implementation instead of OpenSSL.
class SSLSocketAdapter : public talk_base::SSLAdapter {
 public:
  explicit SSLSocketAdapter(talk_base::AsyncSocket* socket);
  virtual ~SSLSocketAdapter();

  // StartSSL returns 0 if successful, or non-zero on failure.
  // If StartSSL is called while the socket is closed or connecting, the SSL
  // negotiation will begin as soon as the socket connects.
  //
  // restartable is not implemented, and must be set to false.
  virtual int StartSSL(const char* hostname, bool restartable);

  // Create the default SSL adapter for this platform.
  static SSLSocketAdapter* Create(AsyncSocket* socket);

  virtual int Send(const void* pv, size_t cb);
  virtual int Recv(void* pv, size_t cb);

 private:
  friend class TransportSocket;

  enum SSLState {
    SSLSTATE_NONE,
    SSLSTATE_WAIT,
    SSLSTATE_CONNECTED,
  };

  enum IOState {
    IOSTATE_NONE,
    IOSTATE_PENDING,
    IOSTATE_COMPLETE,
  };

  void OnConnected(int result);
  void OnRead(int result);
  void OnWrite(int result);

  virtual void OnConnectEvent(talk_base::AsyncSocket* socket);

  int BeginSSL();

  bool ignore_bad_cert_;
  std::string hostname_;
  TransportSocket* transport_socket_;
  scoped_ptr<net::SSLClientSocket> ssl_socket_;
  scoped_ptr<net::CertVerifier> cert_verifier_;
  net::CompletionCallbackImpl<SSLSocketAdapter> connected_callback_;
  net::CompletionCallbackImpl<SSLSocketAdapter> read_callback_;
  net::CompletionCallbackImpl<SSLSocketAdapter> write_callback_;
  SSLState ssl_state_;
  IOState read_state_;
  IOState write_state_;
  scoped_refptr<net::IOBuffer> transport_buf_;
  int data_transferred_;

  DISALLOW_COPY_AND_ASSIGN(SSLSocketAdapter);
};

}  // namespace remoting

#endif  // REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_