blob: 2b1a244209bc4cc3932bddc2e5e3f152114010b4 [file] [log] [blame]
joedow7dc48992016-08-31 19:13:381// 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
5#include "remoting/protocol/validating_authenticator.h"
6
7#include <memory>
8#include <string>
9#include <utility>
10
11#include "base/bind.h"
12#include "base/callback.h"
Hans Wennborg828a0972020-04-27 18:10:0913#include "base/check_op.h"
joedow7dc48992016-08-31 19:13:3814#include "base/memory/ref_counted.h"
15#include "base/memory/weak_ptr.h"
16#include "remoting/protocol/authenticator.h"
17#include "remoting/protocol/channel_authenticator.h"
kjellanderf0e410b2017-01-04 14:45:0118#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
joedow7dc48992016-08-31 19:13:3819
20namespace remoting {
21namespace protocol {
22
23ValidatingAuthenticator::ValidatingAuthenticator(
24 const std::string& remote_jid,
Joe Downingd2819902020-04-27 23:38:4625 const ValidationCallback& validation_callback,
joedow7dc48992016-08-31 19:13:3826 std::unique_ptr<Authenticator> current_authenticator)
27 : remote_jid_(remote_jid),
Joe Downingd2819902020-04-27 23:38:4628 validation_callback_(validation_callback),
Jeremy Roman7c5cfabd2019-08-12 15:45:2729 current_authenticator_(std::move(current_authenticator)) {
joedow7dc48992016-08-31 19:13:3830 DCHECK(!remote_jid_.empty());
joedowf38c5d72017-03-20 15:55:4631 DCHECK(validation_callback_);
joedow7dc48992016-08-31 19:13:3832 DCHECK(current_authenticator_);
33}
34
Chris Watkins6fe52aa2017-11-28 03:24:0535ValidatingAuthenticator::~ValidatingAuthenticator() = default;
joedow7dc48992016-08-31 19:13:3836
37Authenticator::State ValidatingAuthenticator::state() const {
joedowf38c5d72017-03-20 15:55:4638 return pending_auth_message_ ? MESSAGE_READY : state_;
joedow7dc48992016-08-31 19:13:3839}
40
41bool ValidatingAuthenticator::started() const {
42 return current_authenticator_->started();
43}
44
45Authenticator::RejectionReason ValidatingAuthenticator::rejection_reason()
46 const {
47 return rejection_reason_;
48}
49
50const std::string& ValidatingAuthenticator::GetAuthKey() const {
51 return current_authenticator_->GetAuthKey();
52}
53
54std::unique_ptr<ChannelAuthenticator>
55ValidatingAuthenticator::CreateChannelAuthenticator() const {
56 return current_authenticator_->CreateChannelAuthenticator();
57}
58
59void ValidatingAuthenticator::ProcessMessage(
Mirko Bonadei80d1cea2019-01-18 22:22:1760 const jingle_xmpp::XmlElement* message,
Evan Stadece9372b2020-03-12 01:28:1661 base::OnceClosure resume_callback) {
joedow7dc48992016-08-31 19:13:3862 DCHECK_EQ(state_, WAITING_MESSAGE);
63 state_ = PROCESSING_MESSAGE;
64
joedowf38c5d72017-03-20 15:55:4665 current_authenticator_->ProcessMessage(
Daniel Cheng28a5ac482021-02-22 21:03:0866 message,
67 base::BindOnce(&ValidatingAuthenticator::UpdateState,
68 weak_factory_.GetWeakPtr(), std::move(resume_callback)));
joedow7dc48992016-08-31 19:13:3869}
70
Mirko Bonadei80d1cea2019-01-18 22:22:1771std::unique_ptr<jingle_xmpp::XmlElement> ValidatingAuthenticator::GetNextMessage() {
joedowf38c5d72017-03-20 15:55:4672 if (pending_auth_message_) {
73 DCHECK(state_ == ACCEPTED || state_ == WAITING_MESSAGE);
74 return std::move(pending_auth_message_);
75 }
76
Mirko Bonadei80d1cea2019-01-18 22:22:1777 std::unique_ptr<jingle_xmpp::XmlElement> result(
joedow7dc48992016-08-31 19:13:3878 current_authenticator_->GetNextMessage());
79 state_ = current_authenticator_->state();
80 DCHECK(state_ == ACCEPTED || state_ == WAITING_MESSAGE);
81
82 return result;
83}
84
Evan Stadece9372b2020-03-12 01:28:1685void ValidatingAuthenticator::OnValidateComplete(base::OnceClosure callback,
joedowf38c5d72017-03-20 15:55:4686 Result validation_result) {
87 // Map |rejection_reason_| to a known reason, set |state_| to REJECTED and
88 // notify the listener of the connection error via the callback.
joedow7dc48992016-08-31 19:13:3889 switch (validation_result) {
joedow5e3932142016-09-03 00:30:3490 case Result::SUCCESS:
joedowf38c5d72017-03-20 15:55:4691 state_ = ACCEPTED;
Evan Stadece9372b2020-03-12 01:28:1692 std::move(callback).Run();
joedow5e3932142016-09-03 00:30:3493 return;
94
joedow7dc48992016-08-31 19:13:3895 case Result::ERROR_INVALID_CREDENTIALS:
Lei Zhang8dea4712022-07-22 16:28:2596 rejection_reason_ = RejectionReason::INVALID_CREDENTIALS;
joedow7dc48992016-08-31 19:13:3897 break;
98
99 case Result::ERROR_INVALID_ACCOUNT:
Lei Zhang8dea4712022-07-22 16:28:25100 rejection_reason_ = RejectionReason::INVALID_ACCOUNT_ID;
joedow7dc48992016-08-31 19:13:38101 break;
102
joedowf38c5d72017-03-20 15:55:46103 case Result::ERROR_TOO_MANY_CONNECTIONS:
Lei Zhang8dea4712022-07-22 16:28:25104 rejection_reason_ = RejectionReason::TOO_MANY_CONNECTIONS;
joedowf38c5d72017-03-20 15:55:46105 break;
106
joedow7dc48992016-08-31 19:13:38107 case Result::ERROR_REJECTED_BY_USER:
Lei Zhang8dea4712022-07-22 16:28:25108 rejection_reason_ = RejectionReason::REJECTED_BY_USER;
joedow7dc48992016-08-31 19:13:38109 break;
joedow7dc48992016-08-31 19:13:38110 }
111
joedow5e3932142016-09-03 00:30:34112 state_ = Authenticator::REJECTED;
Joe Downingc6696f22021-07-16 01:20:55113
114 // Clear the pending message so the signal strategy will generate a new
115 // SESSION_REJECT message in response to this state change.
116 pending_auth_message_.reset();
117
Evan Stadece9372b2020-03-12 01:28:16118 std::move(callback).Run();
joedow7dc48992016-08-31 19:13:38119}
120
Evan Stadece9372b2020-03-12 01:28:16121void ValidatingAuthenticator::UpdateState(base::OnceClosure resume_callback) {
joedow7dc48992016-08-31 19:13:38122 DCHECK_EQ(state_, PROCESSING_MESSAGE);
123
124 // Update our current state before running |resume_callback|.
125 state_ = current_authenticator_->state();
126 if (state_ == REJECTED) {
127 rejection_reason_ = current_authenticator_->rejection_reason();
joedowf38c5d72017-03-20 15:55:46128 } else if (state_ == MESSAGE_READY) {
129 DCHECK(!pending_auth_message_);
130 pending_auth_message_ = current_authenticator_->GetNextMessage();
131 state_ = current_authenticator_->state();
joedow7dc48992016-08-31 19:13:38132 }
133
joedowf38c5d72017-03-20 15:55:46134 if (state_ == ACCEPTED) {
135 state_ = PROCESSING_MESSAGE;
Joe Downingd2819902020-04-27 23:38:46136 validation_callback_.Run(
137 remote_jid_,
138 base::BindOnce(&ValidatingAuthenticator::OnValidateComplete,
Daniel Cheng28a5ac482021-02-22 21:03:08139 weak_factory_.GetWeakPtr(), std::move(resume_callback)));
joedowf38c5d72017-03-20 15:55:46140 } else {
Evan Stadece9372b2020-03-12 01:28:16141 std::move(resume_callback).Run();
joedowf38c5d72017-03-20 15:55:46142 }
joedow7dc48992016-08-31 19:13:38143}
144
145} // namespace protocol
146} // namespace remoting