| OLD | NEW |
| (Empty) |
| 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 COMPONENTS_CAST_CHANNEL_CAST_SOCKET_H_ | |
| 6 #define COMPONENTS_CAST_CHANNEL_CAST_SOCKET_H_ | |
| 7 | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <queue> | |
| 11 #include <string> | |
| 12 | |
| 13 #include "base/cancelable_callback.h" | |
| 14 #include "base/gtest_prod_util.h" | |
| 15 #include "base/macros.h" | |
| 16 #include "base/memory/ref_counted.h" | |
| 17 #include "base/threading/thread_checker.h" | |
| 18 #include "base/timer/timer.h" | |
| 19 #include "components/cast_channel/cast_auth_util.h" | |
| 20 #include "components/cast_channel/cast_channel_enum.h" | |
| 21 #include "components/cast_channel/cast_socket.h" | |
| 22 #include "components/cast_channel/cast_transport.h" | |
| 23 #include "components/cast_channel/proto/logging.pb.h" | |
| 24 #include "net/base/completion_callback.h" | |
| 25 #include "net/base/io_buffer.h" | |
| 26 #include "net/base/ip_endpoint.h" | |
| 27 #include "net/log/net_log_source.h" | |
| 28 | |
| 29 namespace net { | |
| 30 class CertVerifier; | |
| 31 class CTPolicyEnforcer; | |
| 32 class CTVerifier; | |
| 33 class NetLog; | |
| 34 class SSLClientSocket; | |
| 35 class StreamSocket; | |
| 36 class TCPClientSocket; | |
| 37 class TransportSecurityState; | |
| 38 class X509Certificate; | |
| 39 } | |
| 40 | |
| 41 namespace cast_channel { | |
| 42 class CastMessage; | |
| 43 class Logger; | |
| 44 struct LastErrors; | |
| 45 | |
| 46 // Cast device capabilities. | |
| 47 enum CastDeviceCapability { | |
| 48 NONE = 0, | |
| 49 VIDEO_OUT = 1 << 0, | |
| 50 VIDEO_IN = 1 << 1, | |
| 51 AUDIO_OUT = 1 << 2, | |
| 52 AUDIO_IN = 1 << 3, | |
| 53 DEV_MODE = 1 << 4 | |
| 54 }; | |
| 55 | |
| 56 // Public interface of the CastSocket class. | |
| 57 class CastSocket { | |
| 58 public: | |
| 59 using ChannelError = ::cast_channel::ChannelError; | |
| 60 using ChannelAuthType = ::cast_channel::ChannelAuthType; | |
| 61 using ReadyState = ::cast_channel::ReadyState; | |
| 62 | |
| 63 virtual ~CastSocket() {} | |
| 64 | |
| 65 // Used by BrowserContextKeyedAPIFactory. | |
| 66 static const char* service_name() { return "CastSocketImplManager"; } | |
| 67 | |
| 68 // Connects the channel to the peer. If successful, the channel will be in | |
| 69 // READY_STATE_OPEN. DO NOT delete the CastSocket object in |callback|. | |
| 70 // Instead use Close(). | |
| 71 // |callback| will be invoked with any ChannelError that occurred, or | |
| 72 // CHANNEL_ERROR_NONE if successful. | |
| 73 // If the CastSocket is destroyed while the connection is pending, |callback| | |
| 74 // will be invoked with CHANNEL_ERROR_UNKNOWN. In this case, invoking | |
| 75 // |callback| must not result in any re-entrancy behavior. | |
| 76 // |delegate| receives message receipt and error events. | |
| 77 // Ownership of |delegate| is transferred to this CastSocket. | |
| 78 virtual void Connect(std::unique_ptr<CastTransport::Delegate> delegate, | |
| 79 base::Callback<void(ChannelError)> callback) = 0; | |
| 80 | |
| 81 // Closes the channel if not already closed. On completion, the channel will | |
| 82 // be in READY_STATE_CLOSED. | |
| 83 // | |
| 84 // It is fine to delete this object in |callback|. | |
| 85 virtual void Close(const net::CompletionCallback& callback) = 0; | |
| 86 | |
| 87 // The IP endpoint for the destination of the channel. | |
| 88 virtual const net::IPEndPoint& ip_endpoint() const = 0; | |
| 89 | |
| 90 // Channel id generated by the CastChannelService. | |
| 91 virtual int id() const = 0; | |
| 92 | |
| 93 // Sets the channel id generated by CastChannelService. | |
| 94 virtual void set_id(int id) = 0; | |
| 95 | |
| 96 // The authentication level requested for the channel. | |
| 97 virtual ChannelAuthType channel_auth() const = 0; | |
| 98 | |
| 99 // The ready state of the channel. | |
| 100 virtual ReadyState ready_state() const = 0; | |
| 101 | |
| 102 // Returns the last error that occurred on this channel, or | |
| 103 // CHANNEL_ERROR_NONE if no error has occurred. | |
| 104 virtual ChannelError error_state() const = 0; | |
| 105 | |
| 106 // True when keep-alive signaling is handled for this socket. | |
| 107 virtual bool keep_alive() const = 0; | |
| 108 | |
| 109 // Whether the channel is audio only as identified by the device | |
| 110 // certificate during channel authentication. | |
| 111 virtual bool audio_only() const = 0; | |
| 112 | |
| 113 // Marks a socket as invalid due to an error, and sends an OnError | |
| 114 // event to |delegate_|. | |
| 115 // The OnError event receipient is responsible for closing the socket in the | |
| 116 // event of an error. | |
| 117 // Setting the error state does not close the socket if it is open. | |
| 118 virtual void SetErrorState(ChannelError error_state) = 0; | |
| 119 | |
| 120 // Returns a pointer to the socket's message transport layer. Can be used to | |
| 121 // send and receive CastMessages over the socket. | |
| 122 virtual CastTransport* transport() const = 0; | |
| 123 }; | |
| 124 | |
| 125 // This class implements a channel between Chrome and a Cast device using a TCP | |
| 126 // socket with SSL. The channel may authenticate that the receiver is a genuine | |
| 127 // Cast device. All CastSocketImpl objects must be used only on the IO thread. | |
| 128 // | |
| 129 // NOTE: Not called "CastChannel" to reduce confusion with the generated API | |
| 130 // code. | |
| 131 class CastSocketImpl : public CastSocket { | |
| 132 public: | |
| 133 // Creates a new CastSocket that connects to |ip_endpoint| with | |
| 134 // |channel_auth|. |owner_extension_id| is the id of the extension that opened | |
| 135 // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE. | |
| 136 // Parameters: | |
| 137 // |owner_extension_id|: ID of the extension calling the API. | |
| 138 // |ip_endpoint|: IP address of the remote host. | |
| 139 // |channel_auth|: Authentication method used for connecting to a Cast | |
| 140 // receiver. | |
| 141 // |net_log|: Log of socket events. | |
| 142 // |connect_timeout|: Connection timeout interval. | |
| 143 // |logger|: Log of cast channel events. | |
| 144 CastSocketImpl(const std::string& owner_extension_id, | |
| 145 const net::IPEndPoint& ip_endpoint, | |
| 146 ChannelAuthType channel_auth, | |
| 147 net::NetLog* net_log, | |
| 148 const base::TimeDelta& connect_timeout, | |
| 149 bool keep_alive, | |
| 150 const scoped_refptr<Logger>& logger, | |
| 151 uint64_t device_capabilities); | |
| 152 | |
| 153 // For test-only. | |
| 154 // This constructor allows for setting a custom AuthContext. | |
| 155 CastSocketImpl(const std::string& owner_extension_id, | |
| 156 const net::IPEndPoint& ip_endpoint, | |
| 157 ChannelAuthType channel_auth, | |
| 158 net::NetLog* net_log, | |
| 159 const base::TimeDelta& connect_timeout, | |
| 160 bool keep_alive, | |
| 161 const scoped_refptr<Logger>& logger, | |
| 162 uint64_t device_capabilities, | |
| 163 const AuthContext& auth_context); | |
| 164 | |
| 165 // Ensures that the socket is closed. | |
| 166 ~CastSocketImpl() override; | |
| 167 | |
| 168 // CastSocket interface. | |
| 169 void Connect(std::unique_ptr<CastTransport::Delegate> delegate, | |
| 170 base::Callback<void(ChannelError)> callback) override; | |
| 171 CastTransport* transport() const override; | |
| 172 void Close(const net::CompletionCallback& callback) override; | |
| 173 const net::IPEndPoint& ip_endpoint() const override; | |
| 174 int id() const override; | |
| 175 void set_id(int channel_id) override; | |
| 176 ChannelAuthType channel_auth() const override; | |
| 177 ReadyState ready_state() const override; | |
| 178 ChannelError error_state() const override; | |
| 179 bool keep_alive() const override; | |
| 180 bool audio_only() const override; | |
| 181 | |
| 182 protected: | |
| 183 // CastTransport::Delegate methods for receiving handshake messages. | |
| 184 class AuthTransportDelegate : public CastTransport::Delegate { | |
| 185 public: | |
| 186 explicit AuthTransportDelegate(CastSocketImpl* socket); | |
| 187 | |
| 188 // Gets the error state of the channel. | |
| 189 // Returns CHANNEL_ERROR_NONE if no errors are present. | |
| 190 ChannelError error_state() const; | |
| 191 | |
| 192 // Gets recorded error details. | |
| 193 LastErrors last_errors() const; | |
| 194 | |
| 195 // CastTransport::Delegate interface. | |
| 196 void OnError(ChannelError error_state) override; | |
| 197 void OnMessage(const CastMessage& message) override; | |
| 198 void Start() override; | |
| 199 | |
| 200 private: | |
| 201 CastSocketImpl* socket_; | |
| 202 ChannelError error_state_; | |
| 203 LastErrors last_errors_; | |
| 204 }; | |
| 205 | |
| 206 // Replaces the internally-constructed transport object with one provided | |
| 207 // by the caller (e.g. a mock). | |
| 208 void SetTransportForTesting(std::unique_ptr<CastTransport> transport); | |
| 209 | |
| 210 // Verifies whether the socket complies with cast channel policy. | |
| 211 // Audio only channel policy mandates that a device declaring a video out | |
| 212 // capability must not have a certificate with audio only policy. | |
| 213 bool VerifyChannelPolicy(const AuthResult& result); | |
| 214 | |
| 215 private: | |
| 216 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestConnectAuthMessageCorrupted); | |
| 217 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, | |
| 218 TestConnectChallengeReplyReceiveError); | |
| 219 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, | |
| 220 TestConnectChallengeVerificationFails); | |
| 221 friend class AuthTransportDelegate; | |
| 222 friend class CastSocketTest; | |
| 223 friend class TestCastSocket; | |
| 224 | |
| 225 void SetErrorState(ChannelError error_state) override; | |
| 226 | |
| 227 // Frees resources and cancels pending callbacks. |ready_state_| will be set | |
| 228 // READY_STATE_CLOSED on completion. A no-op if |ready_state_| is already | |
| 229 // READY_STATE_CLOSED. | |
| 230 void CloseInternal(); | |
| 231 | |
| 232 // Creates an instance of TCPClientSocket. | |
| 233 virtual std::unique_ptr<net::TCPClientSocket> CreateTcpSocket(); | |
| 234 // Creates an instance of SSLClientSocket with the given underlying |socket|. | |
| 235 virtual std::unique_ptr<net::SSLClientSocket> CreateSslSocket( | |
| 236 std::unique_ptr<net::StreamSocket> socket); | |
| 237 // Extracts peer certificate from SSLClientSocket instance when the socket | |
| 238 // is in cert error state. | |
| 239 // Returns null if the certificate could not be extracted. | |
| 240 // TODO(kmarshall): Use MockSSLClientSocket for tests instead of overriding | |
| 241 // this function. | |
| 242 virtual scoped_refptr<net::X509Certificate> ExtractPeerCert(); | |
| 243 // Verifies whether the challenge reply received from the peer is valid: | |
| 244 // 1. Signature in the reply is valid. | |
| 245 // 2. Certificate is rooted to a trusted CA. | |
| 246 virtual bool VerifyChallengeReply(); | |
| 247 | |
| 248 // Invoked by a cancelable closure when connection setup time | |
| 249 // exceeds the interval specified at |connect_timeout|. | |
| 250 void OnConnectTimeout(); | |
| 251 | |
| 252 ///////////////////////////////////////////////////////////////////////////// | |
| 253 // Following methods work together to implement the following flow: | |
| 254 // 1. Create a new TCP socket and connect to it | |
| 255 // 2. Create a new SSL socket and try connecting to it | |
| 256 // 3. If connection fails due to invalid cert authority, then extract the | |
| 257 // peer certificate from the error. | |
| 258 // 4. Whitelist the peer certificate and try #1 and #2 again. | |
| 259 // 5. If SSL socket is connected successfully, and if protocol is casts:// | |
| 260 // then issue an auth challenge request. | |
| 261 // 6. Validate the auth challenge response. | |
| 262 // | |
| 263 // Main method that performs connection state transitions. | |
| 264 void DoConnectLoop(int result); | |
| 265 // Each of the below Do* method is executed in the corresponding | |
| 266 // connection state. For example when connection state is TCP_CONNECT | |
| 267 // DoTcpConnect is called, and so on. | |
| 268 int DoTcpConnect(); | |
| 269 int DoTcpConnectComplete(int result); | |
| 270 int DoSslConnect(); | |
| 271 int DoSslConnectComplete(int result); | |
| 272 int DoAuthChallengeSend(); | |
| 273 int DoAuthChallengeSendComplete(int result); | |
| 274 int DoAuthChallengeReplyComplete(int result); | |
| 275 ///////////////////////////////////////////////////////////////////////////// | |
| 276 | |
| 277 // Resets the cancellable callback used for async invocations of | |
| 278 // DoConnectLoop. | |
| 279 void ResetConnectLoopCallback(); | |
| 280 | |
| 281 // Posts a task to invoke |connect_loop_callback_| with |result| on the | |
| 282 // current message loop. | |
| 283 void PostTaskToStartConnectLoop(int result); | |
| 284 | |
| 285 // Runs the external connection callback and resets it. | |
| 286 void DoConnectCallback(); | |
| 287 | |
| 288 virtual base::Timer* GetTimer(); | |
| 289 | |
| 290 void SetConnectState(proto::ConnectionState connect_state); | |
| 291 void SetReadyState(ReadyState ready_state); | |
| 292 | |
| 293 THREAD_CHECKER(thread_checker_); | |
| 294 | |
| 295 // The id of the channel. | |
| 296 int channel_id_; | |
| 297 // The IP endpoint that the the channel is connected to. | |
| 298 net::IPEndPoint ip_endpoint_; | |
| 299 // Receiver authentication requested for the channel. | |
| 300 ChannelAuthType channel_auth_; | |
| 301 // The NetLog for this service. | |
| 302 net::NetLog* net_log_; | |
| 303 // The NetLog source for this service. | |
| 304 net::NetLogSource net_log_source_; | |
| 305 // True when keep-alive signaling should be handled for this socket. | |
| 306 bool keep_alive_; | |
| 307 | |
| 308 // Shared logging object, used to log CastSocket events for diagnostics. | |
| 309 scoped_refptr<Logger> logger_; | |
| 310 | |
| 311 // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket | |
| 312 // since in some cases the destructor of SSLClientSocket may call a method | |
| 313 // to cancel a cert verification request. | |
| 314 std::unique_ptr<net::CertVerifier> cert_verifier_; | |
| 315 std::unique_ptr<net::TransportSecurityState> transport_security_state_; | |
| 316 std::unique_ptr<net::CTVerifier> cert_transparency_verifier_; | |
| 317 std::unique_ptr<net::CTPolicyEnforcer> ct_policy_enforcer_; | |
| 318 | |
| 319 // Owned ptr to the underlying TCP socket. | |
| 320 std::unique_ptr<net::TCPClientSocket> tcp_socket_; | |
| 321 | |
| 322 // Owned ptr to the underlying SSL socket. | |
| 323 std::unique_ptr<net::SSLClientSocket> socket_; | |
| 324 | |
| 325 // Certificate of the peer. This field may be empty if the peer | |
| 326 // certificate is not yet fetched. | |
| 327 scoped_refptr<net::X509Certificate> peer_cert_; | |
| 328 | |
| 329 // The challenge context for the current connection. | |
| 330 const AuthContext auth_context_; | |
| 331 | |
| 332 // Reply received from the receiver to a challenge request. | |
| 333 std::unique_ptr<CastMessage> challenge_reply_; | |
| 334 | |
| 335 // Callback invoked when the socket is connected or fails to connect. | |
| 336 base::Callback<void(ChannelError)> connect_callback_; | |
| 337 | |
| 338 // Callback invoked by |connect_timeout_timer_| to cancel the connection. | |
| 339 base::CancelableClosure connect_timeout_callback_; | |
| 340 | |
| 341 // Duration to wait before timing out. | |
| 342 base::TimeDelta connect_timeout_; | |
| 343 | |
| 344 // Timer invoked when the connection has timed out. | |
| 345 std::unique_ptr<base::Timer> connect_timeout_timer_; | |
| 346 | |
| 347 // Set when a timeout is triggered and the connection process has | |
| 348 // canceled. | |
| 349 bool is_canceled_; | |
| 350 | |
| 351 // Capabilities declared by the cast device. | |
| 352 uint64_t device_capabilities_; | |
| 353 | |
| 354 // Whether the channel is audio only as identified by the device | |
| 355 // certificate during channel authentication. | |
| 356 bool audio_only_; | |
| 357 | |
| 358 // Connection flow state machine state. | |
| 359 proto::ConnectionState connect_state_; | |
| 360 | |
| 361 // Write flow state machine state. | |
| 362 proto::WriteState write_state_; | |
| 363 | |
| 364 // Read flow state machine state. | |
| 365 proto::ReadState read_state_; | |
| 366 | |
| 367 // The last error encountered by the channel. | |
| 368 ChannelError error_state_; | |
| 369 | |
| 370 // The current status of the channel. | |
| 371 ReadyState ready_state_; | |
| 372 | |
| 373 // Callback which, when invoked, will re-enter the connection state machine. | |
| 374 // Oustanding callbacks will be cancelled when |this| is destroyed. | |
| 375 // The callback signature is based on net::CompletionCallback, which passes | |
| 376 // operation result codes as byte counts in the success case, or as | |
| 377 // net::Error enum values for error cases. | |
| 378 base::CancelableCallback<void(int)> connect_loop_callback_; | |
| 379 | |
| 380 // Cast message formatting and parsing layer. | |
| 381 std::unique_ptr<CastTransport> transport_; | |
| 382 | |
| 383 // Caller's message read and error handling delegate. | |
| 384 std::unique_ptr<CastTransport::Delegate> delegate_; | |
| 385 | |
| 386 // Raw pointer to the auth handshake delegate. Used to get detailed error | |
| 387 // information. | |
| 388 AuthTransportDelegate* auth_delegate_; | |
| 389 | |
| 390 DISALLOW_COPY_AND_ASSIGN(CastSocketImpl); | |
| 391 }; | |
| 392 } // namespace cast_channel | |
| 393 | |
| 394 #endif // COMPONENTS_CAST_CHANNEL_CAST_SOCKET_H_ | |
| OLD | NEW |