123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- // const Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "remoting/protocol/fake_authenticator.h"
- #include <memory>
- #include <utility>
- #include "base/base64.h"
- #include "base/bind.h"
- #include "base/rand_util.h"
- #include "base/strings/string_number_conversions.h"
- #include "net/base/io_buffer.h"
- #include "net/base/net_errors.h"
- #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
- #include "remoting/base/constants.h"
- #include "remoting/protocol/p2p_stream_socket.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
- namespace remoting {
- namespace protocol {
- FakeChannelAuthenticator::FakeChannelAuthenticator(bool accept, bool async)
- : result_(accept ? net::OK : net::ERR_FAILED), async_(async) {}
- FakeChannelAuthenticator::~FakeChannelAuthenticator() = default;
- void FakeChannelAuthenticator::SecureAndAuthenticate(
- std::unique_ptr<P2PStreamSocket> socket,
- DoneCallback done_callback) {
- socket_ = std::move(socket);
- done_callback_ = std::move(done_callback);
- if (async_) {
- if (result_ != net::OK) {
- // Don't write anything if we are going to reject auth to make test
- // ordering deterministic.
- did_write_bytes_ = true;
- } else {
- scoped_refptr<net::IOBuffer> write_buf =
- base::MakeRefCounted<net::IOBuffer>(1);
- write_buf->data()[0] = 0;
- int result = socket_->Write(
- write_buf.get(), 1,
- base::BindOnce(&FakeChannelAuthenticator::OnAuthBytesWritten,
- weak_factory_.GetWeakPtr()),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- if (result != net::ERR_IO_PENDING) {
- // This will not call the callback because |did_read_bytes_| is
- // still set to false.
- OnAuthBytesWritten(result);
- }
- }
- scoped_refptr<net::IOBuffer> read_buf =
- base::MakeRefCounted<net::IOBuffer>(1);
- int result =
- socket_->Read(read_buf.get(), 1,
- base::BindOnce(&FakeChannelAuthenticator::OnAuthBytesRead,
- weak_factory_.GetWeakPtr()));
- if (result != net::ERR_IO_PENDING)
- OnAuthBytesRead(result);
- } else {
- CallDoneCallback();
- }
- }
- void FakeChannelAuthenticator::OnAuthBytesWritten(int result) {
- EXPECT_EQ(1, result);
- EXPECT_FALSE(did_write_bytes_);
- did_write_bytes_ = true;
- if (did_read_bytes_)
- CallDoneCallback();
- }
- void FakeChannelAuthenticator::OnAuthBytesRead(int result) {
- EXPECT_EQ(1, result);
- EXPECT_FALSE(did_read_bytes_);
- did_read_bytes_ = true;
- if (did_write_bytes_)
- CallDoneCallback();
- }
- void FakeChannelAuthenticator::CallDoneCallback() {
- if (result_ != net::OK)
- socket_.reset();
- std::move(done_callback_).Run(result_, std::move(socket_));
- }
- FakeAuthenticator::Config::Config() = default;
- FakeAuthenticator::Config::Config(Action action) : action(action) {}
- FakeAuthenticator::Config::Config(int round_trips, Action action, bool async)
- : round_trips(round_trips), action(action), async(async) {}
- FakeAuthenticator::FakeAuthenticator(Type type,
- FakeAuthenticator::Config config,
- const std::string& local_id,
- const std::string& remote_id)
- : type_(type), config_(config), local_id_(local_id), remote_id_(remote_id) {
- EXPECT_TRUE((!local_id_.empty() && !remote_id_.empty()) ||
- config.round_trips == 0);
- }
- FakeAuthenticator::FakeAuthenticator(Action action)
- : FakeAuthenticator(CLIENT,
- FakeAuthenticator::Config(0, action, true),
- std::string(),
- std::string()) {}
- FakeAuthenticator::~FakeAuthenticator() = default;
- void FakeAuthenticator::set_messages_till_started(int messages) {
- messages_till_started_ = messages;
- }
- void FakeAuthenticator::Resume() {
- std::move(resume_closure_).Run();
- }
- Authenticator::State FakeAuthenticator::state() const {
- EXPECT_LE(messages_, config_.round_trips * 2);
- if (messages_ == pause_message_index_ && !resume_closure_.is_null())
- return PROCESSING_MESSAGE;
- if (messages_ >= config_.round_trips * 2) {
- if (config_.action == REJECT) {
- return REJECTED;
- } else {
- return ACCEPTED;
- }
- }
- // Don't send the last message if this is a host that wants to
- // reject a connection.
- if (messages_ == config_.round_trips * 2 - 1 && type_ == HOST &&
- config_.action == REJECT) {
- return REJECTED;
- }
- // We are not done yet. process next message.
- if ((messages_ % 2 == 0 && type_ == CLIENT) ||
- (messages_ % 2 == 1 && type_ == HOST)) {
- return MESSAGE_READY;
- } else {
- return WAITING_MESSAGE;
- }
- }
- bool FakeAuthenticator::started() const {
- return messages_ > messages_till_started_;
- }
- Authenticator::RejectionReason FakeAuthenticator::rejection_reason() const {
- EXPECT_EQ(REJECTED, state());
- return RejectionReason::INVALID_CREDENTIALS;
- }
- void FakeAuthenticator::ProcessMessage(const jingle_xmpp::XmlElement* message,
- base::OnceClosure resume_callback) {
- EXPECT_EQ(WAITING_MESSAGE, state());
- std::string id =
- message->TextNamed(jingle_xmpp::QName(kChromotingXmlNamespace, "id"));
- EXPECT_EQ(id, base::NumberToString(messages_));
- // On the client receive the key in the last message.
- if (type_ == CLIENT && messages_ == config_.round_trips * 2 - 1) {
- std::string key_base64 =
- message->TextNamed(jingle_xmpp::QName(kChromotingXmlNamespace, "key"));
- EXPECT_TRUE(!key_base64.empty());
- EXPECT_TRUE(base::Base64Decode(key_base64, &auth_key_));
- }
- // Receive peer's id.
- if (messages_ < 2) {
- EXPECT_EQ(remote_id_, message->Attr(jingle_xmpp::QName("", "id")));
- }
- ++messages_;
- if (messages_ == pause_message_index_) {
- resume_closure_ = std::move(resume_callback);
- return;
- }
- std::move(resume_callback).Run();
- }
- std::unique_ptr<jingle_xmpp::XmlElement> FakeAuthenticator::GetNextMessage() {
- EXPECT_EQ(MESSAGE_READY, state());
- std::unique_ptr<jingle_xmpp::XmlElement> result(new jingle_xmpp::XmlElement(
- jingle_xmpp::QName(kChromotingXmlNamespace, "authentication")));
- jingle_xmpp::XmlElement* id = new jingle_xmpp::XmlElement(
- jingle_xmpp::QName(kChromotingXmlNamespace, "id"));
- id->AddText(base::NumberToString(messages_));
- result->AddElement(id);
- // Send local id in the first outgoing message.
- if (messages_ < 2) {
- result->AddAttr(jingle_xmpp::QName("", "id"), local_id_);
- }
- // Add authentication key in the last message sent from host to client.
- if (type_ == HOST && messages_ == config_.round_trips * 2 - 1) {
- auth_key_ = base::RandBytesAsString(16);
- jingle_xmpp::XmlElement* key = new jingle_xmpp::XmlElement(
- jingle_xmpp::QName(kChromotingXmlNamespace, "key"));
- std::string key_base64;
- base::Base64Encode(auth_key_, &key_base64);
- key->AddText(key_base64);
- result->AddElement(key);
- }
- ++messages_;
- return result;
- }
- const std::string& FakeAuthenticator::GetAuthKey() const {
- EXPECT_EQ(ACCEPTED, state());
- DCHECK(!auth_key_.empty());
- return auth_key_;
- }
- std::unique_ptr<ChannelAuthenticator>
- FakeAuthenticator::CreateChannelAuthenticator() const {
- EXPECT_EQ(ACCEPTED, state());
- return std::make_unique<FakeChannelAuthenticator>(
- config_.action != REJECT_CHANNEL, config_.async);
- }
- FakeHostAuthenticatorFactory::FakeHostAuthenticatorFactory(
- int messages_till_started,
- FakeAuthenticator::Config config)
- : messages_till_started_(messages_till_started), config_(config) {}
- FakeHostAuthenticatorFactory::~FakeHostAuthenticatorFactory() = default;
- std::unique_ptr<Authenticator>
- FakeHostAuthenticatorFactory::CreateAuthenticator(
- const std::string& local_jid,
- const std::string& remote_jid) {
- std::unique_ptr<FakeAuthenticator> authenticator(new FakeAuthenticator(
- FakeAuthenticator::HOST, config_, local_jid, remote_jid));
- authenticator->set_messages_till_started(messages_till_started_);
- return std::move(authenticator);
- }
- } // namespace protocol
- } // namespace remoting
|