| 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_host.h" | 5 #include "remoting/host/it2me/it2me_host.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <cstdint> |
| 8 | 8 #include <memory> |
| 9 #include <string> |
| 9 #include <utility> | 10 #include <utility> |
| 10 | 11 |
| 11 #include "base/bind.h" | 12 #include "base/bind.h" |
| 12 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
| 13 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 15 #include "base/threading/platform_thread.h" | 16 #include "base/threading/platform_thread.h" |
| 16 #include "components/policy/policy_constants.h" | 17 #include "components/policy/policy_constants.h" |
| 17 #include "net/socket/client_socket_factory.h" | 18 #include "net/socket/client_socket_factory.h" |
| 18 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 30 #include "remoting/host/policy_watcher.h" | 31 #include "remoting/host/policy_watcher.h" |
| 31 #include "remoting/host/register_support_host_request.h" | 32 #include "remoting/host/register_support_host_request.h" |
| 32 #include "remoting/host/service_urls.h" | 33 #include "remoting/host/service_urls.h" |
| 33 #include "remoting/protocol/auth_util.h" | 34 #include "remoting/protocol/auth_util.h" |
| 34 #include "remoting/protocol/chromium_port_allocator_factory.h" | 35 #include "remoting/protocol/chromium_port_allocator_factory.h" |
| 35 #include "remoting/protocol/ice_transport.h" | 36 #include "remoting/protocol/ice_transport.h" |
| 36 #include "remoting/protocol/it2me_host_authenticator_factory.h" | 37 #include "remoting/protocol/it2me_host_authenticator_factory.h" |
| 37 #include "remoting/protocol/jingle_session_manager.h" | 38 #include "remoting/protocol/jingle_session_manager.h" |
| 38 #include "remoting/protocol/network_settings.h" | 39 #include "remoting/protocol/network_settings.h" |
| 39 #include "remoting/protocol/transport_context.h" | 40 #include "remoting/protocol/transport_context.h" |
| 41 #include "remoting/protocol/validating_authenticator.h" |
| 42 #include "remoting/signaling/jid_util.h" |
| 40 #include "remoting/signaling/server_log_entry.h" | 43 #include "remoting/signaling/server_log_entry.h" |
| 41 | 44 |
| 42 namespace remoting { | 45 namespace remoting { |
| 43 | 46 |
| 44 namespace { | 47 namespace { |
| 45 | 48 |
| 46 // This is used for tagging system event logs. | 49 // This is used for tagging system event logs. |
| 47 const char kApplicationName[] = "chromoting"; | 50 const char kApplicationName[] = "chromoting"; |
| 48 const int kMaxLoginAttempts = 5; | 51 const int kMaxLoginAttempts = 5; |
| 49 | 52 |
| 53 using protocol::ValidatingAuthenticator; |
| 54 typedef ValidatingAuthenticator::Result ValidationResult; |
| 55 typedef ValidatingAuthenticator::ValidationCallback ValidationCallback; |
| 56 |
| 50 } // namespace | 57 } // namespace |
| 51 | 58 |
| 52 It2MeHost::It2MeHost( | 59 It2MeHost::It2MeHost( |
| 53 std::unique_ptr<ChromotingHostContext> host_context, | 60 std::unique_ptr<ChromotingHostContext> host_context, |
| 54 std::unique_ptr<PolicyWatcher> policy_watcher, | 61 std::unique_ptr<PolicyWatcher> policy_watcher, |
| 55 std::unique_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory, | 62 std::unique_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory, |
| 56 base::WeakPtr<It2MeHost::Observer> observer, | 63 base::WeakPtr<It2MeHost::Observer> observer, |
| 57 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, | 64 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, |
| 58 const std::string& directory_bot_jid) | 65 const std::string& directory_bot_jid) |
| 59 : host_context_(std::move(host_context)), | 66 : host_context_(std::move(host_context)), |
| 60 task_runner_(host_context_->ui_task_runner()), | 67 task_runner_(host_context_->ui_task_runner()), |
| 61 observer_(observer), | 68 observer_(observer), |
| 62 xmpp_server_config_(xmpp_server_config), | 69 xmpp_server_config_(xmpp_server_config), |
| 63 directory_bot_jid_(directory_bot_jid), | 70 directory_bot_jid_(directory_bot_jid), |
| 64 state_(kDisconnected), | 71 state_(kDisconnected), |
| 65 failed_login_attempts_(0), | 72 failed_login_attempts_(0), |
| 66 policy_watcher_(std::move(policy_watcher)), | 73 policy_watcher_(std::move(policy_watcher)), |
| 67 confirmation_dialog_factory_(std::move(confirmation_dialog_factory)), | 74 confirmation_dialog_factory_(std::move(confirmation_dialog_factory)), |
| 68 nat_traversal_enabled_(false), | 75 nat_traversal_enabled_(false), |
| 69 policy_received_(false) { | 76 policy_received_(false) { |
| 70 DCHECK(task_runner_->BelongsToCurrentThread()); | 77 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 71 } | 78 } |
| 72 | 79 |
| 80 It2MeHost::~It2MeHost() { |
| 81 // Check that resources that need to be torn down on the UI thread are gone. |
| 82 DCHECK(!desktop_environment_factory_.get()); |
| 83 DCHECK(!policy_watcher_.get()); |
| 84 } |
| 85 |
| 73 void It2MeHost::Connect() { | 86 void It2MeHost::Connect() { |
| 74 if (!host_context_->ui_task_runner()->BelongsToCurrentThread()) { | 87 if (!host_context_->ui_task_runner()->BelongsToCurrentThread()) { |
| 75 DCHECK(task_runner_->BelongsToCurrentThread()); | 88 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 76 host_context_->ui_task_runner()->PostTask( | 89 host_context_->ui_task_runner()->PostTask( |
| 77 FROM_HERE, base::Bind(&It2MeHost::Connect, this)); | 90 FROM_HERE, base::Bind(&It2MeHost::Connect, this)); |
| 78 return; | 91 return; |
| 79 } | 92 } |
| 80 | 93 |
| 81 desktop_environment_factory_.reset(new It2MeDesktopEnvironmentFactory( | 94 desktop_environment_factory_.reset(new It2MeDesktopEnvironmentFactory( |
| 82 host_context_->network_task_runner(), | 95 host_context_->network_task_runner(), |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 | 329 |
| 317 SetState(kConnected, ""); | 330 SetState(kConnected, ""); |
| 318 } | 331 } |
| 319 | 332 |
| 320 void It2MeHost::OnClientDisconnected(const std::string& jid) { | 333 void It2MeHost::OnClientDisconnected(const std::string& jid) { |
| 321 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 334 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 322 | 335 |
| 323 DisconnectOnNetworkThread(); | 336 DisconnectOnNetworkThread(); |
| 324 } | 337 } |
| 325 | 338 |
| 339 void It2MeHost::SetPolicyForTesting( |
| 340 std::unique_ptr<base::DictionaryValue> policies, |
| 341 const base::Closure& done_callback) { |
| 342 host_context_->network_task_runner()->PostTaskAndReply( |
| 343 FROM_HERE, |
| 344 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies)), |
| 345 done_callback); |
| 346 } |
| 347 |
| 348 ValidationCallback It2MeHost::GetValidationCallbackForTesting() { |
| 349 return base::Bind(&It2MeHost::ValidateConnectionDetails, |
| 350 base::Unretained(this)); |
| 351 } |
| 352 |
| 326 void It2MeHost::OnPolicyUpdate( | 353 void It2MeHost::OnPolicyUpdate( |
| 327 std::unique_ptr<base::DictionaryValue> policies) { | 354 std::unique_ptr<base::DictionaryValue> policies) { |
| 328 // The policy watcher runs on the |ui_task_runner|. | 355 // The policy watcher runs on the |ui_task_runner|. |
| 329 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 356 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { |
| 330 host_context_->network_task_runner()->PostTask( | 357 host_context_->network_task_runner()->PostTask( |
| 331 FROM_HERE, | 358 FROM_HERE, |
| 332 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies))); | 359 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies))); |
| 333 return; | 360 return; |
| 334 } | 361 } |
| 335 | 362 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 VLOG(2) << "UpdateClientDomainPolicy: " << client_domain; | 425 VLOG(2) << "UpdateClientDomainPolicy: " << client_domain; |
| 399 | 426 |
| 400 // When setting a client domain policy, disconnect any existing session. | 427 // When setting a client domain policy, disconnect any existing session. |
| 401 if (!client_domain.empty() && IsConnected()) { | 428 if (!client_domain.empty() && IsConnected()) { |
| 402 DisconnectOnNetworkThread(); | 429 DisconnectOnNetworkThread(); |
| 403 } | 430 } |
| 404 | 431 |
| 405 required_client_domain_ = client_domain; | 432 required_client_domain_ = client_domain; |
| 406 } | 433 } |
| 407 | 434 |
| 408 It2MeHost::~It2MeHost() { | |
| 409 // Check that resources that need to be torn down on the UI thread are gone. | |
| 410 DCHECK(!desktop_environment_factory_.get()); | |
| 411 DCHECK(!policy_watcher_.get()); | |
| 412 } | |
| 413 | |
| 414 void It2MeHost::SetState(It2MeHostState state, | 435 void It2MeHost::SetState(It2MeHostState state, |
| 415 const std::string& error_message) { | 436 const std::string& error_message) { |
| 416 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 437 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 417 | 438 |
| 418 switch (state_) { | 439 switch (state_) { |
| 419 case kDisconnected: | 440 case kDisconnected: |
| 420 DCHECK(state == kStarting || | 441 DCHECK(state == kStarting || |
| 421 state == kError) << state; | 442 state == kError) << state; |
| 422 break; | 443 break; |
| 423 case kStarting: | 444 case kStarting: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 std::string error_message = "Failed to generate host certificate."; | 504 std::string error_message = "Failed to generate host certificate."; |
| 484 LOG(ERROR) << error_message; | 505 LOG(ERROR) << error_message; |
| 485 SetState(kError, error_message); | 506 SetState(kError, error_message); |
| 486 DisconnectOnNetworkThread(); | 507 DisconnectOnNetworkThread(); |
| 487 return; | 508 return; |
| 488 } | 509 } |
| 489 | 510 |
| 490 std::unique_ptr<protocol::AuthenticatorFactory> factory( | 511 std::unique_ptr<protocol::AuthenticatorFactory> factory( |
| 491 new protocol::It2MeHostAuthenticatorFactory( | 512 new protocol::It2MeHostAuthenticatorFactory( |
| 492 local_certificate, host_key_pair_, access_code_hash, | 513 local_certificate, host_key_pair_, access_code_hash, |
| 493 required_client_domain_)); | 514 base::Bind(&It2MeHost::ValidateConnectionDetails, |
| 515 base::Unretained(this)))); |
| 494 host_->SetAuthenticatorFactory(std::move(factory)); | 516 host_->SetAuthenticatorFactory(std::move(factory)); |
| 495 | 517 |
| 496 // Pass the Access Code to the script object before changing state. | 518 // Pass the Access Code to the script object before changing state. |
| 497 task_runner_->PostTask( | 519 task_runner_->PostTask( |
| 498 FROM_HERE, base::Bind(&It2MeHost::Observer::OnStoreAccessCode, | 520 FROM_HERE, base::Bind(&It2MeHost::Observer::OnStoreAccessCode, |
| 499 observer_, access_code, lifetime)); | 521 observer_, access_code, lifetime)); |
| 500 | 522 |
| 501 SetState(kReceivedAccessCode, ""); | 523 SetState(kReceivedAccessCode, ""); |
| 502 } | 524 } |
| 503 | 525 |
| 526 void It2MeHost::ValidateConnectionDetails( |
| 527 const std::string& remote_jid, |
| 528 const protocol::ValidatingAuthenticator::ResultCallback& result_callback) { |
| 529 // Check the client domain policy. |
| 530 if (!required_client_domain_.empty()) { |
| 531 std::string client_username; |
| 532 if (!SplitJidResource(remote_jid, &client_username, /*resource=*/nullptr)) { |
| 533 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid |
| 534 << ": Invalid JID."; |
| 535 result_callback.Run(ValidationResult::ERROR_INVALID_ACCOUNT); |
| 536 return; |
| 537 } |
| 538 if (!base::EndsWith(client_username, |
| 539 std::string("@") + required_client_domain_, |
| 540 base::CompareCase::INSENSITIVE_ASCII)) { |
| 541 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid |
| 542 << ": Domain mismatch."; |
| 543 result_callback.Run(ValidationResult::ERROR_INVALID_ACCOUNT); |
| 544 return; |
| 545 } |
| 546 } |
| 547 |
| 548 result_callback.Run(ValidationResult::SUCCESS); |
| 549 } |
| 550 |
| 504 It2MeHostFactory::It2MeHostFactory() : policy_service_(nullptr) { | 551 It2MeHostFactory::It2MeHostFactory() : policy_service_(nullptr) { |
| 505 } | 552 } |
| 506 | 553 |
| 507 It2MeHostFactory::~It2MeHostFactory() {} | 554 It2MeHostFactory::~It2MeHostFactory() {} |
| 508 | 555 |
| 509 void It2MeHostFactory::set_policy_service( | 556 void It2MeHostFactory::set_policy_service( |
| 510 policy::PolicyService* policy_service) { | 557 policy::PolicyService* policy_service) { |
| 511 DCHECK(policy_service); | 558 DCHECK(policy_service); |
| 512 DCHECK(!policy_service_) << "|policy_service| can only be set once."; | 559 DCHECK(!policy_service_) << "|policy_service| can only be set once."; |
| 513 policy_service_ = policy_service; | 560 policy_service_ = policy_service; |
| 514 } | 561 } |
| 515 | 562 |
| 516 scoped_refptr<It2MeHost> It2MeHostFactory::CreateIt2MeHost( | 563 scoped_refptr<It2MeHost> It2MeHostFactory::CreateIt2MeHost( |
| 517 std::unique_ptr<ChromotingHostContext> context, | 564 std::unique_ptr<ChromotingHostContext> context, |
| 518 base::WeakPtr<It2MeHost::Observer> observer, | 565 base::WeakPtr<It2MeHost::Observer> observer, |
| 519 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, | 566 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, |
| 520 const std::string& directory_bot_jid) { | 567 const std::string& directory_bot_jid) { |
| 521 DCHECK(context->ui_task_runner()->BelongsToCurrentThread()); | 568 DCHECK(context->ui_task_runner()->BelongsToCurrentThread()); |
| 522 | 569 |
| 523 std::unique_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory( | 570 std::unique_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory( |
| 524 new It2MeConfirmationDialogFactory()); | 571 new It2MeConfirmationDialogFactory()); |
| 525 std::unique_ptr<PolicyWatcher> policy_watcher = | 572 std::unique_ptr<PolicyWatcher> policy_watcher = |
| 526 PolicyWatcher::Create(policy_service_, context->file_task_runner()); | 573 PolicyWatcher::Create(policy_service_, context->file_task_runner()); |
| 527 return new It2MeHost(std::move(context), std::move(policy_watcher), | 574 return new It2MeHost(std::move(context), std::move(policy_watcher), |
| 528 std::move(confirmation_dialog_factory), observer, | 575 std::move(confirmation_dialog_factory), observer, |
| 529 xmpp_server_config, directory_bot_jid); | 576 xmpp_server_config, directory_bot_jid); |
| 530 } | 577 } |
| 531 | 578 |
| 532 } // namespace remoting | 579 } // namespace remoting |
| OLD | NEW |