OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/security_key/gnubby_extension_session.h" | 5 #include "remoting/host/security_key/security_key_extension_session.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "remoting/base/logging.h" | 13 #include "remoting/base/logging.h" |
14 #include "remoting/host/client_session_details.h" | 14 #include "remoting/host/client_session_details.h" |
15 #include "remoting/host/security_key/gnubby_auth_handler.h" | 15 #include "remoting/host/security_key/security_key_auth_handler.h" |
16 #include "remoting/proto/control.pb.h" | 16 #include "remoting/proto/control.pb.h" |
17 #include "remoting/protocol/client_stub.h" | 17 #include "remoting/protocol/client_stub.h" |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 // Used as the type attribute of all Security Key protocol::ExtensionMessages. | 21 // Used as the type attribute of all Security Key protocol::ExtensionMessages. |
22 const char kExtensionMessageType[] = "gnubby-auth"; | 22 const char kExtensionMessageType[] = "gnubby-auth"; |
23 | 23 |
24 // Gnubby extension message data members. | 24 // SecurityKey extension message data members. |
25 const char kConnectionId[] = "connectionId"; | 25 const char kConnectionId[] = "connectionId"; |
26 const char kControlMessage[] = "control"; | 26 const char kControlMessage[] = "control"; |
27 const char kControlOption[] = "option"; | 27 const char kControlOption[] = "option"; |
28 const char kDataMessage[] = "data"; | 28 const char kDataMessage[] = "data"; |
29 const char kDataPayload[] = "data"; | 29 const char kDataPayload[] = "data"; |
30 const char kErrorMessage[] = "error"; | 30 const char kErrorMessage[] = "error"; |
31 const char kGnubbyAuthV1[] = "auth-v1"; | 31 const char kSecurityKeyAuthV1[] = "auth-v1"; |
32 const char kMessageType[] = "type"; | 32 const char kMessageType[] = "type"; |
33 | 33 |
34 // Returns the command code (the first byte of the data) if it exists, or -1 if | 34 // Returns the command code (the first byte of the data) if it exists, or -1 if |
35 // the data is empty. | 35 // the data is empty. |
36 unsigned int GetCommandCode(const std::string& data) { | 36 unsigned int GetCommandCode(const std::string& data) { |
37 return data.empty() ? -1 : static_cast<unsigned int>(data[0]); | 37 return data.empty() ? -1 : static_cast<unsigned int>(data[0]); |
38 } | 38 } |
39 | 39 |
40 // Creates a string of byte data from a ListValue of numbers. Returns true if | 40 // Creates a string of byte data from a ListValue of numbers. Returns true if |
41 // all of the list elements are numbers. | 41 // all of the list elements are numbers. |
(...skipping 11 matching lines...) Expand all Loading... |
53 out->push_back(static_cast<char>(value)); | 53 out->push_back(static_cast<char>(value)); |
54 } | 54 } |
55 } | 55 } |
56 return true; | 56 return true; |
57 } | 57 } |
58 | 58 |
59 } // namespace | 59 } // namespace |
60 | 60 |
61 namespace remoting { | 61 namespace remoting { |
62 | 62 |
63 GnubbyExtensionSession::GnubbyExtensionSession( | 63 SecurityKeyExtensionSession::SecurityKeyExtensionSession( |
64 ClientSessionDetails* client_session_details, | 64 ClientSessionDetails* client_session_details, |
65 protocol::ClientStub* client_stub) | 65 protocol::ClientStub* client_stub) |
66 : client_stub_(client_stub) { | 66 : client_stub_(client_stub) { |
67 DCHECK(client_stub_); | 67 DCHECK(client_stub_); |
68 | 68 |
69 gnubby_auth_handler_ = remoting::GnubbyAuthHandler::Create( | 69 security_key_auth_handler_ = remoting::SecurityKeyAuthHandler::Create( |
70 client_session_details, | 70 client_session_details, |
71 base::Bind(&GnubbyExtensionSession::SendMessageToClient, | 71 base::Bind(&SecurityKeyExtensionSession::SendMessageToClient, |
72 base::Unretained(this))); | 72 base::Unretained(this))); |
73 } | 73 } |
74 | 74 |
75 GnubbyExtensionSession::~GnubbyExtensionSession() {} | 75 SecurityKeyExtensionSession::~SecurityKeyExtensionSession() {} |
76 | 76 |
77 // Returns true if the |message| is a Security Key ExtensionMessage. | 77 // Returns true if the |message| is a Security Key ExtensionMessage. |
78 // This is done so the host does not pass |message| to other HostExtensions. | 78 // This is done so the host does not pass |message| to other HostExtensions. |
79 // TODO(joedow): Use |client_session_details| to disconnect the session if we | 79 // TODO(joedow): Use |client_session_details| to disconnect the session if we |
80 // receive an invalid extension message. | 80 // receive an invalid extension message. |
81 bool GnubbyExtensionSession::OnExtensionMessage( | 81 bool SecurityKeyExtensionSession::OnExtensionMessage( |
82 ClientSessionDetails* client_session_details, | 82 ClientSessionDetails* client_session_details, |
83 protocol::ClientStub* client_stub, | 83 protocol::ClientStub* client_stub, |
84 const protocol::ExtensionMessage& message) { | 84 const protocol::ExtensionMessage& message) { |
85 DCHECK(thread_checker_.CalledOnValidThread()); | 85 DCHECK(thread_checker_.CalledOnValidThread()); |
86 | 86 |
87 if (message.type() != kExtensionMessageType) { | 87 if (message.type() != kExtensionMessageType) { |
88 return false; | 88 return false; |
89 } | 89 } |
90 | 90 |
91 std::unique_ptr<base::Value> value = base::JSONReader::Read(message.data()); | 91 std::unique_ptr<base::Value> value = base::JSONReader::Read(message.data()); |
(...skipping 15 matching lines...) Expand all Loading... |
107 ProcessDataMessage(client_message); | 107 ProcessDataMessage(client_message); |
108 } else if (type == kErrorMessage) { | 108 } else if (type == kErrorMessage) { |
109 ProcessErrorMessage(client_message); | 109 ProcessErrorMessage(client_message); |
110 } else { | 110 } else { |
111 VLOG(2) << "Unknown gnubby-auth message type: " << type; | 111 VLOG(2) << "Unknown gnubby-auth message type: " << type; |
112 } | 112 } |
113 | 113 |
114 return true; | 114 return true; |
115 } | 115 } |
116 | 116 |
117 void GnubbyExtensionSession::ProcessControlMessage( | 117 void SecurityKeyExtensionSession::ProcessControlMessage( |
118 base::DictionaryValue* message_data) const { | 118 base::DictionaryValue* message_data) const { |
119 std::string option; | 119 std::string option; |
120 if (!message_data->GetString(kControlOption, &option)) { | 120 if (!message_data->GetString(kControlOption, &option)) { |
121 LOG(WARNING) << "Could not extract control option from message."; | 121 LOG(WARNING) << "Could not extract control option from message."; |
122 return; | 122 return; |
123 } | 123 } |
124 | 124 |
125 if (option == kGnubbyAuthV1) { | 125 if (option == kSecurityKeyAuthV1) { |
126 gnubby_auth_handler_->CreateGnubbyConnection(); | 126 security_key_auth_handler_->CreateSecurityKeyConnection(); |
127 } else { | 127 } else { |
128 VLOG(2) << "Invalid gnubby-auth control option: " << option; | 128 VLOG(2) << "Invalid gnubby-auth control option: " << option; |
129 } | 129 } |
130 } | 130 } |
131 | 131 |
132 void GnubbyExtensionSession::ProcessDataMessage( | 132 void SecurityKeyExtensionSession::ProcessDataMessage( |
133 base::DictionaryValue* message_data) const { | 133 base::DictionaryValue* message_data) const { |
134 int connection_id; | 134 int connection_id; |
135 if (!message_data->GetInteger(kConnectionId, &connection_id)) { | 135 if (!message_data->GetInteger(kConnectionId, &connection_id)) { |
136 LOG(WARNING) << "Could not extract connection id from message."; | 136 LOG(WARNING) << "Could not extract connection id from message."; |
137 return; | 137 return; |
138 } | 138 } |
139 | 139 |
140 if (!gnubby_auth_handler_->IsValidConnectionId(connection_id)) { | 140 if (!security_key_auth_handler_->IsValidConnectionId(connection_id)) { |
141 LOG(WARNING) << "Unknown gnubby-auth data connection: '" << connection_id | 141 LOG(WARNING) << "Unknown gnubby-auth data connection: '" << connection_id |
142 << "'"; | 142 << "'"; |
143 return; | 143 return; |
144 } | 144 } |
145 | 145 |
146 base::ListValue* bytes; | 146 base::ListValue* bytes; |
147 std::string response; | 147 std::string response; |
148 if (message_data->GetList(kDataPayload, &bytes) && | 148 if (message_data->GetList(kDataPayload, &bytes) && |
149 ConvertListValueToString(bytes, &response)) { | 149 ConvertListValueToString(bytes, &response)) { |
150 HOST_LOG << "Sending gnubby response: " << GetCommandCode(response); | 150 HOST_LOG << "Sending security key response: " << GetCommandCode(response); |
151 gnubby_auth_handler_->SendClientResponse(connection_id, response); | 151 security_key_auth_handler_->SendClientResponse(connection_id, response); |
152 } else { | 152 } else { |
153 LOG(WARNING) << "Could not extract response data from message."; | 153 LOG(WARNING) << "Could not extract response data from message."; |
154 gnubby_auth_handler_->SendErrorAndCloseConnection(connection_id); | 154 security_key_auth_handler_->SendErrorAndCloseConnection(connection_id); |
155 return; | 155 return; |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 void GnubbyExtensionSession::ProcessErrorMessage( | 159 void SecurityKeyExtensionSession::ProcessErrorMessage( |
160 base::DictionaryValue* message_data) const { | 160 base::DictionaryValue* message_data) const { |
161 int connection_id; | 161 int connection_id; |
162 if (!message_data->GetInteger(kConnectionId, &connection_id)) { | 162 if (!message_data->GetInteger(kConnectionId, &connection_id)) { |
163 LOG(WARNING) << "Could not extract connection id from message."; | 163 LOG(WARNING) << "Could not extract connection id from message."; |
164 return; | 164 return; |
165 } | 165 } |
166 | 166 |
167 if (gnubby_auth_handler_->IsValidConnectionId(connection_id)) { | 167 if (security_key_auth_handler_->IsValidConnectionId(connection_id)) { |
168 HOST_LOG << "Sending gnubby error"; | 168 HOST_LOG << "Sending security key error"; |
169 gnubby_auth_handler_->SendErrorAndCloseConnection(connection_id); | 169 security_key_auth_handler_->SendErrorAndCloseConnection(connection_id); |
170 } else { | 170 } else { |
171 LOG(WARNING) << "Unknown gnubby-auth data connection: '" << connection_id | 171 LOG(WARNING) << "Unknown gnubby-auth data connection: '" << connection_id |
172 << "'"; | 172 << "'"; |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 void GnubbyExtensionSession::SendMessageToClient( | 176 void SecurityKeyExtensionSession::SendMessageToClient( |
177 int connection_id, | 177 int connection_id, |
178 const std::string& data) const { | 178 const std::string& data) const { |
179 DCHECK(thread_checker_.CalledOnValidThread()); | 179 DCHECK(thread_checker_.CalledOnValidThread()); |
180 DCHECK(client_stub_); | 180 DCHECK(client_stub_); |
181 | 181 |
182 base::DictionaryValue request; | 182 base::DictionaryValue request; |
183 request.SetString(kMessageType, kDataMessage); | 183 request.SetString(kMessageType, kDataMessage); |
184 request.SetInteger(kConnectionId, connection_id); | 184 request.SetInteger(kConnectionId, connection_id); |
185 | 185 |
186 std::unique_ptr<base::ListValue> bytes(new base::ListValue()); | 186 std::unique_ptr<base::ListValue> bytes(new base::ListValue()); |
187 for (std::string::const_iterator i = data.begin(); i != data.end(); ++i) { | 187 for (std::string::const_iterator i = data.begin(); i != data.end(); ++i) { |
188 bytes->AppendInteger(static_cast<unsigned char>(*i)); | 188 bytes->AppendInteger(static_cast<unsigned char>(*i)); |
189 } | 189 } |
190 request.Set(kDataPayload, bytes.release()); | 190 request.Set(kDataPayload, bytes.release()); |
191 | 191 |
192 std::string request_json; | 192 std::string request_json; |
193 CHECK(base::JSONWriter::Write(request, &request_json)); | 193 CHECK(base::JSONWriter::Write(request, &request_json)); |
194 | 194 |
195 protocol::ExtensionMessage message; | 195 protocol::ExtensionMessage message; |
196 message.set_type(kExtensionMessageType); | 196 message.set_type(kExtensionMessageType); |
197 message.set_data(request_json); | 197 message.set_data(request_json); |
198 | 198 |
199 client_stub_->DeliverHostMessage(message); | 199 client_stub_->DeliverHostMessage(message); |
200 } | 200 } |
201 | 201 |
202 void GnubbyExtensionSession::SetGnubbyAuthHandlerForTesting( | 202 void SecurityKeyExtensionSession::SetSecurityKeyAuthHandlerForTesting( |
203 std::unique_ptr<GnubbyAuthHandler> gnubby_auth_handler) { | 203 std::unique_ptr<SecurityKeyAuthHandler> security_key_auth_handler) { |
204 DCHECK(gnubby_auth_handler); | 204 DCHECK(security_key_auth_handler); |
205 | 205 |
206 gnubby_auth_handler_ = std::move(gnubby_auth_handler); | 206 security_key_auth_handler_ = std::move(security_key_auth_handler); |
207 gnubby_auth_handler_->SetSendMessageCallback(base::Bind( | 207 security_key_auth_handler_->SetSendMessageCallback( |
208 &GnubbyExtensionSession::SendMessageToClient, base::Unretained(this))); | 208 base::Bind(&SecurityKeyExtensionSession::SendMessageToClient, |
| 209 base::Unretained(this))); |
209 } | 210 } |
210 | 211 |
211 } // namespace remoting | 212 } // namespace remoting |
OLD | NEW |