1 // Copyright 2016 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 REMOTING_HOST_SECURITY_KEY_SECURITY_KEY_SOCKET_H_
6 #define REMOTING_HOST_SECURITY_KEY_SECURITY_KEY_SOCKET_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/callback.h"
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/threading/thread_checker.h"
18 
19 namespace base {
20 class OneShotTimer;
21 }  // namespace base
22 
23 namespace net {
24 class DrainableIOBuffer;
25 class IOBufferWithSize;
26 class StreamSocket;
27 }  // namespace net
28 
29 namespace remoting {
30 
31 // Class that manages reading requests and sending responses. The socket can
32 // only handle receiving one request at a time. It expects to receive no extra
33 // bytes over the wire, which is checked by IsRequestTooLarge method.
34 class SecurityKeySocket {
35  public:
36   SecurityKeySocket(std::unique_ptr<net::StreamSocket> socket,
37                     base::TimeDelta timeout,
38                     base::OnceClosure timeout_callback);
39   ~SecurityKeySocket();
40 
41   // Returns false if the request has not yet completed, or is too large to be
42   // processed. Otherwise, the cached request data is copied into |data_out| and
43   // the internal buffer resets and is ready for the next request.
44   bool GetAndClearRequestData(std::string* data_out);
45 
46   // Sends response data to the socket.
47   void SendResponse(const std::string& data);
48 
49   // Sends an SSH error code to the socket.
50   void SendSshError();
51 
52   // |request_received_callback| is used to notify the caller that request data
53   // has been fully read, and caller is to use GetAndClearRequestData method to
54   // get the request data.
55   void StartReadingRequest(base::OnceClosure request_received_callback);
56 
socket_read_error()57   bool socket_read_error() const { return socket_read_error_; }
58 
59  private:
60   // Called when bytes are written to |socket_|.
61   void OnDataWritten(int result);
62 
63   // Continues writing to |socket_| if needed.
64   void DoWrite();
65 
66   // Called when bytes are read from |socket_|.
67   void OnDataRead(int bytes_read);
68 
69   // Continues to read.
70   void DoRead();
71 
72   // Returns true if the current request is complete.
73   bool IsRequestComplete() const;
74 
75   // Returns true if the stated request size is larger than the allowed maximum.
76   bool IsRequestTooLarge() const;
77 
78   // Returns the stated request length.
79   size_t GetRequestLength() const;
80 
81   // Returns the response length bytes.
82   std::string GetResponseLengthAsBytes(const std::string& response) const;
83 
84   // Resets the socket activity timer.
85   void ResetTimer();
86 
87   // Ensures SecurityKeySocketSocket methods are called on the same thread.
88   base::ThreadChecker thread_checker_;
89 
90   // The socket.
91   std::unique_ptr<net::StreamSocket> socket_;
92 
93   // Invoked when request data has been read.
94   base::OnceClosure request_received_callback_;
95 
96   // Indicates whether the socket is being used to wait for a request.
97   bool waiting_for_request_ = false;
98 
99   // Indicates whether an error was encountered while reading from the socket.
100   bool socket_read_error_ = false;
101 
102   // Request data.
103   std::vector<char> request_data_;
104 
105   scoped_refptr<net::DrainableIOBuffer> write_buffer_;
106 
107   scoped_refptr<net::IOBufferWithSize> read_buffer_;
108 
109   // The activity timer.
110   std::unique_ptr<base::OneShotTimer> timer_;
111 
112   DISALLOW_COPY_AND_ASSIGN(SecurityKeySocket);
113 };
114 
115 }  // namespace remoting
116 
117 #endif  // REMOTING_HOST_SECURITY_KEY_SECURITY_KEY_SOCKET_H_
118