OLD | NEW |
| (Empty) |
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 #include "remoting/host/security_key/remote_security_key_message_handler.h" | |
6 | |
7 #include <cstdint> | |
8 #include <string> | |
9 #include <utility> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/callback.h" | |
13 #include "base/callback_helpers.h" | |
14 #include "remoting/host/security_key/remote_security_key_ipc_client.h" | |
15 #include "remoting/host/security_key/remote_security_key_ipc_constants.h" | |
16 #include "remoting/host/security_key/remote_security_key_message_reader_impl.h" | |
17 #include "remoting/host/security_key/remote_security_key_message_writer_impl.h" | |
18 | |
19 namespace remoting { | |
20 | |
21 RemoteSecurityKeyMessageHandler::RemoteSecurityKeyMessageHandler() {} | |
22 | |
23 RemoteSecurityKeyMessageHandler::~RemoteSecurityKeyMessageHandler() {} | |
24 | |
25 void RemoteSecurityKeyMessageHandler::Start( | |
26 base::File message_read_stream, | |
27 base::File message_write_stream, | |
28 std::unique_ptr<RemoteSecurityKeyIpcClient> ipc_client, | |
29 const base::Closure& error_callback) { | |
30 DCHECK(thread_checker_.CalledOnValidThread()); | |
31 DCHECK(message_read_stream.IsValid()); | |
32 DCHECK(message_write_stream.IsValid()); | |
33 DCHECK(ipc_client); | |
34 DCHECK(!error_callback.is_null()); | |
35 DCHECK(error_callback_.is_null()); | |
36 | |
37 if (!reader_) { | |
38 reader_.reset( | |
39 new RemoteSecurityKeyMessageReaderImpl(std::move(message_read_stream))); | |
40 } | |
41 | |
42 if (!writer_) { | |
43 writer_.reset(new RemoteSecurityKeyMessageWriterImpl( | |
44 std::move(message_write_stream))); | |
45 } | |
46 | |
47 ipc_client_ = std::move(ipc_client); | |
48 error_callback_ = error_callback; | |
49 | |
50 reader_->Start( | |
51 base::Bind( | |
52 &RemoteSecurityKeyMessageHandler::ProcessRemoteSecurityKeyMessage, | |
53 base::Unretained(this)), | |
54 base::Bind(&RemoteSecurityKeyMessageHandler::OnError, | |
55 base::Unretained(this))); | |
56 } | |
57 | |
58 void RemoteSecurityKeyMessageHandler::SetRemoteSecurityKeyMessageReaderForTest( | |
59 std::unique_ptr<RemoteSecurityKeyMessageReader> reader) { | |
60 DCHECK(!reader_); | |
61 reader_ = std::move(reader); | |
62 } | |
63 | |
64 void RemoteSecurityKeyMessageHandler::SetRemoteSecurityKeyMessageWriterForTest( | |
65 std::unique_ptr<RemoteSecurityKeyMessageWriter> writer) { | |
66 DCHECK(!writer_); | |
67 writer_ = std::move(writer); | |
68 } | |
69 | |
70 void RemoteSecurityKeyMessageHandler::ProcessRemoteSecurityKeyMessage( | |
71 std::unique_ptr<SecurityKeyMessage> message) { | |
72 DCHECK(thread_checker_.CalledOnValidThread()); | |
73 | |
74 RemoteSecurityKeyMessageType message_type = message->type(); | |
75 if (message_type == RemoteSecurityKeyMessageType::CONNECT) { | |
76 HandleConnectRequest(message->payload()); | |
77 } else if (message_type == RemoteSecurityKeyMessageType::REQUEST) { | |
78 HandleSecurityKeyRequest(message->payload()); | |
79 } else { | |
80 LOG(ERROR) << "Unknown message type: " | |
81 << static_cast<uint8_t>(message_type); | |
82 SendMessage(RemoteSecurityKeyMessageType::UNKNOWN_COMMAND); | |
83 } | |
84 } | |
85 | |
86 void RemoteSecurityKeyMessageHandler::HandleIpcConnectionChange( | |
87 bool connection_established) { | |
88 DCHECK(thread_checker_.CalledOnValidThread()); | |
89 if (connection_established) { | |
90 SendMessageWithPayload(RemoteSecurityKeyMessageType::CONNECT_RESPONSE, | |
91 std::string(1, kConnectResponseActiveSession)); | |
92 } else { | |
93 SendMessageWithPayload( | |
94 RemoteSecurityKeyMessageType::CONNECT_ERROR, | |
95 "Unknown error occurred while establishing connection."); | |
96 } | |
97 } | |
98 | |
99 void RemoteSecurityKeyMessageHandler::HandleSecurityKeyResponse( | |
100 const std::string& response_data) { | |
101 if (response_data.compare(kRemoteSecurityKeyConnectionError) == 0) { | |
102 SendMessageWithPayload(RemoteSecurityKeyMessageType::REQUEST_ERROR, | |
103 "An error occurred during the request."); | |
104 return; | |
105 } | |
106 | |
107 if (response_data.empty()) { | |
108 SendMessageWithPayload(RemoteSecurityKeyMessageType::REQUEST_ERROR, | |
109 "Invalid client response received."); | |
110 return; | |
111 } | |
112 | |
113 SendMessageWithPayload(RemoteSecurityKeyMessageType::REQUEST_RESPONSE, | |
114 response_data); | |
115 } | |
116 | |
117 void RemoteSecurityKeyMessageHandler::HandleConnectRequest( | |
118 const std::string& message_payload) { | |
119 DCHECK(thread_checker_.CalledOnValidThread()); | |
120 if (!message_payload.empty()) { | |
121 SendMessageWithPayload(RemoteSecurityKeyMessageType::CONNECT_ERROR, | |
122 "Unexpected payload data received."); | |
123 return; | |
124 } | |
125 | |
126 if (ipc_client_->WaitForSecurityKeyIpcServerChannel()) { | |
127 // If we find an IPC server, then attempt to establish a connection. | |
128 ipc_client_->EstablishIpcConnection( | |
129 base::Bind(&RemoteSecurityKeyMessageHandler::HandleIpcConnectionChange, | |
130 base::Unretained(this), true), | |
131 base::Bind(&RemoteSecurityKeyMessageHandler::HandleIpcConnectionChange, | |
132 base::Unretained(this), false)); | |
133 } else { | |
134 SendMessageWithPayload(RemoteSecurityKeyMessageType::CONNECT_RESPONSE, | |
135 std::string(1, kConnectResponseNoSession)); | |
136 } | |
137 } | |
138 | |
139 void RemoteSecurityKeyMessageHandler::HandleSecurityKeyRequest( | |
140 const std::string& message_payload) { | |
141 DCHECK(thread_checker_.CalledOnValidThread()); | |
142 if (message_payload.empty()) { | |
143 SendMessageWithPayload(RemoteSecurityKeyMessageType::REQUEST_ERROR, | |
144 "Request sent without request data."); | |
145 return; | |
146 } | |
147 | |
148 if (!ipc_client_->SendSecurityKeyRequest( | |
149 message_payload, | |
150 base::Bind( | |
151 &RemoteSecurityKeyMessageHandler::HandleSecurityKeyResponse, | |
152 base::Unretained(this)))) { | |
153 SendMessageWithPayload(RemoteSecurityKeyMessageType::REQUEST_ERROR, | |
154 "Failed to send request data."); | |
155 } | |
156 } | |
157 | |
158 void RemoteSecurityKeyMessageHandler::SendMessage( | |
159 RemoteSecurityKeyMessageType message_type) { | |
160 if (!writer_->WriteMessage(message_type)) { | |
161 OnError(); | |
162 } | |
163 } | |
164 | |
165 void RemoteSecurityKeyMessageHandler::SendMessageWithPayload( | |
166 RemoteSecurityKeyMessageType message_type, | |
167 const std::string& message_payload) { | |
168 if (!writer_->WriteMessageWithPayload(message_type, message_payload)) { | |
169 OnError(); | |
170 } | |
171 } | |
172 | |
173 void RemoteSecurityKeyMessageHandler::OnError() { | |
174 DCHECK(thread_checker_.CalledOnValidThread()); | |
175 ipc_client_.reset(); | |
176 writer_.reset(); | |
177 reader_.reset(); | |
178 | |
179 if (!error_callback_.is_null()) { | |
180 base::ResetAndReturn(&error_callback_).Run(); | |
181 } | |
182 } | |
183 | |
184 } // namespace remoting | |
OLD | NEW |