| 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 <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 base::Bind(&It2MeHost::OnPolicyError, this)); | 89 base::Bind(&It2MeHost::OnPolicyError, this)); |
| 90 | 90 |
| 91 // Switch to the network thread to start the actual connection. | 91 // Switch to the network thread to start the actual connection. |
| 92 host_context_->network_task_runner()->PostTask( | 92 host_context_->network_task_runner()->PostTask( |
| 93 FROM_HERE, base::Bind(&It2MeHost::ShowConfirmationPrompt, this)); | 93 FROM_HERE, base::Bind(&It2MeHost::ShowConfirmationPrompt, this)); |
| 94 } | 94 } |
| 95 | 95 |
| 96 void It2MeHost::Disconnect() { | 96 void It2MeHost::Disconnect() { |
| 97 DCHECK(task_runner_->BelongsToCurrentThread()); | 97 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 98 host_context_->network_task_runner()->PostTask( | 98 host_context_->network_task_runner()->PostTask( |
| 99 FROM_HERE, base::Bind(&It2MeHost::Shutdown, this)); | 99 FROM_HERE, base::Bind(&It2MeHost::DisconnectOnNetworkThread, this)); |
| 100 } | 100 } |
| 101 | 101 |
| 102 void It2MeHost::Shutdown() { | 102 void It2MeHost::DisconnectOnNetworkThread() { |
| 103 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 103 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 104 | 104 |
| 105 // Disconnect() may be called even when after the host been already stopped. |
| 106 // Ignore repeated calls. |
| 107 if (state_ == kDisconnected) { |
| 108 return; |
| 109 } |
| 110 |
| 105 confirmation_dialog_proxy_.reset(); | 111 confirmation_dialog_proxy_.reset(); |
| 106 | 112 |
| 107 host_event_logger_.reset(); | 113 host_event_logger_.reset(); |
| 108 if (host_) { | 114 if (host_) { |
| 109 host_->RemoveStatusObserver(this); | 115 host_->RemoveStatusObserver(this); |
| 110 host_.reset(); | 116 host_.reset(); |
| 111 } | 117 } |
| 112 | 118 |
| 113 register_request_.reset(); | 119 register_request_.reset(); |
| 114 host_status_logger_.reset(); | 120 host_status_logger_.reset(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 base::Bind(&It2MeHost::OnConfirmationResult, base::Unretained(this))); | 163 base::Bind(&It2MeHost::OnConfirmationResult, base::Unretained(this))); |
| 158 } | 164 } |
| 159 | 165 |
| 160 void It2MeHost::OnConfirmationResult(It2MeConfirmationDialog::Result result) { | 166 void It2MeHost::OnConfirmationResult(It2MeConfirmationDialog::Result result) { |
| 161 switch (result) { | 167 switch (result) { |
| 162 case It2MeConfirmationDialog::Result::OK: | 168 case It2MeConfirmationDialog::Result::OK: |
| 163 ReadPolicyAndConnect(); | 169 ReadPolicyAndConnect(); |
| 164 break; | 170 break; |
| 165 | 171 |
| 166 case It2MeConfirmationDialog::Result::CANCEL: | 172 case It2MeConfirmationDialog::Result::CANCEL: |
| 167 Shutdown(); | 173 DisconnectOnNetworkThread(); |
| 168 break; | 174 break; |
| 169 | 175 |
| 170 default: | 176 default: |
| 171 NOTREACHED(); | 177 NOTREACHED(); |
| 172 return; | 178 return; |
| 173 } | 179 } |
| 174 } | 180 } |
| 175 | 181 |
| 176 void It2MeHost::ReadPolicyAndConnect() { | 182 void It2MeHost::ReadPolicyAndConnect() { |
| 177 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 183 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 | 283 |
| 278 SetState(kRequestedAccessCode, ""); | 284 SetState(kRequestedAccessCode, ""); |
| 279 return; | 285 return; |
| 280 } | 286 } |
| 281 | 287 |
| 282 void It2MeHost::OnAccessDenied(const std::string& jid) { | 288 void It2MeHost::OnAccessDenied(const std::string& jid) { |
| 283 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 289 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 284 | 290 |
| 285 ++failed_login_attempts_; | 291 ++failed_login_attempts_; |
| 286 if (failed_login_attempts_ == kMaxLoginAttempts) { | 292 if (failed_login_attempts_ == kMaxLoginAttempts) { |
| 287 Shutdown(); | 293 DisconnectOnNetworkThread(); |
| 288 } | 294 } |
| 289 } | 295 } |
| 290 | 296 |
| 291 void It2MeHost::OnClientConnected(const std::string& jid) { | 297 void It2MeHost::OnClientConnected(const std::string& jid) { |
| 292 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 298 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 293 | 299 |
| 294 // ChromotingHost doesn't allow multiple concurrent connection and the | 300 // ChromotingHost doesn't allow multiple concurrent connection and the |
| 295 // host is destroyed in OnClientDisconnected() after the first connection. | 301 // host is destroyed in OnClientDisconnected() after the first connection. |
| 296 CHECK_NE(state_, kConnected); | 302 CHECK_NE(state_, kConnected); |
| 297 | 303 |
| 298 std::string client_username = jid; | 304 std::string client_username = jid; |
| 299 size_t pos = client_username.find('/'); | 305 size_t pos = client_username.find('/'); |
| 300 if (pos != std::string::npos) | 306 if (pos != std::string::npos) |
| 301 client_username.replace(pos, std::string::npos, ""); | 307 client_username.replace(pos, std::string::npos, ""); |
| 302 | 308 |
| 303 HOST_LOG << "Client " << client_username << " connected."; | 309 HOST_LOG << "Client " << client_username << " connected."; |
| 304 | 310 |
| 305 // Pass the client user name to the script object before changing state. | 311 // Pass the client user name to the script object before changing state. |
| 306 task_runner_->PostTask( | 312 task_runner_->PostTask( |
| 307 FROM_HERE, base::Bind(&It2MeHost::Observer::OnClientAuthenticated, | 313 FROM_HERE, base::Bind(&It2MeHost::Observer::OnClientAuthenticated, |
| 308 observer_, client_username)); | 314 observer_, client_username)); |
| 309 | 315 |
| 310 SetState(kConnected, ""); | 316 SetState(kConnected, ""); |
| 311 } | 317 } |
| 312 | 318 |
| 313 void It2MeHost::OnClientDisconnected(const std::string& jid) { | 319 void It2MeHost::OnClientDisconnected(const std::string& jid) { |
| 314 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 320 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 315 | 321 |
| 316 Shutdown(); | 322 DisconnectOnNetworkThread(); |
| 317 } | 323 } |
| 318 | 324 |
| 319 void It2MeHost::OnPolicyUpdate( | 325 void It2MeHost::OnPolicyUpdate( |
| 320 std::unique_ptr<base::DictionaryValue> policies) { | 326 std::unique_ptr<base::DictionaryValue> policies) { |
| 321 // The policy watcher runs on the |ui_task_runner|. | 327 // The policy watcher runs on the |ui_task_runner|. |
| 322 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 328 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { |
| 323 host_context_->network_task_runner()->PostTask( | 329 host_context_->network_task_runner()->PostTask( |
| 324 FROM_HERE, | 330 FROM_HERE, |
| 325 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies))); | 331 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies))); |
| 326 return; | 332 return; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 354 } | 360 } |
| 355 | 361 |
| 356 void It2MeHost::UpdateNatPolicy(bool nat_traversal_enabled) { | 362 void It2MeHost::UpdateNatPolicy(bool nat_traversal_enabled) { |
| 357 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 363 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 358 | 364 |
| 359 VLOG(2) << "UpdateNatPolicy: " << nat_traversal_enabled; | 365 VLOG(2) << "UpdateNatPolicy: " << nat_traversal_enabled; |
| 360 | 366 |
| 361 // When transitioning from enabled to disabled, force disconnect any | 367 // When transitioning from enabled to disabled, force disconnect any |
| 362 // existing session. | 368 // existing session. |
| 363 if (nat_traversal_enabled_ && !nat_traversal_enabled && IsConnected()) { | 369 if (nat_traversal_enabled_ && !nat_traversal_enabled && IsConnected()) { |
| 364 Shutdown(); | 370 DisconnectOnNetworkThread(); |
| 365 } | 371 } |
| 366 | 372 |
| 367 nat_traversal_enabled_ = nat_traversal_enabled; | 373 nat_traversal_enabled_ = nat_traversal_enabled; |
| 368 | 374 |
| 369 // Notify the web-app of the policy setting. | 375 // Notify the web-app of the policy setting. |
| 370 task_runner_->PostTask( | 376 task_runner_->PostTask( |
| 371 FROM_HERE, base::Bind(&It2MeHost::Observer::OnNatPolicyChanged, | 377 FROM_HERE, base::Bind(&It2MeHost::Observer::OnNatPolicyChanged, |
| 372 observer_, nat_traversal_enabled_)); | 378 observer_, nat_traversal_enabled_)); |
| 373 } | 379 } |
| 374 | 380 |
| 375 void It2MeHost::UpdateHostDomainPolicy(const std::string& host_domain) { | 381 void It2MeHost::UpdateHostDomainPolicy(const std::string& host_domain) { |
| 376 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 382 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 377 | 383 |
| 378 VLOG(2) << "UpdateHostDomainPolicy: " << host_domain; | 384 VLOG(2) << "UpdateHostDomainPolicy: " << host_domain; |
| 379 | 385 |
| 380 // When setting a host domain policy, force disconnect any existing session. | 386 // When setting a host domain policy, force disconnect any existing session. |
| 381 if (!host_domain.empty() && IsConnected()) { | 387 if (!host_domain.empty() && IsConnected()) { |
| 382 Shutdown(); | 388 DisconnectOnNetworkThread(); |
| 383 } | 389 } |
| 384 | 390 |
| 385 required_host_domain_ = host_domain; | 391 required_host_domain_ = host_domain; |
| 386 } | 392 } |
| 387 | 393 |
| 388 void It2MeHost::UpdateClientDomainPolicy(const std::string& client_domain) { | 394 void It2MeHost::UpdateClientDomainPolicy(const std::string& client_domain) { |
| 389 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 395 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 390 | 396 |
| 391 VLOG(2) << "UpdateClientDomainPolicy: " << client_domain; | 397 VLOG(2) << "UpdateClientDomainPolicy: " << client_domain; |
| 392 | 398 |
| 393 // When setting a client domain policy, disconnect any existing session. | 399 // When setting a client domain policy, disconnect any existing session. |
| 394 if (!client_domain.empty() && IsConnected()) { | 400 if (!client_domain.empty() && IsConnected()) { |
| 395 Shutdown(); | 401 DisconnectOnNetworkThread(); |
| 396 } | 402 } |
| 397 | 403 |
| 398 required_client_domain_ = client_domain; | 404 required_client_domain_ = client_domain; |
| 399 } | 405 } |
| 400 | 406 |
| 401 It2MeHost::~It2MeHost() { | 407 It2MeHost::~It2MeHost() { |
| 402 // Check that resources that need to be torn down on the UI thread are gone. | 408 // Check that resources that need to be torn down on the UI thread are gone. |
| 403 DCHECK(!desktop_environment_factory_.get()); | 409 DCHECK(!desktop_environment_factory_.get()); |
| 404 DCHECK(!policy_watcher_.get()); | 410 DCHECK(!policy_watcher_.get()); |
| 405 } | 411 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 } | 461 } |
| 456 | 462 |
| 457 void It2MeHost::OnReceivedSupportID( | 463 void It2MeHost::OnReceivedSupportID( |
| 458 const std::string& support_id, | 464 const std::string& support_id, |
| 459 const base::TimeDelta& lifetime, | 465 const base::TimeDelta& lifetime, |
| 460 const std::string& error_message) { | 466 const std::string& error_message) { |
| 461 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 467 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 462 | 468 |
| 463 if (!error_message.empty()) { | 469 if (!error_message.empty()) { |
| 464 SetState(kError, error_message); | 470 SetState(kError, error_message); |
| 465 Shutdown(); | 471 DisconnectOnNetworkThread(); |
| 466 return; | 472 return; |
| 467 } | 473 } |
| 468 | 474 |
| 469 std::string host_secret = GenerateSupportHostSecret(); | 475 std::string host_secret = GenerateSupportHostSecret(); |
| 470 std::string access_code = support_id + host_secret; | 476 std::string access_code = support_id + host_secret; |
| 471 std::string access_code_hash = | 477 std::string access_code_hash = |
| 472 protocol::GetSharedSecretHash(support_id, access_code); | 478 protocol::GetSharedSecretHash(support_id, access_code); |
| 473 | 479 |
| 474 std::string local_certificate = host_key_pair_->GenerateCertificate(); | 480 std::string local_certificate = host_key_pair_->GenerateCertificate(); |
| 475 if (local_certificate.empty()) { | 481 if (local_certificate.empty()) { |
| 476 std::string error_message = "Failed to generate host certificate."; | 482 std::string error_message = "Failed to generate host certificate."; |
| 477 LOG(ERROR) << error_message; | 483 LOG(ERROR) << error_message; |
| 478 SetState(kError, error_message); | 484 SetState(kError, error_message); |
| 479 Shutdown(); | 485 DisconnectOnNetworkThread(); |
| 480 return; | 486 return; |
| 481 } | 487 } |
| 482 | 488 |
| 483 std::unique_ptr<protocol::AuthenticatorFactory> factory( | 489 std::unique_ptr<protocol::AuthenticatorFactory> factory( |
| 484 new protocol::It2MeHostAuthenticatorFactory( | 490 new protocol::It2MeHostAuthenticatorFactory( |
| 485 local_certificate, host_key_pair_, access_code_hash, | 491 local_certificate, host_key_pair_, access_code_hash, |
| 486 required_client_domain_)); | 492 required_client_domain_)); |
| 487 host_->SetAuthenticatorFactory(std::move(factory)); | 493 host_->SetAuthenticatorFactory(std::move(factory)); |
| 488 | 494 |
| 489 // Pass the Access Code to the script object before changing state. | 495 // Pass the Access Code to the script object before changing state. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 516 std::unique_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory( | 522 std::unique_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory( |
| 517 new It2MeConfirmationDialogFactory()); | 523 new It2MeConfirmationDialogFactory()); |
| 518 std::unique_ptr<PolicyWatcher> policy_watcher = | 524 std::unique_ptr<PolicyWatcher> policy_watcher = |
| 519 PolicyWatcher::Create(policy_service_, context->file_task_runner()); | 525 PolicyWatcher::Create(policy_service_, context->file_task_runner()); |
| 520 return new It2MeHost(std::move(context), std::move(policy_watcher), | 526 return new It2MeHost(std::move(context), std::move(policy_watcher), |
| 521 std::move(confirmation_dialog_factory), observer, | 527 std::move(confirmation_dialog_factory), observer, |
| 522 xmpp_server_config, directory_bot_jid); | 528 xmpp_server_config, directory_bot_jid); |
| 523 } | 529 } |
| 524 | 530 |
| 525 } // namespace remoting | 531 } // namespace remoting |
| OLD | NEW |