1 // Copyright 2014 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 EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ 6 #define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ 7 8 #include <queue> 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/cancelable_callback.h" 13 #include "base/gtest_prod_util.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/threading/thread_checker.h" 16 #include "base/timer/timer.h" 17 #include "extensions/browser/api/api_resource.h" 18 #include "extensions/browser/api/api_resource_manager.h" 19 #include "extensions/common/api/cast_channel.h" 20 #include "extensions/common/api/cast_channel/logging.pb.h" 21 #include "net/base/completion_callback.h" 22 #include "net/base/io_buffer.h" 23 #include "net/base/ip_endpoint.h" 24 #include "net/base/net_log.h" 25 26 namespace net { 27 class AddressList; 28 class CertVerifier; 29 class SSLClientSocket; 30 class StreamSocket; 31 class TCPClientSocket; 32 class TransportSecurityState; 33 } 34 35 namespace extensions { 36 namespace core_api { 37 namespace cast_channel { 38 39 class CastMessage; 40 class Logger; 41 struct LastErrors; 42 class MessageFramer; 43 44 // This class implements a channel between Chrome and a Cast device using a TCP 45 // socket with SSL. The channel may authenticate that the receiver is a genuine 46 // Cast device. All CastSocket objects must be used only on the IO thread. 47 // 48 // NOTE: Not called "CastChannel" to reduce confusion with the generated API 49 // code. 50 // TODO(kmarshall): Inherit from CastSocket and rename to CastSocketImpl. 51 class CastSocket : public ApiResource { 52 public: 53 // Object to be informed of incoming messages and errors. The CastSocket 54 // that owns the delegate must not be deleted by it, only by the 55 // ApiResourceManager or in the callback to Close(). 56 class Delegate { 57 public: 58 // An error occurred on the channel. |last_errors| contains the last errors 59 // logged for the channel from the implementation. 60 virtual void OnError(const CastSocket* socket, 61 ChannelError error_state, 62 const LastErrors& last_errors) = 0; 63 // A message was received on the channel. 64 virtual void OnMessage(const CastSocket* socket, 65 const MessageInfo& message) = 0; 66 67 protected: 68 virtual ~Delegate() {} 69 }; 70 71 // Creates a new CastSocket that connects to |ip_endpoint| with 72 // |channel_auth|. |owner_extension_id| is the id of the extension that opened 73 // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE. 74 CastSocket(const std::string& owner_extension_id, 75 const net::IPEndPoint& ip_endpoint, 76 ChannelAuthType channel_auth, 77 CastSocket::Delegate* delegate, 78 net::NetLog* net_log, 79 const base::TimeDelta& connect_timeout, 80 const scoped_refptr<Logger>& logger); 81 82 // Ensures that the socket is closed. 83 virtual ~CastSocket(); 84 85 // The IP endpoint for the destination of the channel. 86 const net::IPEndPoint& ip_endpoint() const { return ip_endpoint_; } 87 88 // The authentication level requested for the channel. 89 ChannelAuthType channel_auth() const { return channel_auth_; } 90 91 // Returns a cast:// or casts:// URL for the channel endpoint. 92 // For backwards compatibility. 93 std::string CastUrl() const; 94 95 // Channel id for the ApiResourceManager. 96 int id() const { return channel_id_; } 97 98 // Sets the channel id. 99 void set_id(int channel_id) { channel_id_ = channel_id; } 100 101 // Returns the state of the channel. Virtual for testing. 102 virtual ReadyState ready_state() const; 103 104 // Returns the last error that occurred on this channel, or 105 // CHANNEL_ERROR_NONE if no error has occurred. Virtual for testing. 106 virtual ChannelError error_state() const; 107 108 // Connects the channel to the peer. If successful, the channel will be in 109 // READY_STATE_OPEN. DO NOT delete the CastSocket object in |callback|. 110 // Instead use Close(). 111 virtual void Connect(const net::CompletionCallback& callback); 112 113 // Sends a message over a connected channel. The channel must be in 114 // READY_STATE_OPEN. 115 // 116 // Note that if an error occurs the following happens: 117 // 1. Completion callbacks for all pending writes are invoked with error. 118 // 2. Delegate::OnError is called once. 119 // 3. CastSocket is closed. 120 // 121 // DO NOT delete the CastSocket object in |callback|. Instead use Close(). 122 virtual void SendMessage(const MessageInfo& message, 123 const net::CompletionCallback& callback); 124 125 // Closes the channel if not already closed. On completion, the channel will 126 // be in READY_STATE_CLOSED. 127 // 128 // It is fine to delete the CastSocket object in |callback|. 129 virtual void Close(const net::CompletionCallback& callback); 130 131 private: 132 friend class ApiResourceManager<CastSocket>; 133 friend class CastSocketTest; 134 friend class TestCastSocket; 135 136 static const char* service_name() { return "CastSocketManager"; } 137 138 // Creates an instance of TCPClientSocket. 139 virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket(); 140 // Creates an instance of SSLClientSocket with the given underlying |socket|. 141 virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket( 142 scoped_ptr<net::StreamSocket> socket); 143 // Extracts peer certificate from SSLClientSocket instance when the socket 144 // is in cert error state. 145 // Returns whether certificate is successfully extracted. 146 virtual bool ExtractPeerCert(std::string* cert); 147 // Verifies whether the challenge reply received from the peer is valid: 148 // 1. Signature in the reply is valid. 149 // 2. Certificate is rooted to a trusted CA. 150 virtual bool VerifyChallengeReply(); 151 152 // Invoked by a cancelable closure when connection setup time 153 // exceeds the interval specified at |connect_timeout|. 154 void OnConnectTimeout(); 155 156 ///////////////////////////////////////////////////////////////////////////// 157 // Following methods work together to implement the following flow: 158 // 1. Create a new TCP socket and connect to it 159 // 2. Create a new SSL socket and try connecting to it 160 // 3. If connection fails due to invalid cert authority, then extract the 161 // peer certificate from the error. 162 // 4. Whitelist the peer certificate and try #1 and #2 again. 163 // 5. If SSL socket is connected successfully, and if protocol is casts:// 164 // then issue an auth challenge request. 165 // 6. Validate the auth challenge response. 166 // 167 // Main method that performs connection state transitions. 168 void DoConnectLoop(int result); 169 // Each of the below Do* method is executed in the corresponding 170 // connection state. For example when connection state is TCP_CONNECT 171 // DoTcpConnect is called, and so on. 172 int DoTcpConnect(); 173 int DoTcpConnectComplete(int result); 174 int DoSslConnect(); 175 int DoSslConnectComplete(int result); 176 int DoAuthChallengeSend(); 177 int DoAuthChallengeSendComplete(int result); 178 void DoAuthChallengeSendWriteComplete(int result); 179 int DoAuthChallengeReplyComplete(int result); 180 ///////////////////////////////////////////////////////////////////////////// 181 182 ///////////////////////////////////////////////////////////////////////////// 183 // Following methods work together to implement write flow. 184 // 185 // Main method that performs write flow state transitions. 186 void DoWriteLoop(int result); 187 // Each of the below Do* method is executed in the corresponding 188 // write state. For example when write state is WRITE_STATE_WRITE_COMPLETE 189 // DowriteComplete is called, and so on. 190 int DoWrite(); 191 int DoWriteComplete(int result); 192 int DoWriteCallback(); 193 int DoWriteError(int result); 194 ///////////////////////////////////////////////////////////////////////////// 195 196 ///////////////////////////////////////////////////////////////////////////// 197 // Following methods work together to implement read flow. 198 // 199 // Main method that performs write flow state transitions. 200 void DoReadLoop(int result); 201 // Each of the below Do* method is executed in the corresponding 202 // write state. For example when write state is READ_STATE_READ_COMPLETE 203 // DoReadComplete is called, and so on. 204 int DoRead(); 205 int DoReadComplete(int result); 206 int DoReadCallback(); 207 int DoReadError(int result); 208 ///////////////////////////////////////////////////////////////////////////// 209 210 // Runs the external connection callback and resets it. 211 void DoConnectCallback(int result); 212 // Adds |message| to the write queue and starts the write loop if needed. 213 void SendCastMessageInternal(const CastMessage& message, 214 const net::CompletionCallback& callback); 215 void PostTaskToStartConnectLoop(int result); 216 void PostTaskToStartReadLoop(); 217 void StartReadLoop(); 218 // Closes socket, signaling the delegate that |error| has occurred. 219 void CloseWithError(); 220 // Frees resources and cancels pending callbacks. |ready_state_| will be set 221 // READY_STATE_CLOSED on completion. A no-op if |ready_state_| is already 222 // READY_STATE_CLOSED. 223 void CloseInternal(); 224 // Runs pending callbacks that are passed into us to notify API clients that 225 // pending operations will fail because the socket has been closed. 226 void RunPendingCallbacksOnClose(); 227 // Serializes the content of message_proto (with a header) to |message_data|. 228 static bool Serialize(const CastMessage& message_proto, 229 std::string* message_data); 230 231 virtual bool CalledOnValidThread() const; 232 233 virtual base::Timer* GetTimer(); 234 235 void SetConnectState(proto::ConnectionState connect_state); 236 void SetReadyState(ReadyState ready_state); 237 void SetErrorState(ChannelError error_state); 238 void SetReadState(proto::ReadState read_state); 239 void SetWriteState(proto::WriteState write_state); 240 241 base::ThreadChecker thread_checker_; 242 243 // The id of the channel. 244 int channel_id_; 245 246 // The IP endpoint that the the channel is connected to. 247 net::IPEndPoint ip_endpoint_; 248 // Receiver authentication requested for the channel. 249 ChannelAuthType channel_auth_; 250 // Delegate to inform of incoming messages and errors. 251 Delegate* delegate_; 252 253 // IOBuffer for reading the message header. 254 scoped_refptr<net::GrowableIOBuffer> read_buffer_; 255 scoped_ptr<MessageFramer> framer_; 256 257 // The NetLog for this service. 258 net::NetLog* net_log_; 259 // The NetLog source for this service. 260 net::NetLog::Source net_log_source_; 261 262 // Logger used to track multiple CastSockets. Does NOT own this object. 263 scoped_refptr<Logger> logger_; 264 265 // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket 266 // since in some cases the destructor of SSLClientSocket may call a method 267 // to cancel a cert verification request. 268 scoped_ptr<net::CertVerifier> cert_verifier_; 269 scoped_ptr<net::TransportSecurityState> transport_security_state_; 270 271 // Owned ptr to the underlying TCP socket. 272 scoped_ptr<net::TCPClientSocket> tcp_socket_; 273 // Owned ptr to the underlying SSL socket. 274 scoped_ptr<net::SSLClientSocket> socket_; 275 // Certificate of the peer. This field may be empty if the peer 276 // certificate is not yet fetched. 277 std::string peer_cert_; 278 // Reply received from the receiver to a challenge request. 279 scoped_ptr<CastMessage> challenge_reply_; 280 281 // Callback invoked when the socket is connected or fails to connect. 282 net::CompletionCallback connect_callback_; 283 284 // Callback invoked by |connect_timeout_timer_| to cancel the connection. 285 base::CancelableClosure connect_timeout_callback_; 286 // Duration to wait before timing out. 287 base::TimeDelta connect_timeout_; 288 // Timer invoked when the connection has timed out. 289 scoped_ptr<base::Timer> connect_timeout_timer_; 290 // Set when a timeout is triggered and the connection process has 291 // canceled. 292 bool is_canceled_; 293 294 scoped_ptr<CastMessage> current_message_; 295 296 // Connection flow state machine state. 297 proto::ConnectionState connect_state_; 298 // Write flow state machine state. 299 proto::WriteState write_state_; 300 // Read flow state machine state. 301 proto::ReadState read_state_; 302 // The last error encountered by the channel. 303 ChannelError error_state_; 304 // The current status of the channel. 305 ReadyState ready_state_; 306 307 // Task invoked to (re)start the connect loop. Canceled on entry to the 308 // connect loop. 309 base::CancelableClosure connect_loop_callback_; 310 // Task invoked to send the auth challenge. Canceled when the auth challenge 311 // has been sent. 312 base::CancelableClosure send_auth_challenge_callback_; 313 // Callback invoked to (re)start the read loop. Canceled on entry to the read 314 // loop. 315 base::CancelableClosure read_loop_callback_; 316 317 // Holds a message to be written to the socket. |callback| is invoked when the 318 // message is fully written or an error occurrs. 319 struct WriteRequest { 320 explicit WriteRequest(const net::CompletionCallback& callback); 321 ~WriteRequest(); 322 // Sets the content of the request by serializing |message| into |io_buffer| 323 // and prepending the header. Must only be called once. 324 bool SetContent(const CastMessage& message_proto); 325 326 net::CompletionCallback callback; 327 std::string message_namespace; 328 scoped_refptr<net::DrainableIOBuffer> io_buffer; 329 }; 330 // Queue of pending writes. The message at the front of the queue is the one 331 // being written. 332 std::queue<WriteRequest> write_queue_; 333 334 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestFullSecureConnectionFlowAsync); 335 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestRead); 336 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadHeaderParseError); 337 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadMany); 338 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestWriteErrorLargeMessage); 339 DISALLOW_COPY_AND_ASSIGN(CastSocket); 340 }; 341 } // namespace cast_channel 342 } // namespace core_api 343 } // namespace extensions 344 345 #endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ 346