Home | History | Annotate | Download | only in cast_channel
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
      6 #define CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
      7 
      8 #include <queue>
      9 #include <string>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/callback.h"
     13 #include "base/gtest_prod_util.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "base/threading/thread_checker.h"
     17 #include "chrome/common/extensions/api/cast_channel.h"
     18 #include "extensions/browser/api/api_resource.h"
     19 #include "extensions/browser/api/api_resource_manager.h"
     20 #include "net/base/completion_callback.h"
     21 #include "net/base/io_buffer.h"
     22 #include "net/base/ip_endpoint.h"
     23 #include "net/base/net_log.h"
     24 
     25 namespace net {
     26 class AddressList;
     27 class CertVerifier;
     28 class SSLClientSocket;
     29 class StreamSocket;
     30 class TCPClientSocket;
     31 class TransportSecurityState;
     32 }
     33 
     34 namespace extensions {
     35 namespace api {
     36 namespace cast_channel {
     37 
     38 class CastMessage;
     39 
     40 // This class implements a channel between Chrome and a Cast device using a TCP
     41 // socket with SSL.  The channel may authenticate that the receiver is a genuine
     42 // Cast device.  All CastSocket objects must be used only on the IO thread.
     43 //
     44 // NOTE: Not called "CastChannel" to reduce confusion with the generated API
     45 // code.
     46 class CastSocket : public ApiResource,
     47                    public base::SupportsWeakPtr<CastSocket> {
     48  public:
     49   // Object to be informed of incoming messages and errors.
     50   class Delegate {
     51    public:
     52     // An error occurred on the channel.
     53     // It is fine to delete the socket in this callback.
     54     virtual void OnError(const CastSocket* socket, ChannelError error) = 0;
     55     // A message was received on the channel.
     56     // Do NOT delete the socket in this callback.
     57     virtual void OnMessage(const CastSocket* socket,
     58                            const MessageInfo& message) = 0;
     59 
     60    protected:
     61     virtual ~Delegate() {}
     62   };
     63 
     64   // Creates a new CastSocket that connects to |ip_endpoint| with
     65   // |channel_auth|. |owner_extension_id| is the id of the extension that opened
     66   // the socket.  |channel_auth| must not be CHANNEL_AUTH_NONE.
     67   CastSocket(const std::string& owner_extension_id,
     68              const net::IPEndPoint& ip_endpoint,
     69              ChannelAuthType channel_auth,
     70              CastSocket::Delegate* delegate,
     71              net::NetLog* net_log);
     72   virtual ~CastSocket();
     73 
     74   // The IP endpoint for the destination of the channel.
     75   const net::IPEndPoint& ip_endpoint() const { return ip_endpoint_; }
     76 
     77   // The authentication level requested for the channel.
     78   ChannelAuthType channel_auth() const { return channel_auth_; }
     79 
     80   // Returns a cast:// or casts:// URL for the channel endpoint.
     81   // For backwards compatibility.
     82   std::string CastUrl() const;
     83 
     84   // Channel id for the ApiResourceManager.
     85   int id() const { return channel_id_; }
     86 
     87   // Sets the channel id.
     88   void set_id(int channel_id) { channel_id_ = channel_id; }
     89 
     90   // Returns the state of the channel.  Virtual for testing.
     91   virtual ReadyState ready_state() const;
     92 
     93   // Returns the last error that occurred on this channel, or
     94   // CHANNEL_ERROR_NONE if no error has occurred.  Virtual for testing.
     95   virtual ChannelError error_state() const;
     96 
     97   // Connects the channel to the peer. If successful, the channel will be in
     98   // READY_STATE_OPEN.
     99   // It is fine to delete the CastSocket object in |callback|.
    100   virtual void Connect(const net::CompletionCallback& callback);
    101 
    102   // Sends a message over a connected channel. The channel must be in
    103   // READY_STATE_OPEN.
    104   //
    105   // Note that if an error occurs the following happens:
    106   // 1. Completion callbacks for all pending writes are invoked with error.
    107   // 2. Delegate::OnError is called once.
    108   // 3. Castsocket is closed.
    109   //
    110   // DO NOT delete the CastSocket object in write completion callback.
    111   // But it is fine to delete the socket in Delegate::OnError
    112   virtual void SendMessage(const MessageInfo& message,
    113                            const net::CompletionCallback& callback);
    114 
    115   // Closes the channel. On completion, the channel will be in
    116   // READY_STATE_CLOSED.
    117   // It is fine to delete the CastSocket object in |callback|.
    118   virtual void Close(const net::CompletionCallback& callback);
    119 
    120  protected:
    121   // Message header struct. If fields are added, be sure to update
    122   // header_size().  Protected to allow use of *_size() methods in unit tests.
    123   struct MessageHeader {
    124     MessageHeader();
    125     // Sets the message size.
    126     void SetMessageSize(size_t message_size);
    127     // Prepends this header to |str|.
    128     void PrependToString(std::string* str);
    129     // Reads |header| from the beginning of |buffer|.
    130     static void ReadFromIOBuffer(net::GrowableIOBuffer* buffer,
    131                                  MessageHeader* header);
    132     // Size (in bytes) of the message header.
    133     static uint32 header_size() { return sizeof(uint32); }
    134 
    135     // Maximum size (in bytes) of a message payload on the wire (does not
    136     // include header).
    137     static uint32 max_message_size() { return 65536; }
    138 
    139     std::string ToString();
    140     // The size of the following protocol message in bytes, in host byte order.
    141     uint32 message_size;
    142   };
    143 
    144  private:
    145   friend class ApiResourceManager<CastSocket>;
    146   friend class CastSocketTest;
    147 
    148   static const char* service_name() { return "CastSocketManager"; }
    149 
    150   // Internal connection states.
    151   enum ConnectionState {
    152     CONN_STATE_NONE,
    153     CONN_STATE_TCP_CONNECT,
    154     CONN_STATE_TCP_CONNECT_COMPLETE,
    155     CONN_STATE_SSL_CONNECT,
    156     CONN_STATE_SSL_CONNECT_COMPLETE,
    157     CONN_STATE_AUTH_CHALLENGE_SEND,
    158     CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE,
    159     CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE,
    160   };
    161 
    162   // Internal write states.
    163   enum WriteState {
    164     WRITE_STATE_NONE,
    165     WRITE_STATE_WRITE,
    166     WRITE_STATE_WRITE_COMPLETE,
    167     WRITE_STATE_DO_CALLBACK,
    168     WRITE_STATE_ERROR,
    169   };
    170 
    171   // Internal read states.
    172   enum ReadState {
    173     READ_STATE_NONE,
    174     READ_STATE_READ,
    175     READ_STATE_READ_COMPLETE,
    176     READ_STATE_DO_CALLBACK,
    177     READ_STATE_ERROR,
    178   };
    179 
    180   // Creates an instance of TCPClientSocket.
    181   virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket();
    182   // Creates an instance of SSLClientSocket with the given underlying |socket|.
    183   virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket(
    184       scoped_ptr<net::StreamSocket> socket);
    185   // Extracts peer certificate from SSLClientSocket instance when the socket
    186   // is in cert error state.
    187   // Returns whether certificate is successfully extracted.
    188   virtual bool ExtractPeerCert(std::string* cert);
    189   // Verifies whether the challenge reply received from the peer is valid:
    190   // 1. Signature in the reply is valid.
    191   // 2. Certificate is rooted to a trusted CA.
    192   virtual bool VerifyChallengeReply();
    193 
    194   /////////////////////////////////////////////////////////////////////////////
    195   // Following methods work together to implement the following flow:
    196   // 1. Create a new TCP socket and connect to it
    197   // 2. Create a new SSL socket and try connecting to it
    198   // 3. If connection fails due to invalid cert authority, then extract the
    199   //    peer certificate from the error.
    200   // 4. Whitelist the peer certificate and try #1 and #2 again.
    201   // 5. If SSL socket is connected successfully, and if protocol is casts://
    202   //    then issue an auth challenge request.
    203   // 6. Validate the auth challenge response.
    204   //
    205   // Main method that performs connection state transitions.
    206   void DoConnectLoop(int result);
    207   // Each of the below Do* method is executed in the corresponding
    208   // connection state. For example when connection state is TCP_CONNECT
    209   // DoTcpConnect is called, and so on.
    210   int DoTcpConnect();
    211   int DoTcpConnectComplete(int result);
    212   int DoSslConnect();
    213   int DoSslConnectComplete(int result);
    214   int DoAuthChallengeSend();
    215   int DoAuthChallengeSendComplete(int result);
    216   int DoAuthChallengeReplyComplete(int result);
    217   /////////////////////////////////////////////////////////////////////////////
    218 
    219   /////////////////////////////////////////////////////////////////////////////
    220   // Following methods work together to implement write flow.
    221   //
    222   // Main method that performs write flow state transitions.
    223   void DoWriteLoop(int result);
    224   // Each of the below Do* method is executed in the corresponding
    225   // write state. For example when write state is WRITE_STATE_WRITE_COMPLETE
    226   // DowriteComplete is called, and so on.
    227   int DoWrite();
    228   int DoWriteComplete(int result);
    229   int DoWriteCallback();
    230   int DoWriteError(int result);
    231   /////////////////////////////////////////////////////////////////////////////
    232 
    233   /////////////////////////////////////////////////////////////////////////////
    234   // Following methods work together to implement read flow.
    235   //
    236   // Main method that performs write flow state transitions.
    237   void DoReadLoop(int result);
    238   // Each of the below Do* method is executed in the corresponding
    239   // write state. For example when write state is READ_STATE_READ_COMPLETE
    240   // DoReadComplete is called, and so on.
    241   int DoRead();
    242   int DoReadComplete(int result);
    243   int DoReadCallback();
    244   int DoReadError(int result);
    245   /////////////////////////////////////////////////////////////////////////////
    246 
    247   // Runs the external connection callback and resets it.
    248   void DoConnectCallback(int result);
    249   // Adds |message| to the write queue and starts the write loop if needed.
    250   void SendCastMessageInternal(const CastMessage& message,
    251                                const net::CompletionCallback& callback);
    252   void PostTaskToStartConnectLoop(int result);
    253   void PostTaskToStartReadLoop();
    254   void StartReadLoop();
    255   // Parses the contents of header_read_buffer_ and sets current_message_size_
    256   // to the size of the body of the message.
    257   bool ProcessHeader();
    258   // Parses the contents of body_read_buffer_ and sets current_message_ to
    259   // the message received.
    260   bool ProcessBody();
    261   // Closes socket, updating the error state and signaling the delegate that
    262   // |error| has occurred.
    263   void CloseWithError(ChannelError error);
    264   // Serializes the content of message_proto (with a header) to |message_data|.
    265   static bool Serialize(const CastMessage& message_proto,
    266                         std::string* message_data);
    267 
    268   virtual bool CalledOnValidThread() const;
    269 
    270   base::ThreadChecker thread_checker_;
    271 
    272   // The id of the channel.
    273   int channel_id_;
    274 
    275   // The IP endpoint that the the channel is connected to.
    276   net::IPEndPoint ip_endpoint_;
    277   // Receiver authentication requested for the channel.
    278   ChannelAuthType channel_auth_;
    279   // Delegate to inform of incoming messages and errors.
    280   Delegate* delegate_;
    281 
    282   // IOBuffer for reading the message header.
    283   scoped_refptr<net::GrowableIOBuffer> header_read_buffer_;
    284   // IOBuffer for reading the message body.
    285   scoped_refptr<net::GrowableIOBuffer> body_read_buffer_;
    286   // IOBuffer to currently read into.
    287   scoped_refptr<net::GrowableIOBuffer> current_read_buffer_;
    288   // The number of bytes in the current message body.
    289   uint32 current_message_size_;
    290   // Last message received on the socket.
    291   scoped_ptr<CastMessage> current_message_;
    292 
    293   // The NetLog for this service.
    294   net::NetLog* net_log_;
    295   // The NetLog source for this service.
    296   net::NetLog::Source net_log_source_;
    297 
    298   // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket
    299   // since in some cases the destructor of SSLClientSocket may call a method
    300   // to cancel a cert verification request.
    301   scoped_ptr<net::CertVerifier> cert_verifier_;
    302   scoped_ptr<net::TransportSecurityState> transport_security_state_;
    303 
    304   // Owned ptr to the underlying TCP socket.
    305   scoped_ptr<net::TCPClientSocket> tcp_socket_;
    306   // Owned ptr to the underlying SSL socket.
    307   scoped_ptr<net::SSLClientSocket> socket_;
    308   // Certificate of the peer. This field may be empty if the peer
    309   // certificate is not yet fetched.
    310   std::string peer_cert_;
    311   // Reply received from the receiver to a challenge request.
    312   scoped_ptr<CastMessage> challenge_reply_;
    313 
    314   // Callback invoked when the socket is connected.
    315   net::CompletionCallback connect_callback_;
    316 
    317   // Connection flow state machine state.
    318   ConnectionState connect_state_;
    319   // Write flow state machine state.
    320   WriteState write_state_;
    321   // Read flow state machine state.
    322   ReadState read_state_;
    323   // The last error encountered by the channel.
    324   ChannelError error_state_;
    325   // The current status of the channel.
    326   ReadyState ready_state_;
    327 
    328   // Holds a message to be written to the socket. |callback| is invoked when the
    329   // message is fully written or an error occurrs.
    330   struct WriteRequest {
    331     explicit WriteRequest(const net::CompletionCallback& callback);
    332     ~WriteRequest();
    333     // Sets the content of the request by serializing |message| into |io_buffer|
    334     // and prepending the header.  Must only be called once.
    335     bool SetContent(const CastMessage& message_proto);
    336 
    337     net::CompletionCallback callback;
    338     scoped_refptr<net::DrainableIOBuffer> io_buffer;
    339   };
    340   // Queue of pending writes. The message at the front of the queue is the one
    341   // being written.
    342   std::queue<WriteRequest> write_queue_;
    343 
    344   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestFullSecureConnectionFlowAsync);
    345   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestRead);
    346   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadHeaderParseError);
    347   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadMany);
    348   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestWriteErrorLargeMessage);
    349   DISALLOW_COPY_AND_ASSIGN(CastSocket);
    350 };
    351 
    352 }  // namespace cast_channel
    353 }  // namespace api
    354 }  // namespace extensions
    355 
    356 #endif  // CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
    357