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 |