validating_authenticator.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/protocol/validating_authenticator.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/callback.h"
  10. #include "base/check_op.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "remoting/protocol/authenticator.h"
  14. #include "remoting/protocol/channel_authenticator.h"
  15. #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
  16. namespace remoting {
  17. namespace protocol {
  18. ValidatingAuthenticator::ValidatingAuthenticator(
  19. const std::string& remote_jid,
  20. const ValidationCallback& validation_callback,
  21. std::unique_ptr<Authenticator> current_authenticator)
  22. : remote_jid_(remote_jid),
  23. validation_callback_(validation_callback),
  24. current_authenticator_(std::move(current_authenticator)) {
  25. DCHECK(!remote_jid_.empty());
  26. DCHECK(validation_callback_);
  27. DCHECK(current_authenticator_);
  28. }
  29. ValidatingAuthenticator::~ValidatingAuthenticator() = default;
  30. Authenticator::State ValidatingAuthenticator::state() const {
  31. return pending_auth_message_ ? MESSAGE_READY : state_;
  32. }
  33. bool ValidatingAuthenticator::started() const {
  34. return current_authenticator_->started();
  35. }
  36. Authenticator::RejectionReason ValidatingAuthenticator::rejection_reason()
  37. const {
  38. return rejection_reason_;
  39. }
  40. const std::string& ValidatingAuthenticator::GetAuthKey() const {
  41. return current_authenticator_->GetAuthKey();
  42. }
  43. std::unique_ptr<ChannelAuthenticator>
  44. ValidatingAuthenticator::CreateChannelAuthenticator() const {
  45. return current_authenticator_->CreateChannelAuthenticator();
  46. }
  47. void ValidatingAuthenticator::ProcessMessage(
  48. const jingle_xmpp::XmlElement* message,
  49. base::OnceClosure resume_callback) {
  50. DCHECK_EQ(state_, WAITING_MESSAGE);
  51. state_ = PROCESSING_MESSAGE;
  52. current_authenticator_->ProcessMessage(
  53. message,
  54. base::BindOnce(&ValidatingAuthenticator::UpdateState,
  55. weak_factory_.GetWeakPtr(), std::move(resume_callback)));
  56. }
  57. std::unique_ptr<jingle_xmpp::XmlElement> ValidatingAuthenticator::GetNextMessage() {
  58. if (pending_auth_message_) {
  59. DCHECK(state_ == ACCEPTED || state_ == WAITING_MESSAGE);
  60. return std::move(pending_auth_message_);
  61. }
  62. std::unique_ptr<jingle_xmpp::XmlElement> result(
  63. current_authenticator_->GetNextMessage());
  64. state_ = current_authenticator_->state();
  65. DCHECK(state_ == ACCEPTED || state_ == WAITING_MESSAGE);
  66. return result;
  67. }
  68. void ValidatingAuthenticator::OnValidateComplete(base::OnceClosure callback,
  69. Result validation_result) {
  70. // Map |rejection_reason_| to a known reason, set |state_| to REJECTED and
  71. // notify the listener of the connection error via the callback.
  72. switch (validation_result) {
  73. case Result::SUCCESS:
  74. state_ = ACCEPTED;
  75. std::move(callback).Run();
  76. return;
  77. case Result::ERROR_INVALID_CREDENTIALS:
  78. rejection_reason_ = RejectionReason::INVALID_CREDENTIALS;
  79. break;
  80. case Result::ERROR_INVALID_ACCOUNT:
  81. rejection_reason_ = RejectionReason::INVALID_ACCOUNT_ID;
  82. break;
  83. case Result::ERROR_TOO_MANY_CONNECTIONS:
  84. rejection_reason_ = RejectionReason::TOO_MANY_CONNECTIONS;
  85. break;
  86. case Result::ERROR_REJECTED_BY_USER:
  87. rejection_reason_ = RejectionReason::REJECTED_BY_USER;
  88. break;
  89. }
  90. state_ = Authenticator::REJECTED;
  91. // Clear the pending message so the signal strategy will generate a new
  92. // SESSION_REJECT message in response to this state change.
  93. pending_auth_message_.reset();
  94. std::move(callback).Run();
  95. }
  96. void ValidatingAuthenticator::UpdateState(base::OnceClosure resume_callback) {
  97. DCHECK_EQ(state_, PROCESSING_MESSAGE);
  98. // Update our current state before running |resume_callback|.
  99. state_ = current_authenticator_->state();
  100. if (state_ == REJECTED) {
  101. rejection_reason_ = current_authenticator_->rejection_reason();
  102. } else if (state_ == MESSAGE_READY) {
  103. DCHECK(!pending_auth_message_);
  104. pending_auth_message_ = current_authenticator_->GetNextMessage();
  105. state_ = current_authenticator_->state();
  106. }
  107. if (state_ == ACCEPTED) {
  108. state_ = PROCESSING_MESSAGE;
  109. validation_callback_.Run(
  110. remote_jid_,
  111. base::BindOnce(&ValidatingAuthenticator::OnValidateComplete,
  112. weak_factory_.GetWeakPtr(), std::move(resume_callback)));
  113. } else {
  114. std::move(resume_callback).Run();
  115. }
  116. }
  117. } // namespace protocol
  118. } // namespace remoting