OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/setup/native_messaging_host.h" | 5 #include "remoting/host/setup/native_messaging_host.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/json/json_reader.h" | |
12 #include "base/json/json_writer.h" | |
13 #include "base/location.h" | 11 #include "base/location.h" |
14 #include "base/strings/stringize_macros.h" | 12 #include "base/strings/stringize_macros.h" |
15 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
16 #include "base/values.h" | 14 #include "base/values.h" |
17 #include "net/base/net_util.h" | 15 #include "net/base/net_util.h" |
18 #include "remoting/base/rsa_key_pair.h" | 16 #include "remoting/base/rsa_key_pair.h" |
19 #include "remoting/host/pin_hash.h" | 17 #include "remoting/host/pin_hash.h" |
20 | 18 |
21 namespace { | 19 namespace { |
22 | 20 |
23 // Helper to extract the "config" part of a message as a DictionaryValue. | 21 // Helper to extract the "config" part of a message as a DictionaryValue. |
24 // Returns NULL on failure, and logs an error message. | 22 // Returns NULL on failure, and logs an error message. |
25 scoped_ptr<base::DictionaryValue> ConfigDictionaryFromMessage( | 23 scoped_ptr<base::DictionaryValue> ConfigDictionaryFromMessage( |
26 const base::DictionaryValue& message) { | 24 const base::DictionaryValue& message) { |
27 scoped_ptr<base::DictionaryValue> config_dict; | 25 scoped_ptr<base::DictionaryValue> result; |
28 std::string config_str; | 26 const base::DictionaryValue* config_dict; |
29 if (!message.GetString("config", &config_str)) { | 27 if (message.GetDictionary("config", &config_dict)) { |
30 LOG(ERROR) << "'config' not found."; | 28 result.reset(config_dict->DeepCopy()); |
31 return config_dict.Pass(); | 29 } else { |
| 30 LOG(ERROR) << "'config' dictionary not found"; |
32 } | 31 } |
33 | 32 return result.Pass(); |
34 // TODO(lambroslambrou): Fix the webapp to embed the config dictionary | |
35 // directly into the request, rather than as a serialized JSON string. | |
36 scoped_ptr<base::Value> config( | |
37 base::JSONReader::Read(config_str, base::JSON_ALLOW_TRAILING_COMMAS)); | |
38 if (!config || !config->IsType(base::Value::TYPE_DICTIONARY)) { | |
39 LOG(ERROR) << "Bad config parameter."; | |
40 return config_dict.Pass(); | |
41 } | |
42 config_dict.reset(reinterpret_cast<base::DictionaryValue*>(config.release())); | |
43 return config_dict.Pass(); | |
44 } | 33 } |
45 | 34 |
46 } // namespace | 35 } // namespace |
47 | 36 |
48 namespace remoting { | 37 namespace remoting { |
49 | 38 |
50 NativeMessagingHost::NativeMessagingHost( | 39 NativeMessagingHost::NativeMessagingHost( |
51 base::PlatformFile input, | 40 base::PlatformFile input, |
52 base::PlatformFile output, | 41 base::PlatformFile output, |
53 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 42 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
54 const base::Closure& quit_closure) | 43 const base::Closure& quit_closure) |
55 : caller_task_runner_(caller_task_runner), | 44 : caller_task_runner_(caller_task_runner), |
56 quit_closure_(quit_closure), | 45 quit_closure_(quit_closure), |
57 native_messaging_reader_(input), | 46 native_messaging_reader_(input), |
58 native_messaging_writer_(output), | 47 native_messaging_writer_(output), |
59 daemon_controller_(DaemonController::Create()), | 48 daemon_controller_(DaemonController::Create()), |
60 weak_factory_(this) { | 49 weak_factory_(this) { |
61 weak_ptr_ = weak_factory_.GetWeakPtr(); | 50 weak_ptr_ = weak_factory_.GetWeakPtr(); |
62 } | 51 } |
63 | 52 |
64 NativeMessagingHost::~NativeMessagingHost() { | 53 NativeMessagingHost::~NativeMessagingHost() {} |
65 } | |
66 | 54 |
67 void NativeMessagingHost::Start() { | 55 void NativeMessagingHost::Start() { |
68 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 56 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
69 | 57 |
70 native_messaging_reader_.Start( | 58 native_messaging_reader_.Start( |
71 base::Bind(&NativeMessagingHost::ProcessMessage, weak_ptr_), | 59 base::Bind(&NativeMessagingHost::ProcessMessage, weak_ptr_), |
72 base::Bind(&NativeMessagingHost::Shutdown, weak_ptr_)); | 60 base::Bind(&NativeMessagingHost::Shutdown, weak_ptr_)); |
73 } | 61 } |
74 | 62 |
75 void NativeMessagingHost::Shutdown() { | 63 void NativeMessagingHost::Shutdown() { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 daemon_controller_->UpdateConfig( | 179 daemon_controller_->UpdateConfig( |
192 config_dict.Pass(), | 180 config_dict.Pass(), |
193 base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), | 181 base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), |
194 base::Passed(&response))); | 182 base::Passed(&response))); |
195 return true; | 183 return true; |
196 } | 184 } |
197 | 185 |
198 bool NativeMessagingHost::ProcessGetDaemonConfig( | 186 bool NativeMessagingHost::ProcessGetDaemonConfig( |
199 const base::DictionaryValue& message, | 187 const base::DictionaryValue& message, |
200 scoped_ptr<base::DictionaryValue> response) { | 188 scoped_ptr<base::DictionaryValue> response) { |
201 daemon_controller_->GetConfig(base::Bind( | 189 daemon_controller_->GetConfig( |
202 &NativeMessagingHost::SendConfigResponse, | 190 base::Bind(&NativeMessagingHost::SendConfigResponse, |
203 base::Unretained(this), base::Passed(&response))); | 191 base::Unretained(this), base::Passed(&response))); |
204 return true; | 192 return true; |
205 } | 193 } |
206 | 194 |
207 bool NativeMessagingHost::ProcessGetUsageStatsConsent( | 195 bool NativeMessagingHost::ProcessGetUsageStatsConsent( |
208 const base::DictionaryValue& message, | 196 const base::DictionaryValue& message, |
209 scoped_ptr<base::DictionaryValue> response) { | 197 scoped_ptr<base::DictionaryValue> response) { |
210 daemon_controller_->GetUsageStatsConsent(base::Bind( | 198 daemon_controller_->GetUsageStatsConsent( |
211 &NativeMessagingHost::SendUsageStatsConsentResponse, | 199 base::Bind(&NativeMessagingHost::SendUsageStatsConsentResponse, |
212 base::Unretained(this), base::Passed(&response))); | 200 base::Unretained(this), base::Passed(&response))); |
213 return true; | 201 return true; |
214 } | 202 } |
215 | 203 |
216 bool NativeMessagingHost::ProcessStartDaemon( | 204 bool NativeMessagingHost::ProcessStartDaemon( |
217 const base::DictionaryValue& message, | 205 const base::DictionaryValue& message, |
218 scoped_ptr<base::DictionaryValue> response) { | 206 scoped_ptr<base::DictionaryValue> response) { |
219 bool consent; | 207 bool consent; |
220 if (!message.GetBoolean("consent", &consent)) { | 208 if (!message.GetBoolean("consent", &consent)) { |
221 LOG(ERROR) << "'consent' not found."; | 209 LOG(ERROR) << "'consent' not found."; |
222 return false; | 210 return false; |
223 } | 211 } |
224 | 212 |
225 scoped_ptr<base::DictionaryValue> config_dict = | 213 scoped_ptr<base::DictionaryValue> config_dict = |
226 ConfigDictionaryFromMessage(message); | 214 ConfigDictionaryFromMessage(message); |
227 if (!config_dict) | 215 if (!config_dict) |
228 return false; | 216 return false; |
229 | 217 |
230 daemon_controller_->SetConfigAndStart( | 218 daemon_controller_->SetConfigAndStart( |
231 config_dict.Pass(), consent, | 219 config_dict.Pass(), consent, |
232 base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), | 220 base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), |
233 base::Passed(&response))); | 221 base::Passed(&response))); |
234 return true; | 222 return true; |
235 } | 223 } |
236 | 224 |
237 bool NativeMessagingHost::ProcessStopDaemon( | 225 bool NativeMessagingHost::ProcessStopDaemon( |
238 const base::DictionaryValue& message, | 226 const base::DictionaryValue& message, |
239 scoped_ptr<base::DictionaryValue> response) { | 227 scoped_ptr<base::DictionaryValue> response) { |
240 daemon_controller_->Stop(base::Bind( | 228 daemon_controller_->Stop( |
241 &NativeMessagingHost::SendAsyncResult, base::Unretained(this), | 229 base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), |
242 base::Passed(&response))); | 230 base::Passed(&response))); |
243 return true; | 231 return true; |
244 } | 232 } |
245 | 233 |
246 bool NativeMessagingHost::ProcessGetDaemonState( | 234 bool NativeMessagingHost::ProcessGetDaemonState( |
247 const base::DictionaryValue& message, | 235 const base::DictionaryValue& message, |
248 scoped_ptr<base::DictionaryValue> response) { | 236 scoped_ptr<base::DictionaryValue> response) { |
249 // TODO(lambroslambrou): Send the state as a string instead of an integer, | 237 // TODO(lambroslambrou): Send the state as a string instead of an integer, |
250 // and update the web-app accordingly. | 238 // and update the web-app accordingly. |
251 DaemonController::State state = daemon_controller_->GetState(); | 239 DaemonController::State state = daemon_controller_->GetState(); |
252 response->SetInteger("state", state); | 240 response->SetInteger("state", state); |
253 SendResponse(response.Pass()); | 241 SendResponse(response.Pass()); |
254 return true; | 242 return true; |
255 } | 243 } |
256 | 244 |
257 void NativeMessagingHost::SendResponse( | 245 void NativeMessagingHost::SendResponse( |
258 scoped_ptr<base::DictionaryValue> response) { | 246 scoped_ptr<base::DictionaryValue> response) { |
259 if (!caller_task_runner_->BelongsToCurrentThread()) { | 247 if (!caller_task_runner_->BelongsToCurrentThread()) { |
260 caller_task_runner_->PostTask(FROM_HERE, base::Bind( | 248 caller_task_runner_->PostTask( |
261 &NativeMessagingHost::SendResponse, weak_ptr_, | 249 FROM_HERE, base::Bind(&NativeMessagingHost::SendResponse, weak_ptr_, |
262 base::Passed(&response))); | 250 base::Passed(&response))); |
263 return; | 251 return; |
264 } | 252 } |
265 | 253 |
266 if (!native_messaging_writer_.WriteMessage(*response)) | 254 if (!native_messaging_writer_.WriteMessage(*response)) |
267 Shutdown(); | 255 Shutdown(); |
268 } | 256 } |
269 | 257 |
270 void NativeMessagingHost::SendConfigResponse( | 258 void NativeMessagingHost::SendConfigResponse( |
271 scoped_ptr<base::DictionaryValue> response, | 259 scoped_ptr<base::DictionaryValue> response, |
272 scoped_ptr<base::DictionaryValue> config) { | 260 scoped_ptr<base::DictionaryValue> config) { |
273 // TODO(lambroslambrou): Fix the web-app to accept the config dictionary | 261 response->Set("config", config.release()); |
274 // directly embedded in the response, rather than as serialized JSON. See | |
275 // http://crbug.com/232135. | |
276 std::string config_json; | |
277 base::JSONWriter::Write(config.get(), &config_json); | |
278 response->SetString("config", config_json); | |
279 SendResponse(response.Pass()); | 262 SendResponse(response.Pass()); |
280 } | 263 } |
281 | 264 |
282 void NativeMessagingHost::SendUsageStatsConsentResponse( | 265 void NativeMessagingHost::SendUsageStatsConsentResponse( |
283 scoped_ptr<base::DictionaryValue> response, | 266 scoped_ptr<base::DictionaryValue> response, |
284 bool supported, | 267 bool supported, |
285 bool allowed, | 268 bool allowed, |
286 bool set_by_policy) { | 269 bool set_by_policy) { |
287 response->SetBoolean("supported", supported); | 270 response->SetBoolean("supported", supported); |
288 response->SetBoolean("allowed", allowed); | 271 response->SetBoolean("allowed", allowed); |
289 response->SetBoolean("set_by_policy", set_by_policy); | 272 response->SetBoolean("set_by_policy", set_by_policy); |
290 SendResponse(response.Pass()); | 273 SendResponse(response.Pass()); |
291 } | 274 } |
292 | 275 |
293 void NativeMessagingHost::SendAsyncResult( | 276 void NativeMessagingHost::SendAsyncResult( |
294 scoped_ptr<base::DictionaryValue> response, | 277 scoped_ptr<base::DictionaryValue> response, |
295 DaemonController::AsyncResult result) { | 278 DaemonController::AsyncResult result) { |
296 // TODO(lambroslambrou): Send the result as a string instead of an integer, | 279 // TODO(lambroslambrou): Send the result as a string instead of an integer, |
297 // and update the web-app accordingly. See http://crbug.com/232135. | 280 // and update the web-app accordingly. See http://crbug.com/232135. |
298 response->SetInteger("result", result); | 281 response->SetInteger("result", result); |
299 SendResponse(response.Pass()); | 282 SendResponse(response.Pass()); |
300 } | 283 } |
301 | 284 |
302 } // namespace remoting | 285 } // namespace remoting |
OLD | NEW |