Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: remoting/host/it2me/it2me_host.cc

Issue 2724223003: Disconnect all users if too many connection requests are received for It2Me (Closed)
Patch Set: Fixing another non-Windows build error Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <cstdint> 7 #include <cstdint>
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 namespace remoting { 44 namespace remoting {
45 45
46 namespace { 46 namespace {
47 47
48 // This is used for tagging system event logs. 48 // This is used for tagging system event logs.
49 const char kApplicationName[] = "chromoting"; 49 const char kApplicationName[] = "chromoting";
50 const int kMaxLoginAttempts = 5; 50 const int kMaxLoginAttempts = 5;
51 51
52 using protocol::ValidatingAuthenticator; 52 using protocol::ValidatingAuthenticator;
53 typedef ValidatingAuthenticator::Result ValidationResult; 53 typedef ValidatingAuthenticator::Result ValidationResult;
54 typedef ValidatingAuthenticator::ResultCallback ValidationResultCallback;
54 typedef ValidatingAuthenticator::ValidationCallback ValidationCallback; 55 typedef ValidatingAuthenticator::ValidationCallback ValidationCallback;
55 56
57 bool GetUsernameFromJid(const std::string& remote_jid,
Sergey Ulanov 2017/03/15 22:25:33 Maybe use base::Optional<std::string> for the resu
joedow 2017/03/16 21:32:18 Acknowledged.
58 std::string* client_username) {
59 DCHECK(client_username);
60 if (!SplitJidResource(remote_jid, client_username, /*resource=*/nullptr)) {
61 LOG(ERROR) << "Malformed jid: '" << remote_jid << "'";
62 return false;
63 }
64
65 if (client_username->empty()) {
66 LOG(ERROR) << "Malformed jid, missing username: " << remote_jid;
67 return false;
68 }
69
70 return true;
71 }
72
56 } // namespace 73 } // namespace
57 74
58 It2MeHost::It2MeHost( 75 It2MeHost::It2MeHost(
59 std::unique_ptr<ChromotingHostContext> host_context, 76 std::unique_ptr<ChromotingHostContext> host_context,
60 std::unique_ptr<PolicyWatcher> policy_watcher, 77 std::unique_ptr<PolicyWatcher> policy_watcher,
61 std::unique_ptr<It2MeConfirmationDialog> confirmation_dialog, 78 std::unique_ptr<It2MeConfirmationDialog> confirmation_dialog,
62 base::WeakPtr<It2MeHost::Observer> observer, 79 base::WeakPtr<It2MeHost::Observer> observer,
63 std::unique_ptr<SignalStrategy> signal_strategy, 80 std::unique_ptr<SignalStrategy> signal_strategy,
64 const std::string& username, 81 const std::string& username,
65 const std::string& directory_bot_jid) 82 const std::string& directory_bot_jid)
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 307
291 void It2MeHost::SetPolicyForTesting( 308 void It2MeHost::SetPolicyForTesting(
292 std::unique_ptr<base::DictionaryValue> policies, 309 std::unique_ptr<base::DictionaryValue> policies,
293 const base::Closure& done_callback) { 310 const base::Closure& done_callback) {
294 host_context_->network_task_runner()->PostTaskAndReply( 311 host_context_->network_task_runner()->PostTaskAndReply(
295 FROM_HERE, 312 FROM_HERE,
296 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies)), 313 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies)),
297 done_callback); 314 done_callback);
298 } 315 }
299 316
300 ValidationCallback It2MeHost::GetValidationCallbackForTesting() { 317 ValidationCallback It2MeHost::GetIncomingConnectionCallbackForTesting() {
301 return base::Bind(&It2MeHost::ValidateConnectionDetails, 318 return base::Bind(&It2MeHost::ValidateConnectionDetails,
302 base::Unretained(this)); 319 base::Unretained(this));
303 } 320 }
304 321
322 ValidationCallback It2MeHost::GetAcceptedConnectionCallbackForTesting() {
323 return base::Bind(&It2MeHost::ShowConfirmationDialog, base::Unretained(this));
324 }
325
305 void It2MeHost::OnPolicyUpdate( 326 void It2MeHost::OnPolicyUpdate(
306 std::unique_ptr<base::DictionaryValue> policies) { 327 std::unique_ptr<base::DictionaryValue> policies) {
307 // The policy watcher runs on the |ui_task_runner|. 328 // The policy watcher runs on the |ui_task_runner|.
308 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { 329 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) {
309 host_context_->network_task_runner()->PostTask( 330 host_context_->network_task_runner()->PostTask(
310 FROM_HERE, 331 FROM_HERE,
311 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies))); 332 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies)));
312 return; 333 return;
313 } 334 }
314 335
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 } 390 }
370 391
371 required_host_domain_ = host_domain; 392 required_host_domain_ = host_domain;
372 } 393 }
373 394
374 void It2MeHost::UpdateClientDomainPolicy(const std::string& client_domain) { 395 void It2MeHost::UpdateClientDomainPolicy(const std::string& client_domain) {
375 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 396 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
376 397
377 VLOG(2) << "UpdateClientDomainPolicy: " << client_domain; 398 VLOG(2) << "UpdateClientDomainPolicy: " << client_domain;
378 399
379 // When setting a client domain policy, disconnect any existing session. 400 // When setting a client domain policy, disconnect any existing session.
380 if (!client_domain.empty() && IsRunning()) { 401 if (!client_domain.empty() && IsRunning()) {
381 DisconnectOnNetworkThread(); 402 DisconnectOnNetworkThread();
382 } 403 }
383 404
384 required_client_domain_ = client_domain; 405 required_client_domain_ = client_domain;
385 } 406 }
386 407
387 void It2MeHost::SetState(It2MeHostState state, 408 void It2MeHost::SetState(It2MeHostState state,
388 const std::string& error_message) { 409 const std::string& error_message) {
389 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 410 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 LOG(ERROR) << error_message; 483 LOG(ERROR) << error_message;
463 SetState(kError, error_message); 484 SetState(kError, error_message);
464 DisconnectOnNetworkThread(); 485 DisconnectOnNetworkThread();
465 return; 486 return;
466 } 487 }
467 488
468 std::unique_ptr<protocol::AuthenticatorFactory> factory( 489 std::unique_ptr<protocol::AuthenticatorFactory> factory(
469 new protocol::It2MeHostAuthenticatorFactory( 490 new protocol::It2MeHostAuthenticatorFactory(
470 local_certificate, host_key_pair_, access_code_hash, 491 local_certificate, host_key_pair_, access_code_hash,
471 base::Bind(&It2MeHost::ValidateConnectionDetails, 492 base::Bind(&It2MeHost::ValidateConnectionDetails,
493 base::Unretained(this)),
494 base::Bind(&It2MeHost::ShowConfirmationDialog,
472 base::Unretained(this)))); 495 base::Unretained(this))));
473 host_->SetAuthenticatorFactory(std::move(factory)); 496 host_->SetAuthenticatorFactory(std::move(factory));
474 497
475 // Pass the Access Code to the script object before changing state. 498 // Pass the Access Code to the script object before changing state.
476 host_context_->ui_task_runner()->PostTask( 499 host_context_->ui_task_runner()->PostTask(
477 FROM_HERE, base::Bind(&It2MeHost::Observer::OnStoreAccessCode, observer_, 500 FROM_HERE, base::Bind(&It2MeHost::Observer::OnStoreAccessCode, observer_,
478 access_code, lifetime)); 501 access_code, lifetime));
479 502
480 SetState(kReceivedAccessCode, ""); 503 SetState(kReceivedAccessCode, "");
481 } 504 }
482 505
483 void It2MeHost::ValidateConnectionDetails( 506 void It2MeHost::ValidateConnectionDetails(
484 const std::string& remote_jid, 507 const std::string& remote_jid,
485 const protocol::ValidatingAuthenticator::ResultCallback& result_callback) { 508 const ValidationResultCallback& result_callback) {
486 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 509 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
487 510
488 // First ensure the JID we received is valid. 511 // First ensure the JID we received is valid.
489 std::string client_username; 512 std::string client_username;
490 if (!SplitJidResource(remote_jid, &client_username, /*resource=*/nullptr)) { 513 if (!GetUsernameFromJid(remote_jid, &client_username)) {
491 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid 514 result_callback.Run(ValidationResult::ERROR_INVALID_ACCOUNT);
492 << ": Invalid JID.";
493 result_callback.Run(
494 protocol::ValidatingAuthenticator::Result::ERROR_INVALID_ACCOUNT);
495 DisconnectOnNetworkThread(); 515 DisconnectOnNetworkThread();
496 return; 516 return;
497 } 517 }
498
499 if (client_username.empty()) {
500 LOG(ERROR) << "Invalid user name passed in: " << remote_jid;
501 result_callback.Run(
502 protocol::ValidatingAuthenticator::Result::ERROR_INVALID_ACCOUNT);
503 DisconnectOnNetworkThread();
504 return;
505 }
506 518
507 // Check the client domain policy. 519 // Check the client domain policy.
Sergey Ulanov 2017/03/15 22:25:33 Does this check need to be separate from ShowConfi
joedow 2017/03/16 21:32:18 Done.
508 if (!required_client_domain_.empty()) { 520 if (!required_client_domain_.empty()) {
509 if (!base::EndsWith(client_username, 521 if (!base::EndsWith(client_username,
510 std::string("@") + required_client_domain_, 522 std::string("@") + required_client_domain_,
511 base::CompareCase::INSENSITIVE_ASCII)) { 523 base::CompareCase::INSENSITIVE_ASCII)) {
512 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid 524 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid
513 << ": Domain mismatch."; 525 << ": Domain mismatch.";
514 result_callback.Run(ValidationResult::ERROR_INVALID_ACCOUNT); 526 result_callback.Run(ValidationResult::ERROR_INVALID_ACCOUNT);
515 DisconnectOnNetworkThread(); 527 DisconnectOnNetworkThread();
516 return; 528 return;
517 } 529 }
518 } 530 }
519 531
532 result_callback.Run(ValidationResult::SUCCESS);
533 }
534
535 void It2MeHost::ShowConfirmationDialog(
536 const std::string& remote_jid,
537 const ValidationResultCallback& result_callback) {
538 std::string client_username;
539 if (!GetUsernameFromJid(remote_jid, &client_username)) {
540 result_callback.Run(ValidationResult::ERROR_INVALID_ACCOUNT);
541 DisconnectOnNetworkThread();
542 return;
543 }
544
545 // If we receive valid connection details multiple times, then we don't know
546 // which remote user (if either) is valid so disconnect everyone.
547 if (state_ != kReceivedAccessCode) {
548 LOG(ERROR) << "Received too many connection requests.";
Sergey Ulanov 2017/03/15 22:25:33 Can we DCHECK here that state_ is kConnecting? I d
joedow 2017/03/16 21:32:18 Done.
549 result_callback.Run(ValidationResult::ERROR_TOO_MANY_CONNECTIONS);
550 DisconnectOnNetworkThread();
551 return;
552 }
553
520 HOST_LOG << "Client " << client_username << " connecting."; 554 HOST_LOG << "Client " << client_username << " connecting.";
521 SetState(kConnecting, std::string()); 555 SetState(kConnecting, std::string());
522 556
523 // Show a confirmation dialog to the user to allow them to confirm/reject it. 557 // Show a confirmation dialog to the user to allow them to confirm/reject it.
524 confirmation_dialog_proxy_.reset(new It2MeConfirmationDialogProxy( 558 confirmation_dialog_proxy_.reset(new It2MeConfirmationDialogProxy(
525 host_context_->ui_task_runner(), std::move(confirmation_dialog_))); 559 host_context_->ui_task_runner(), std::move(confirmation_dialog_)));
526 560
527 confirmation_dialog_proxy_->Show( 561 confirmation_dialog_proxy_->Show(
528 client_username, base::Bind(&It2MeHost::OnConfirmationResult, 562 client_username, base::Bind(&It2MeHost::OnConfirmationResult,
529 base::Unretained(this), result_callback)); 563 base::Unretained(this), result_callback));
530 } 564 }
531 565
532 void It2MeHost::OnConfirmationResult( 566 void It2MeHost::OnConfirmationResult(
533 const protocol::ValidatingAuthenticator::ResultCallback& result_callback, 567 const ValidationResultCallback& result_callback,
534 It2MeConfirmationDialog::Result result) { 568 It2MeConfirmationDialog::Result result) {
535 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 569 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
536 570
537 switch (result) { 571 switch (result) {
538 case It2MeConfirmationDialog::Result::OK: 572 case It2MeConfirmationDialog::Result::OK:
539 result_callback.Run(ValidationResult::SUCCESS); 573 result_callback.Run(ValidationResult::SUCCESS);
540 break; 574 break;
541 575
542 case It2MeConfirmationDialog::Result::CANCEL: 576 case It2MeConfirmationDialog::Result::CANCEL:
543 result_callback.Run(ValidationResult::ERROR_REJECTED_BY_USER); 577 result_callback.Run(ValidationResult::ERROR_REJECTED_BY_USER);
(...skipping 16 matching lines...) Expand all
560 DCHECK(context->ui_task_runner()->BelongsToCurrentThread()); 594 DCHECK(context->ui_task_runner()->BelongsToCurrentThread());
561 595
562 std::unique_ptr<PolicyWatcher> policy_watcher = 596 std::unique_ptr<PolicyWatcher> policy_watcher =
563 PolicyWatcher::Create(policy_service, context->file_task_runner()); 597 PolicyWatcher::Create(policy_service, context->file_task_runner());
564 return new It2MeHost(std::move(context), std::move(policy_watcher), 598 return new It2MeHost(std::move(context), std::move(policy_watcher),
565 It2MeConfirmationDialog::Create(), observer, 599 It2MeConfirmationDialog::Create(), observer,
566 std::move(signal_strategy), username, directory_bot_jid); 600 std::move(signal_strategy), username, directory_bot_jid);
567 } 601 }
568 602
569 } // namespace remoting 603 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698