Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file implements a standalone host process for Me2Me. | 5 // This file implements a standalone host process for Me2Me. |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 void OnConfigUpdated(const std::string& serialized_config) override; | 164 void OnConfigUpdated(const std::string& serialized_config) override; |
| 165 void OnConfigWatcherError() override; | 165 void OnConfigWatcherError() override; |
| 166 | 166 |
| 167 // IPC::Listener implementation. | 167 // IPC::Listener implementation. |
| 168 bool OnMessageReceived(const IPC::Message& message) override; | 168 bool OnMessageReceived(const IPC::Message& message) override; |
| 169 void OnChannelError() override; | 169 void OnChannelError() override; |
| 170 | 170 |
| 171 // HostChangeNotificationListener::Listener overrides. | 171 // HostChangeNotificationListener::Listener overrides. |
| 172 void OnHostDeleted() override; | 172 void OnHostDeleted() override; |
| 173 | 173 |
| 174 // Initializes the pairing registry on Windows. | 174 // Handler of the ChromotingDaemonNetworkMsg_InitializePairingRegistry IPC |
| 175 // message. | |
| 175 void OnInitializePairingRegistry( | 176 void OnInitializePairingRegistry( |
| 176 IPC::PlatformFileForTransit privileged_key, | 177 IPC::PlatformFileForTransit privileged_key, |
| 177 IPC::PlatformFileForTransit unprivileged_key); | 178 IPC::PlatformFileForTransit unprivileged_key); |
| 178 | 179 |
| 179 private: | 180 private: |
| 180 enum HostState { | 181 enum HostState { |
| 181 // Host process has just been started. Waiting for config and policies to be | 182 // Host process has just been started. Waiting for config and policies to be |
| 182 // read from the disk. | 183 // read from the disk. |
| 183 HOST_INITIALIZING, | 184 HOST_INITIALIZING, |
| 184 | 185 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 | 265 |
| 265 // Stops the host and shuts down the process with the specified |exit_code|. | 266 // Stops the host and shuts down the process with the specified |exit_code|. |
| 266 void ShutdownHost(HostExitCodes exit_code); | 267 void ShutdownHost(HostExitCodes exit_code); |
| 267 | 268 |
| 268 void ScheduleHostShutdown(); | 269 void ScheduleHostShutdown(); |
| 269 | 270 |
| 270 void ShutdownOnNetworkThread(); | 271 void ShutdownOnNetworkThread(); |
| 271 | 272 |
| 272 void OnPolicyWatcherShutdown(); | 273 void OnPolicyWatcherShutdown(); |
| 273 | 274 |
| 275 #if defined(OS_WIN) | |
| 276 // Initializes the pairing registry on Windows. This should be invoked on the | |
| 277 // network thread. | |
| 278 void InitializePairingRegistry( | |
| 279 IPC::PlatformFileForTransit privileged_key, | |
| 280 IPC::PlatformFileForTransit unprivileged_key); | |
| 281 #endif // defined(OS_WIN) | |
| 282 | |
| 274 // Crashes the process in response to a daemon's request. The daemon passes | 283 // Crashes the process in response to a daemon's request. The daemon passes |
| 275 // the location of the code that detected the fatal error resulted in this | 284 // the location of the code that detected the fatal error resulted in this |
| 276 // request. | 285 // request. |
| 277 void OnCrash(const std::string& function_name, | 286 void OnCrash(const std::string& function_name, |
| 278 const std::string& file_name, | 287 const std::string& file_name, |
| 279 const int& line_number); | 288 const int& line_number); |
| 280 | 289 |
| 281 scoped_ptr<ChromotingHostContext> context_; | 290 scoped_ptr<ChromotingHostContext> context_; |
| 282 | 291 |
| 283 // Created on the UI thread but used from the network thread. | 292 // Created on the UI thread but used from the network thread. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 // Used to keep this HostProcess alive until it is shutdown. | 354 // Used to keep this HostProcess alive until it is shutdown. |
| 346 scoped_refptr<HostProcess> self_; | 355 scoped_refptr<HostProcess> self_; |
| 347 | 356 |
| 348 #if defined(REMOTING_MULTI_PROCESS) | 357 #if defined(REMOTING_MULTI_PROCESS) |
| 349 DesktopSessionConnector* desktop_session_connector_; | 358 DesktopSessionConnector* desktop_session_connector_; |
| 350 #endif // defined(REMOTING_MULTI_PROCESS) | 359 #endif // defined(REMOTING_MULTI_PROCESS) |
| 351 | 360 |
| 352 int* exit_code_out_; | 361 int* exit_code_out_; |
| 353 bool signal_parent_; | 362 bool signal_parent_; |
| 354 | 363 |
| 355 scoped_ptr<PairingRegistry::Delegate> pairing_registry_delegate_; | 364 #if defined(OS_WIN) |
| 365 // The registry keys for pinless authentication. | |
| 366 HKEY privileged_key_; | |
| 367 HKEY unprivileged_key_; | |
| 368 #endif // defined(OS_WIN) | |
| 356 | 369 |
| 357 ShutdownWatchdog* shutdown_watchdog_; | 370 ShutdownWatchdog* shutdown_watchdog_; |
| 358 }; | 371 }; |
| 359 | 372 |
| 360 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, | 373 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, |
| 361 int* exit_code_out, | 374 int* exit_code_out, |
| 362 ShutdownWatchdog* shutdown_watchdog) | 375 ShutdownWatchdog* shutdown_watchdog) |
| 363 : context_(context.Pass()), | 376 : context_(context.Pass()), |
| 364 state_(HOST_INITIALIZING), | 377 state_(HOST_INITIALIZING), |
| 365 use_service_account_(false), | 378 use_service_account_(false), |
| 366 enable_vp9_(false), | 379 enable_vp9_(false), |
| 367 frame_recorder_buffer_size_(0), | 380 frame_recorder_buffer_size_(0), |
| 368 host_username_match_required_(false), | 381 host_username_match_required_(false), |
| 369 allow_nat_traversal_(true), | 382 allow_nat_traversal_(true), |
| 370 allow_relay_(true), | 383 allow_relay_(true), |
| 371 min_udp_port_(0), | 384 min_udp_port_(0), |
| 372 max_udp_port_(0), | 385 max_udp_port_(0), |
| 373 allow_pairing_(true), | 386 allow_pairing_(true), |
| 374 curtain_required_(false), | 387 curtain_required_(false), |
| 375 enable_gnubby_auth_(false), | 388 enable_gnubby_auth_(false), |
| 376 enable_window_capture_(false), | 389 enable_window_capture_(false), |
| 377 window_id_(0), | 390 window_id_(0), |
| 378 #if defined(REMOTING_MULTI_PROCESS) | 391 #if defined(REMOTING_MULTI_PROCESS) |
| 379 desktop_session_connector_(NULL), | 392 desktop_session_connector_(NULL), |
| 380 #endif // defined(REMOTING_MULTI_PROCESS) | 393 #endif // defined(REMOTING_MULTI_PROCESS) |
| 381 self_(this), | 394 self_(this), |
| 382 exit_code_out_(exit_code_out), | 395 exit_code_out_(exit_code_out), |
| 383 signal_parent_(false), | 396 signal_parent_(false), |
| 397 privileged_key_(NULL), | |
| 398 unprivileged_key_(NULL), | |
| 384 shutdown_watchdog_(shutdown_watchdog) { | 399 shutdown_watchdog_(shutdown_watchdog) { |
| 385 StartOnUiThread(); | 400 StartOnUiThread(); |
| 386 } | 401 } |
| 387 | 402 |
| 388 HostProcess::~HostProcess() { | 403 HostProcess::~HostProcess() { |
| 389 // Verify that UI components have been torn down. | 404 // Verify that UI components have been torn down. |
| 390 DCHECK(!config_watcher_); | 405 DCHECK(!config_watcher_); |
| 391 DCHECK(!daemon_channel_); | 406 DCHECK(!daemon_channel_); |
| 392 DCHECK(!desktop_environment_factory_); | 407 DCHECK(!desktop_environment_factory_); |
| 393 | 408 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 if (state_ != HOST_STARTED) | 616 if (state_ != HOST_STARTED) |
| 602 return; | 617 return; |
| 603 | 618 |
| 604 std::string local_certificate = key_pair_->GenerateCertificate(); | 619 std::string local_certificate = key_pair_->GenerateCertificate(); |
| 605 if (local_certificate.empty()) { | 620 if (local_certificate.empty()) { |
| 606 LOG(ERROR) << "Failed to generate host certificate."; | 621 LOG(ERROR) << "Failed to generate host certificate."; |
| 607 ShutdownHost(kInitializationFailed); | 622 ShutdownHost(kInitializationFailed); |
| 608 return; | 623 return; |
| 609 } | 624 } |
| 610 | 625 |
| 611 scoped_refptr<PairingRegistry> pairing_registry = NULL; | |
| 612 if (allow_pairing_) { | |
| 613 if (!pairing_registry_delegate_) | |
| 614 pairing_registry_delegate_ = CreatePairingRegistryDelegate(); | |
| 615 | |
| 616 if (pairing_registry_delegate_) { | |
| 617 pairing_registry = new PairingRegistry(context_->file_task_runner(), | |
| 618 pairing_registry_delegate_.Pass()); | |
| 619 } | |
| 620 } | |
| 621 | |
| 622 scoped_ptr<protocol::AuthenticatorFactory> factory; | 626 scoped_ptr<protocol::AuthenticatorFactory> factory; |
| 623 | 627 |
| 624 if (third_party_auth_config_.is_empty()) { | 628 if (third_party_auth_config_.is_empty()) { |
| 629 scoped_refptr<PairingRegistry> pairing_registry = NULL; | |
|
Sergey Ulanov
2015/01/07 20:26:43
don't need to set it to NULL explicitly. Also use
weitao
2015/01/08 00:13:36
Done.
| |
| 630 if (allow_pairing_) { | |
| 631 scoped_ptr<PairingRegistry::Delegate> delegate( | |
| 632 CreatePairingRegistryDelegate()); | |
| 633 | |
| 634 #if defined(OS_WIN) | |
| 635 if (unprivileged_key_) { | |
|
Sergey Ulanov
2015/01/07 20:26:43
On windows there is no point creating PairingRegis
weitao
2015/01/08 00:13:36
Done.
| |
| 636 PairingRegistryDelegateWin* delegate_win = | |
| 637 reinterpret_cast<PairingRegistryDelegateWin*>(delegate.get()); | |
|
Sergey Ulanov
2015/01/07 20:26:43
Ouch, reinterpret_cast<>! You can avoid it, see my
weitao
2015/01/08 00:13:36
Done.
| |
| 638 delegate_win->SetRootKeys(privileged_key_, unprivileged_key_); | |
| 639 } | |
| 640 #endif // defined(OS_WIN) | |
| 641 | |
| 642 pairing_registry = new PairingRegistry(context_->file_task_runner(), | |
|
Sergey Ulanov
2015/01/07 20:26:43
We don't really need a new instance of PairingRegi
weitao
2015/01/08 00:13:35
Done.
| |
| 643 delegate.Pass()); | |
| 644 } | |
| 645 | |
| 625 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithSharedSecret( | 646 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithSharedSecret( |
| 626 use_service_account_, host_owner_, local_certificate, key_pair_, | 647 use_service_account_, host_owner_, local_certificate, key_pair_, |
| 627 host_secret_hash_, pairing_registry); | 648 host_secret_hash_, pairing_registry); |
| 628 | 649 |
| 650 host_->set_pairing_registry(pairing_registry); | |
| 629 } else if (third_party_auth_config_.is_valid()) { | 651 } else if (third_party_auth_config_.is_valid()) { |
| 630 scoped_ptr<protocol::TokenValidatorFactory> token_validator_factory( | 652 scoped_ptr<protocol::TokenValidatorFactory> token_validator_factory( |
| 631 new TokenValidatorFactoryImpl( | 653 new TokenValidatorFactoryImpl( |
| 632 third_party_auth_config_, | 654 third_party_auth_config_, |
| 633 key_pair_, context_->url_request_context_getter())); | 655 key_pair_, context_->url_request_context_getter())); |
| 634 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( | 656 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( |
| 635 use_service_account_, host_owner_, local_certificate, key_pair_, | 657 use_service_account_, host_owner_, local_certificate, key_pair_, |
| 636 token_validator_factory.Pass()); | 658 token_validator_factory.Pass()); |
| 637 | 659 |
| 638 } else { | 660 } else { |
| 639 // TODO(rmsousa): If the policy is bad the host should not go online. It | 661 // TODO(rmsousa): If the policy is bad the host should not go online. It |
| 640 // should keep running, but not connected, until the policies are fixed. | 662 // should keep running, but not connected, until the policies are fixed. |
| 641 // Having it show up as online and then reject all clients is misleading. | 663 // Having it show up as online and then reject all clients is misleading. |
| 642 LOG(ERROR) << "One of the third-party token URLs is empty or invalid. " | 664 LOG(ERROR) << "One of the third-party token URLs is empty or invalid. " |
| 643 << "Host will reject all clients until policies are corrected. " | 665 << "Host will reject all clients until policies are corrected. " |
| 644 << "TokenUrl: " << third_party_auth_config_.token_url << ", " | 666 << "TokenUrl: " << third_party_auth_config_.token_url << ", " |
| 645 << "TokenValidationUrl: " | 667 << "TokenValidationUrl: " |
| 646 << third_party_auth_config_.token_validation_url; | 668 << third_party_auth_config_.token_validation_url; |
| 647 factory = protocol::Me2MeHostAuthenticatorFactory::CreateRejecting(); | 669 factory = protocol::Me2MeHostAuthenticatorFactory::CreateRejecting(); |
| 648 } | 670 } |
| 649 | 671 |
| 650 #if defined(OS_POSIX) | 672 #if defined(OS_POSIX) |
| 651 // On Linux and Mac, perform a PAM authorization step after authentication. | 673 // On Linux and Mac, perform a PAM authorization step after authentication. |
| 652 factory.reset(new PamAuthorizationFactory(factory.Pass())); | 674 factory.reset(new PamAuthorizationFactory(factory.Pass())); |
| 653 #endif | 675 #endif |
| 654 host_->SetAuthenticatorFactory(factory.Pass()); | 676 host_->SetAuthenticatorFactory(factory.Pass()); |
| 655 | |
| 656 host_->set_pairing_registry(pairing_registry); | |
| 657 } | 677 } |
| 658 | 678 |
| 659 // IPC::Listener implementation. | 679 // IPC::Listener implementation. |
| 660 bool HostProcess::OnMessageReceived(const IPC::Message& message) { | 680 bool HostProcess::OnMessageReceived(const IPC::Message& message) { |
| 661 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 681 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 662 | 682 |
| 663 #if defined(REMOTING_MULTI_PROCESS) | 683 #if defined(REMOTING_MULTI_PROCESS) |
| 664 bool handled = true; | 684 bool handled = true; |
| 665 IPC_BEGIN_MESSAGE_MAP(HostProcess, message) | 685 IPC_BEGIN_MESSAGE_MAP(HostProcess, message) |
| 666 IPC_MESSAGE_HANDLER(ChromotingDaemonMsg_Crash, OnCrash) | 686 IPC_MESSAGE_HANDLER(ChromotingDaemonMsg_Crash, OnCrash) |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 } | 816 } |
| 797 | 817 |
| 798 void HostProcess::OnHostDeleted() { | 818 void HostProcess::OnHostDeleted() { |
| 799 LOG(ERROR) << "Host was deleted from the directory."; | 819 LOG(ERROR) << "Host was deleted from the directory."; |
| 800 ShutdownHost(kInvalidHostIdExitCode); | 820 ShutdownHost(kInvalidHostIdExitCode); |
| 801 } | 821 } |
| 802 | 822 |
| 803 void HostProcess::OnInitializePairingRegistry( | 823 void HostProcess::OnInitializePairingRegistry( |
| 804 IPC::PlatformFileForTransit privileged_key, | 824 IPC::PlatformFileForTransit privileged_key, |
| 805 IPC::PlatformFileForTransit unprivileged_key) { | 825 IPC::PlatformFileForTransit unprivileged_key) { |
| 806 DCHECK(!pairing_registry_delegate_); | 826 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 807 | 827 |
| 808 #if defined(OS_WIN) | 828 #if defined(OS_WIN) |
| 809 // Initialize the pairing registry delegate. | 829 context_->network_task_runner()->PostTask(FROM_HERE, base::Bind( |
| 810 scoped_ptr<PairingRegistryDelegateWin> delegate( | 830 &HostProcess::InitializePairingRegistry, |
| 811 new PairingRegistryDelegateWin()); | 831 this, privileged_key, unprivileged_key)); |
| 812 bool result = delegate->SetRootKeys( | |
| 813 reinterpret_cast<HKEY>( | |
| 814 IPC::PlatformFileForTransitToPlatformFile(privileged_key)), | |
| 815 reinterpret_cast<HKEY>( | |
| 816 IPC::PlatformFileForTransitToPlatformFile(unprivileged_key))); | |
| 817 if (!result) | |
| 818 return; | |
| 819 | |
| 820 pairing_registry_delegate_ = delegate.Pass(); | |
| 821 #else // !defined(OS_WIN) | 832 #else // !defined(OS_WIN) |
| 822 NOTREACHED(); | 833 NOTREACHED(); |
| 823 #endif // !defined(OS_WIN) | 834 #endif // !defined(OS_WIN) |
| 824 } | 835 } |
| 825 | 836 |
| 837 #if defined(OS_WIN) | |
| 838 void HostProcess::InitializePairingRegistry( | |
| 839 IPC::PlatformFileForTransit privileged_key, | |
| 840 IPC::PlatformFileForTransit unprivileged_key) { | |
| 841 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 842 | |
| 843 // |privileged_key| can be NULL but not |unprivileged_key|. | |
| 844 DCHECK(unprivileged_key); | |
| 845 | |
| 846 // |privileged_key_| and |unprivileged_key_| will only be initialized once. | |
| 847 DCHECK(!privileged_key_); | |
| 848 DCHECK(!unprivileged_key_); | |
| 849 | |
| 850 privileged_key_ = reinterpret_cast<HKEY>( | |
| 851 IPC::PlatformFileForTransitToPlatformFile(privileged_key)), | |
| 852 unprivileged_key_ = reinterpret_cast<HKEY>( | |
| 853 IPC::PlatformFileForTransitToPlatformFile(unprivileged_key)); | |
| 854 | |
| 855 // (Re)Create the authenticator factory now that we have received the | |
| 856 // registry keys for pinless auth. | |
| 857 CreateAuthenticatorFactory(); | |
| 858 } | |
| 859 #endif // !defined(OS_WIN) | |
| 860 | |
| 826 // Applies the host config, returning true if successful. | 861 // Applies the host config, returning true if successful. |
| 827 bool HostProcess::ApplyConfig(const base::DictionaryValue& config) { | 862 bool HostProcess::ApplyConfig(const base::DictionaryValue& config) { |
| 828 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 863 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 829 | 864 |
| 830 if (!config.GetString(kHostIdConfigPath, &host_id_)) { | 865 if (!config.GetString(kHostIdConfigPath, &host_id_)) { |
| 831 LOG(ERROR) << "host_id is not defined in the config."; | 866 LOG(ERROR) << "host_id is not defined in the config."; |
| 832 return false; | 867 return false; |
| 833 } | 868 } |
| 834 | 869 |
| 835 std::string key_base64; | 870 std::string key_base64; |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); | 1538 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); |
| 1504 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); | 1539 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); |
| 1505 | 1540 |
| 1506 // Run the main (also UI) message loop until the host no longer needs it. | 1541 // Run the main (also UI) message loop until the host no longer needs it. |
| 1507 message_loop.Run(); | 1542 message_loop.Run(); |
| 1508 | 1543 |
| 1509 return exit_code; | 1544 return exit_code; |
| 1510 } | 1545 } |
| 1511 | 1546 |
| 1512 } // namespace remoting | 1547 } // namespace remoting |
| OLD | NEW |