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/it2me/it2me_native_messaging_host.h" | 5 #include "remoting/host/it2me/it2me_native_messaging_host.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
14 #include "base/json/json_reader.h" | 14 #include "base/json/json_reader.h" |
15 #include "base/json/json_writer.h" | 15 #include "base/json/json_writer.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
18 #include "base/strings/stringize_macros.h" | 18 #include "base/strings/stringize_macros.h" |
19 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
21 #include "base/values.h" | 21 #include "base/values.h" |
22 #include "build/build_config.h" | 22 #include "build/build_config.h" |
23 #include "components/policy/policy_constants.h" | 23 #include "components/policy/policy_constants.h" |
24 #include "net/base/url_util.h" | 24 #include "net/base/url_util.h" |
25 #include "net/socket/client_socket_factory.h" | |
25 #include "net/url_request/url_request_context_getter.h" | 26 #include "net/url_request/url_request_context_getter.h" |
26 #include "remoting/base/auto_thread_task_runner.h" | 27 #include "remoting/base/auto_thread_task_runner.h" |
27 #include "remoting/host/chromoting_host_context.h" | 28 #include "remoting/host/chromoting_host_context.h" |
28 #include "remoting/host/host_exit_codes.h" | 29 #include "remoting/host/host_exit_codes.h" |
29 #include "remoting/host/policy_watcher.h" | 30 #include "remoting/host/policy_watcher.h" |
30 #include "remoting/host/service_urls.h" | 31 #include "remoting/host/service_urls.h" |
31 #include "remoting/protocol/name_value_map.h" | 32 #include "remoting/protocol/name_value_map.h" |
33 #include "remoting/signaling/delegating_signal_strategy.h" | |
32 | 34 |
33 #if defined(OS_WIN) | 35 #if defined(OS_WIN) |
34 #include "base/command_line.h" | 36 #include "base/command_line.h" |
35 #include "base/files/file_path.h" | 37 #include "base/files/file_path.h" |
36 | 38 |
37 #include "remoting/host/win/elevated_native_messaging_host.h" | 39 #include "remoting/host/win/elevated_native_messaging_host.h" |
38 #endif // defined(OS_WIN) | 40 #endif // defined(OS_WIN) |
39 | 41 |
40 namespace remoting { | 42 namespace remoting { |
41 | 43 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
77 } | 79 } |
78 | 80 |
79 } // namespace | 81 } // namespace |
80 | 82 |
81 It2MeNativeMessagingHost::It2MeNativeMessagingHost( | 83 It2MeNativeMessagingHost::It2MeNativeMessagingHost( |
82 bool needs_elevation, | 84 bool needs_elevation, |
83 policy::PolicyService* policy_service, | 85 policy::PolicyService* policy_service, |
84 std::unique_ptr<ChromotingHostContext> context, | 86 std::unique_ptr<ChromotingHostContext> context, |
85 std::unique_ptr<It2MeHostFactory> factory) | 87 std::unique_ptr<It2MeHostFactory> factory) |
86 : needs_elevation_(needs_elevation), | 88 : needs_elevation_(needs_elevation), |
89 delegating_signal_strategy_(nullptr), | |
Sergey Ulanov
2016/10/05 21:49:06
please put this initializer in the class declarati
kelvinp
2016/10/06 00:43:05
Done.
| |
87 host_context_(std::move(context)), | 90 host_context_(std::move(context)), |
88 factory_(std::move(factory)), | 91 factory_(std::move(factory)), |
89 policy_service_(policy_service), | 92 policy_service_(policy_service), |
90 policy_watcher_(PolicyWatcher::Create(policy_service_, | 93 policy_watcher_(PolicyWatcher::Create(policy_service_, |
91 host_context_->file_task_runner())), | 94 host_context_->file_task_runner())), |
92 weak_factory_(this) { | 95 weak_factory_(this) { |
93 weak_ptr_ = weak_factory_.GetWeakPtr(); | 96 weak_ptr_ = weak_factory_.GetWeakPtr(); |
94 | 97 |
95 const ServiceUrls* service_urls = ServiceUrls::GetInstance(); | 98 const ServiceUrls* service_urls = ServiceUrls::GetInstance(); |
96 const bool xmpp_server_valid = | 99 const bool xmpp_server_valid = |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
148 } | 151 } |
149 | 152 |
150 response->SetString("type", type + "Response"); | 153 response->SetString("type", type + "Response"); |
151 | 154 |
152 if (type == "hello") { | 155 if (type == "hello") { |
153 ProcessHello(std::move(message_dict), std::move(response)); | 156 ProcessHello(std::move(message_dict), std::move(response)); |
154 } else if (type == "connect") { | 157 } else if (type == "connect") { |
155 ProcessConnect(std::move(message_dict), std::move(response)); | 158 ProcessConnect(std::move(message_dict), std::move(response)); |
156 } else if (type == "disconnect") { | 159 } else if (type == "disconnect") { |
157 ProcessDisconnect(std::move(message_dict), std::move(response)); | 160 ProcessDisconnect(std::move(message_dict), std::move(response)); |
161 } else if (type == "incomingIq") { | |
162 ProcessIncomingIq(std::move(message_dict), std::move(response)); | |
158 } else { | 163 } else { |
159 SendErrorAndExit(std::move(response), "Unsupported request type: " + type); | 164 SendErrorAndExit(std::move(response), "Unsupported request type: " + type); |
160 } | 165 } |
161 } | 166 } |
162 | 167 |
163 void It2MeNativeMessagingHost::Start(Client* client) { | 168 void It2MeNativeMessagingHost::Start(Client* client) { |
164 DCHECK(task_runner()->BelongsToCurrentThread()); | 169 DCHECK(task_runner()->BelongsToCurrentThread()); |
165 client_ = client; | 170 client_ = client; |
166 #if !defined(OS_CHROMEOS) | 171 #if !defined(OS_CHROMEOS) |
167 log_message_handler_.reset( | 172 log_message_handler_.reset( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 } | 224 } |
220 return; | 225 return; |
221 } | 226 } |
222 | 227 |
223 if (it2me_host_.get()) { | 228 if (it2me_host_.get()) { |
224 SendErrorAndExit(std::move(response), | 229 SendErrorAndExit(std::move(response), |
225 "Connect can be called only when disconnected."); | 230 "Connect can be called only when disconnected."); |
226 return; | 231 return; |
227 } | 232 } |
228 | 233 |
229 XmppSignalStrategy::XmppServerConfig xmpp_config = xmpp_server_config_; | 234 XmppSignalStrategy::XmppServerConfig xmpp_config = xmpp_server_config_; |
Sergey Ulanov
2016/10/05 21:49:06
This code uses XmppSignalStrategy::XmppServerConfi
kelvinp
2016/10/06 00:43:05
Done.
| |
230 | 235 |
231 if (!message->GetString("userName", &xmpp_config.username)) { | 236 if (!message->GetString("userName", &xmpp_config.username)) { |
232 SendErrorAndExit(std::move(response), "'userName' not found in request."); | 237 SendErrorAndExit(std::move(response), "'userName' not found in request."); |
233 return; | 238 return; |
234 } | 239 } |
240 bool use_signaling_proxy = false; | |
Sergey Ulanov
2016/10/05 21:49:06
nit: add empty line here
kelvinp
2016/10/06 00:43:05
Done.
| |
241 message->GetBoolean("useSignalingProxy", &use_signaling_proxy); | |
235 | 242 |
236 std::string auth_service_with_token; | 243 std::unique_ptr<SignalStrategy> signal_strategy; |
237 if (!message->GetString("authServiceWithToken", &auth_service_with_token)) { | 244 |
238 SendErrorAndExit(std::move(response), | 245 if (!use_signaling_proxy) { |
246 std::string auth_service_with_token; | |
247 if (!message->GetString("authServiceWithToken", &auth_service_with_token)) { | |
248 SendErrorAndExit(std::move(response), | |
239 "'authServiceWithToken' not found in request."); | 249 "'authServiceWithToken' not found in request."); |
240 return; | 250 return; |
251 } | |
252 | |
253 // For backward compatibility the webapp still passes OAuth service as part | |
254 // of the authServiceWithToken field. But auth service part is always | |
255 // expected to be set to oauth2. | |
256 const char kOAuth2ServicePrefix[] = "oauth2:"; | |
257 if (!base::StartsWith(auth_service_with_token, kOAuth2ServicePrefix, | |
258 base::CompareCase::SENSITIVE)) { | |
259 SendErrorAndExit(std::move(response), "Invalid 'authServiceWithToken': " + | |
260 auth_service_with_token); | |
261 return; | |
262 } | |
263 | |
264 xmpp_config.auth_token = | |
265 auth_service_with_token.substr(strlen(kOAuth2ServicePrefix)); | |
266 | |
267 #if !defined(NDEBUG) | |
268 std::string address; | |
269 if (!message->GetString("xmppServerAddress", &address)) { | |
270 SendErrorAndExit(std::move(response), | |
271 "'xmppServerAddress' not found in request."); | |
272 return; | |
273 } | |
274 | |
275 if (!net::ParseHostAndPort(address, &xmpp_config.host, | |
276 &xmpp_config.port)) { | |
277 SendErrorAndExit(std::move(response), | |
278 "Invalid 'xmppServerAddress': " + address); | |
279 return; | |
280 } | |
281 | |
282 if (!message->GetBoolean("xmppServerUseTls", &xmpp_config.use_tls)) { | |
283 SendErrorAndExit(std::move(response), | |
284 "'xmppServerUseTls' not found in request."); | |
285 return; | |
286 } | |
287 #endif // !defined(NDEBUG) | |
288 signal_strategy.reset(new XmppSignalStrategy( | |
Sergey Ulanov
2016/10/05 21:49:06
nit: add empty line here
kelvinp
2016/10/06 00:43:05
Done.
| |
289 net::ClientSocketFactory::GetDefaultFactory(), | |
290 host_context_->url_request_context_getter(), xmpp_config)); | |
291 } else { | |
292 std::string host_jid; | |
293 | |
294 if (!message->GetString("hostJid", &host_jid)) { | |
Sergey Ulanov
2016/10/05 21:49:06
maybe call this localJid and local_jid?
kelvinp
2016/10/06 00:43:05
Done.
| |
295 SendErrorAndExit(std::move(response), "'hostJid' not found in request."); | |
296 return; | |
297 } | |
298 | |
299 delegating_signal_strategy_ = new DelegatingSignalStrategy( | |
300 host_jid, | |
301 task_runner(), | |
Sergey Ulanov
2016/10/05 21:49:06
'git cl format' please
kelvinp
2016/10/06 00:43:05
Done.
| |
302 host_context_->network_task_runner(), | |
303 base::Bind(&It2MeNativeMessagingHost::SendOutgoingIq, | |
304 weak_factory_.GetWeakPtr())); | |
305 signal_strategy.reset(delegating_signal_strategy_); | |
241 } | 306 } |
242 | 307 |
243 // For backward compatibility the webapp still passes OAuth service as part of | |
244 // the authServiceWithToken field. But auth service part is always expected to | |
245 // be set to oauth2. | |
246 const char kOAuth2ServicePrefix[] = "oauth2:"; | |
247 if (!base::StartsWith(auth_service_with_token, kOAuth2ServicePrefix, | |
248 base::CompareCase::SENSITIVE)) { | |
249 SendErrorAndExit(std::move(response), "Invalid 'authServiceWithToken': " + | |
250 auth_service_with_token); | |
251 return; | |
252 } | |
253 | |
254 xmpp_config.auth_token = | |
255 auth_service_with_token.substr(strlen(kOAuth2ServicePrefix)); | |
256 | |
257 #if !defined(NDEBUG) | 308 #if !defined(NDEBUG) |
258 std::string address; | |
259 if (!message->GetString("xmppServerAddress", &address)) { | |
260 SendErrorAndExit(std::move(response), | |
261 "'xmppServerAddress' not found in request."); | |
262 return; | |
263 } | |
264 | |
265 if (!net::ParseHostAndPort(address, &xmpp_config.host, | |
266 &xmpp_config.port)) { | |
267 SendErrorAndExit(std::move(response), | |
268 "Invalid 'xmppServerAddress': " + address); | |
269 return; | |
270 } | |
271 | |
272 if (!message->GetBoolean("xmppServerUseTls", &xmpp_config.use_tls)) { | |
273 SendErrorAndExit(std::move(response), | |
274 "'xmppServerUseTls' not found in request."); | |
275 return; | |
276 } | |
277 | |
278 if (!message->GetString("directoryBotJid", &directory_bot_jid_)) { | 309 if (!message->GetString("directoryBotJid", &directory_bot_jid_)) { |
279 SendErrorAndExit(std::move(response), | 310 SendErrorAndExit(std::move(response), |
280 "'directoryBotJid' not found in request."); | 311 "'directoryBotJid' not found in request."); |
281 return; | 312 return; |
282 } | 313 } |
283 #endif // !defined(NDEBUG) | 314 #endif // !defined(NDEBUG) |
284 | 315 |
285 // Create the It2Me host and start connecting. | 316 // Create the It2Me host and start connecting. |
286 it2me_host_ = | 317 it2me_host_ = |
287 factory_->CreateIt2MeHost(host_context_->Copy(), policy_service_, | 318 factory_->CreateIt2MeHost(host_context_->Copy(), policy_service_, |
288 weak_ptr_, xmpp_config, directory_bot_jid_); | 319 weak_ptr_, std::move(signal_strategy), |
320 xmpp_server_config_.username, | |
321 directory_bot_jid_); | |
289 it2me_host_->Connect(); | 322 it2me_host_->Connect(); |
290 | 323 |
291 SendMessageToClient(std::move(response)); | 324 SendMessageToClient(std::move(response)); |
292 } | 325 } |
293 | 326 |
294 void It2MeNativeMessagingHost::ProcessDisconnect( | 327 void It2MeNativeMessagingHost::ProcessDisconnect( |
295 std::unique_ptr<base::DictionaryValue> message, | 328 std::unique_ptr<base::DictionaryValue> message, |
296 std::unique_ptr<base::DictionaryValue> response) { | 329 std::unique_ptr<base::DictionaryValue> response) { |
297 DCHECK(task_runner()->BelongsToCurrentThread()); | 330 DCHECK(task_runner()->BelongsToCurrentThread()); |
298 DCHECK(policy_received_); | 331 DCHECK(policy_received_); |
(...skipping 11 matching lines...) Expand all Loading... | |
310 return; | 343 return; |
311 } | 344 } |
312 | 345 |
313 if (it2me_host_.get()) { | 346 if (it2me_host_.get()) { |
314 it2me_host_->Disconnect(); | 347 it2me_host_->Disconnect(); |
315 it2me_host_ = nullptr; | 348 it2me_host_ = nullptr; |
316 } | 349 } |
317 SendMessageToClient(std::move(response)); | 350 SendMessageToClient(std::move(response)); |
318 } | 351 } |
319 | 352 |
353 void It2MeNativeMessagingHost::ProcessIncomingIq( | |
354 std::unique_ptr<base::DictionaryValue>message, | |
355 std::unique_ptr<base::DictionaryValue> response) { | |
356 | |
357 std::string iq; | |
358 if (!message->GetString("iq", &iq)) { | |
359 LOG(ERROR) << "Invalid incomingIq() data."; | |
360 return; | |
361 } | |
362 | |
363 if (delegating_signal_strategy_) | |
364 delegating_signal_strategy_->OnIncomingMessage(iq); | |
365 SendMessageToClient(std::move(response)); | |
366 }; | |
367 | |
368 void It2MeNativeMessagingHost::SendOutgoingIq(const std::string& iq) { | |
369 std::unique_ptr<base::DictionaryValue> message(new base::DictionaryValue()); | |
370 message->SetString("iq", iq); | |
371 message->SetString("type", "sendOutgoingIq"); | |
372 SendMessageToClient(std::move(message)); | |
373 } | |
374 | |
320 void It2MeNativeMessagingHost::SendErrorAndExit( | 375 void It2MeNativeMessagingHost::SendErrorAndExit( |
321 std::unique_ptr<base::DictionaryValue> response, | 376 std::unique_ptr<base::DictionaryValue> response, |
322 const std::string& description) const { | 377 const std::string& description) const { |
323 DCHECK(task_runner()->BelongsToCurrentThread()); | 378 DCHECK(task_runner()->BelongsToCurrentThread()); |
324 | 379 |
325 LOG(ERROR) << description; | 380 LOG(ERROR) << description; |
326 | 381 |
327 response->SetString("type", "error"); | 382 response->SetString("type", "error"); |
328 response->SetString("description", description); | 383 response->SetString("description", description); |
329 SendMessageToClient(std::move(response)); | 384 SendMessageToClient(std::move(response)); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 | 531 |
477 bool It2MeNativeMessagingHost::DelegateToElevatedHost( | 532 bool It2MeNativeMessagingHost::DelegateToElevatedHost( |
478 std::unique_ptr<base::DictionaryValue> message) { | 533 std::unique_ptr<base::DictionaryValue> message) { |
479 NOTREACHED(); | 534 NOTREACHED(); |
480 return false; | 535 return false; |
481 } | 536 } |
482 | 537 |
483 #endif // !defined(OS_WIN) | 538 #endif // !defined(OS_WIN) |
484 | 539 |
485 } // namespace remoting | 540 } // namespace remoting |
OLD | NEW |