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.
5 #ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_
6 #define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_
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/browser/api/cast_channel/cast_socket.h"
20 #include "extensions/browser/api/cast_channel/cast_transport.h"
21 #include "extensions/browser/api/cast_channel/logger_util.h"
22 #include "extensions/common/api/cast_channel.h"
23 #include "extensions/common/api/cast_channel/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.h"
32 class SSLClientSocket
;
34 class TCPClientSocket
;
35 class TransportSecurityState
;
38 namespace extensions
{
40 namespace cast_channel
{
46 // Cast device capabilities.
47 enum CastDeviceCapability
{
56 // Public interface of the CastSocket class.
57 class CastSocket
: public ApiResource
{
59 explicit CastSocket(const std::string
& owner_extension_id
);
60 ~CastSocket() override
{}
62 // Used by BrowserContextKeyedAPIFactory.
63 static const char* service_name() { return "CastSocketImplManager"; }
65 // Connects the channel to the peer. If successful, the channel will be in
66 // READY_STATE_OPEN. DO NOT delete the CastSocket object in |callback|.
67 // Instead use Close().
68 // |callback| will be invoked with any ChannelError that occurred, or
69 // CHANNEL_ERROR_NONE if successful.
70 // |delegate| receives message receipt and error events.
71 // Ownership of |delegate| is transferred to this CastSocket.
72 virtual void Connect(scoped_ptr
<CastTransport::Delegate
> delegate
,
73 base::Callback
<void(ChannelError
)> callback
) = 0;
75 // Closes the channel if not already closed. On completion, the channel will
76 // be in READY_STATE_CLOSED.
78 // It is fine to delete this object in |callback|.
79 virtual void Close(const net::CompletionCallback
& callback
) = 0;
81 // The IP endpoint for the destination of the channel.
82 virtual const net::IPEndPoint
& ip_endpoint() const = 0;
84 // Channel id generated by the ApiResourceManager.
85 virtual int id() const = 0;
87 // Sets the channel id generated by ApiResourceManager.
88 virtual void set_id(int id
) = 0;
90 // The authentication level requested for the channel.
91 virtual ChannelAuthType
channel_auth() const = 0;
93 // The ready state of the channel.
94 virtual ReadyState
ready_state() const = 0;
96 // Returns the last error that occurred on this channel, or
97 // CHANNEL_ERROR_NONE if no error has occurred.
98 virtual ChannelError
error_state() const = 0;
100 // True when keep-alive signaling is handled for this socket.
101 virtual bool keep_alive() const = 0;
103 // Marks a socket as invalid due to an error, and sends an OnError
104 // event to |delegate_|.
105 // The OnError event receipient is responsible for closing the socket in the
106 // event of an error.
107 // Setting the error state does not close the socket if it is open.
108 virtual void SetErrorState(ChannelError error_state
) = 0;
110 // Returns a pointer to the socket's message transport layer. Can be used to
111 // send and receive CastMessages over the socket.
112 virtual CastTransport
* transport() const = 0;
114 // Tells the ApiResourceManager to retain CastSocket objects even
115 // if their corresponding extension is suspended.
116 // (CastSockets are still deleted if the extension is removed entirely from
118 bool IsPersistent() const override
;
121 // This class implements a channel between Chrome and a Cast device using a TCP
122 // socket with SSL. The channel may authenticate that the receiver is a genuine
123 // Cast device. All CastSocketImpl objects must be used only on the IO thread.
125 // NOTE: Not called "CastChannel" to reduce confusion with the generated API
127 class CastSocketImpl
: public CastSocket
{
129 // Creates a new CastSocket that connects to |ip_endpoint| with
130 // |channel_auth|. |owner_extension_id| is the id of the extension that opened
131 // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE.
133 // |owner_extension_id|: ID of the extension calling the API.
134 // |ip_endpoint|: IP address of the remote host.
135 // |channel_auth|: Authentication method used for connecting to a Cast
137 // |net_log|: Log of socket events.
138 // |connect_timeout|: Connection timeout interval.
139 // |logger|: Log of cast channel events.
140 CastSocketImpl(const std::string
& owner_extension_id
,
141 const net::IPEndPoint
& ip_endpoint
,
142 ChannelAuthType channel_auth
,
143 net::NetLog
* net_log
,
144 const base::TimeDelta
& connect_timeout
,
146 const scoped_refptr
<Logger
>& logger
,
147 uint64 device_capabilities
);
149 // Ensures that the socket is closed.
150 ~CastSocketImpl() override
;
152 // CastSocket interface.
153 void Connect(scoped_ptr
<CastTransport::Delegate
> delegate
,
154 base::Callback
<void(ChannelError
)> callback
) override
;
155 CastTransport
* transport() const override
;
156 void Close(const net::CompletionCallback
& callback
) override
;
157 const net::IPEndPoint
& ip_endpoint() const override
;
158 int id() const override
;
159 void set_id(int channel_id
) override
;
160 ChannelAuthType
channel_auth() const override
;
161 ReadyState
ready_state() const override
;
162 ChannelError
error_state() const override
;
163 bool keep_alive() const override
;
165 // Required by ApiResourceManager.
166 static const char* service_name() { return "CastSocketManager"; }
169 // CastTransport::Delegate methods for receiving handshake messages.
170 class AuthTransportDelegate
: public CastTransport::Delegate
{
172 explicit AuthTransportDelegate(CastSocketImpl
* socket
);
174 // Gets the error state of the channel.
175 // Returns CHANNEL_ERROR_NONE if no errors are present.
176 ChannelError
error_state() const;
178 // Gets recorded error details.
179 LastErrors
last_errors() const;
181 // CastTransport::Delegate interface.
182 void OnError(ChannelError error_state
) override
;
183 void OnMessage(const CastMessage
& message
) override
;
184 void Start() override
;
187 CastSocketImpl
* socket_
;
188 ChannelError error_state_
;
189 LastErrors last_errors_
;
192 // Replaces the internally-constructed transport object with one provided
193 // by the caller (e.g. a mock).
194 void SetTransportForTesting(scoped_ptr
<CastTransport
> transport
);
196 // Verifies whether the socket complies with cast channel policy.
197 // Audio only channel policy mandates that a device declaring a video out
198 // capability must not have a certificate with audio only policy.
199 bool VerifyChannelPolicy(const AuthResult
& result
);
202 FRIEND_TEST_ALL_PREFIXES(CastSocketTest
, TestConnectAuthMessageCorrupted
);
203 FRIEND_TEST_ALL_PREFIXES(CastSocketTest
,
204 TestConnectChallengeReplyReceiveError
);
205 FRIEND_TEST_ALL_PREFIXES(CastSocketTest
,
206 TestConnectChallengeVerificationFails
);
207 friend class AuthTransportDelegate
;
208 friend class ApiResourceManager
<CastSocketImpl
>;
209 friend class CastSocketTest
;
210 friend class TestCastSocket
;
212 void SetErrorState(ChannelError error_state
) override
;
214 // Frees resources and cancels pending callbacks. |ready_state_| will be set
215 // READY_STATE_CLOSED on completion. A no-op if |ready_state_| is already
216 // READY_STATE_CLOSED.
217 void CloseInternal();
219 // Creates an instance of TCPClientSocket.
220 virtual scoped_ptr
<net::TCPClientSocket
> CreateTcpSocket();
221 // Creates an instance of SSLClientSocket with the given underlying |socket|.
222 virtual scoped_ptr
<net::SSLClientSocket
> CreateSslSocket(
223 scoped_ptr
<net::StreamSocket
> socket
);
224 // Extracts peer certificate from SSLClientSocket instance when the socket
225 // is in cert error state.
226 // Returns whether certificate is successfully extracted.
227 virtual bool ExtractPeerCert(std::string
* cert
);
228 // Verifies whether the challenge reply received from the peer is valid:
229 // 1. Signature in the reply is valid.
230 // 2. Certificate is rooted to a trusted CA.
231 virtual bool VerifyChallengeReply();
233 // Invoked by a cancelable closure when connection setup time
234 // exceeds the interval specified at |connect_timeout|.
235 void OnConnectTimeout();
237 /////////////////////////////////////////////////////////////////////////////
238 // Following methods work together to implement the following flow:
239 // 1. Create a new TCP socket and connect to it
240 // 2. Create a new SSL socket and try connecting to it
241 // 3. If connection fails due to invalid cert authority, then extract the
242 // peer certificate from the error.
243 // 4. Whitelist the peer certificate and try #1 and #2 again.
244 // 5. If SSL socket is connected successfully, and if protocol is casts://
245 // then issue an auth challenge request.
246 // 6. Validate the auth challenge response.
248 // Main method that performs connection state transitions.
249 void DoConnectLoop(int result
);
250 // Each of the below Do* method is executed in the corresponding
251 // connection state. For example when connection state is TCP_CONNECT
252 // DoTcpConnect is called, and so on.
254 int DoTcpConnectComplete(int result
);
256 int DoSslConnectComplete(int result
);
257 int DoAuthChallengeSend();
258 int DoAuthChallengeSendComplete(int result
);
259 int DoAuthChallengeReplyComplete(int result
);
260 /////////////////////////////////////////////////////////////////////////////
262 // Schedules asynchrous connection loop processing in the MessageLoop.
263 void PostTaskToStartConnectLoop(int result
);
265 // Runs the external connection callback and resets it.
266 void DoConnectCallback();
268 virtual bool CalledOnValidThread() const;
270 virtual base::Timer
* GetTimer();
272 void SetConnectState(proto::ConnectionState connect_state
);
273 void SetReadyState(ReadyState ready_state
);
275 base::ThreadChecker thread_checker_
;
277 const std::string owner_extension_id_
;
278 // The id of the channel.
280 // The IP endpoint that the the channel is connected to.
281 net::IPEndPoint ip_endpoint_
;
282 // Receiver authentication requested for the channel.
283 ChannelAuthType channel_auth_
;
284 // The NetLog for this service.
285 net::NetLog
* net_log_
;
286 // The NetLog source for this service.
287 net::NetLog::Source net_log_source_
;
288 // True when keep-alive signaling should be handled for this socket.
291 // Shared logging object, used to log CastSocket events for diagnostics.
292 scoped_refptr
<Logger
> logger_
;
294 // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket
295 // since in some cases the destructor of SSLClientSocket may call a method
296 // to cancel a cert verification request.
297 scoped_ptr
<net::CertVerifier
> cert_verifier_
;
298 scoped_ptr
<net::TransportSecurityState
> transport_security_state_
;
300 // Owned ptr to the underlying TCP socket.
301 scoped_ptr
<net::TCPClientSocket
> tcp_socket_
;
303 // Owned ptr to the underlying SSL socket.
304 scoped_ptr
<net::SSLClientSocket
> socket_
;
306 // Certificate of the peer. This field may be empty if the peer
307 // certificate is not yet fetched.
308 std::string peer_cert_
;
310 // Reply received from the receiver to a challenge request.
311 scoped_ptr
<CastMessage
> challenge_reply_
;
313 // Callback invoked when the socket is connected or fails to connect.
314 base::Callback
<void(ChannelError
)> connect_callback_
;
316 // Callback invoked by |connect_timeout_timer_| to cancel the connection.
317 base::CancelableClosure connect_timeout_callback_
;
319 // Duration to wait before timing out.
320 base::TimeDelta connect_timeout_
;
322 // Timer invoked when the connection has timed out.
323 scoped_ptr
<base::Timer
> connect_timeout_timer_
;
325 // Set when a timeout is triggered and the connection process has
329 // Capabilities declared by the cast device.
330 uint64 device_capabilities_
;
332 // Connection flow state machine state.
333 proto::ConnectionState connect_state_
;
335 // Write flow state machine state.
336 proto::WriteState write_state_
;
338 // Read flow state machine state.
339 proto::ReadState read_state_
;
341 // The last error encountered by the channel.
342 ChannelError error_state_
;
344 // The current status of the channel.
345 ReadyState ready_state_
;
347 // Task invoked to (re)start the connect loop. Canceled on entry to the
349 base::CancelableClosure connect_loop_callback_
;
351 // Task invoked to send the auth challenge. Canceled when the auth challenge
353 base::CancelableClosure send_auth_challenge_callback_
;
355 // Cast message formatting and parsing layer.
356 scoped_ptr
<CastTransport
> transport_
;
358 // Caller's message read and error handling delegate.
359 scoped_ptr
<CastTransport::Delegate
> delegate_
;
361 // Raw pointer to the auth handshake delegate. Used to get detailed error
363 AuthTransportDelegate
* auth_delegate_
;
365 DISALLOW_COPY_AND_ASSIGN(CastSocketImpl
);
367 } // namespace cast_channel
368 } // namespace core_api
369 } // namespace extensions
371 #endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_