blob: 38f8127307c43c06873637f240675c9969359f26 [file] [log] [blame]
[email protected]9a6361d02013-03-23 16:27:521// Copyright 2013 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
sergeyu89d088b2015-12-24 00:22:445#include <utility>
6
[email protected]9a6361d02013-03-23 16:27:527#include "base/bind.h"
sergeyud9bdcb62015-04-25 00:18:088#include "base/callback_helpers.h"
avi5a080f012015-12-22 23:15:439#include "base/macros.h"
dcheng0765c492016-04-06 22:41:5310#include "base/memory/ptr_util.h"
fdoray2ad58be2016-06-22 20:36:1611#include "base/run_loop.h"
[email protected]9a6361d02013-03-23 16:27:5212#include "net/base/net_errors.h"
13#include "remoting/base/rsa_key_pair.h"
14#include "remoting/protocol/authenticator_test_base.h"
15#include "remoting/protocol/channel_authenticator.h"
16#include "remoting/protocol/connection_tester.h"
17#include "remoting/protocol/fake_authenticator.h"
18#include "remoting/protocol/third_party_authenticator_base.h"
19#include "remoting/protocol/third_party_client_authenticator.h"
20#include "remoting/protocol/third_party_host_authenticator.h"
[email protected]d95ee262014-02-26 06:30:3121#include "remoting/protocol/token_validator.h"
sergeyu12e320a2016-03-08 18:10:2822#include "remoting/protocol/v2_authenticator.h"
[email protected]9a6361d02013-03-23 16:27:5223#include "testing/gmock/include/gmock/gmock.h"
24#include "testing/gtest/include/gtest/gtest.h"
kjellanderf0e410b2017-01-04 14:45:0125#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
[email protected]9a6361d02013-03-23 16:27:5226
27using testing::_;
28using testing::DeleteArg;
29using testing::SaveArg;
30
31namespace {
32
33const int kMessageSize = 100;
34const int kMessages = 1;
35
36const char kTokenUrl[] = "https://example.com/Issue";
37const char kTokenScope[] = "host:[email protected]/1 client:[email protected]/2";
38const char kToken[] = "abc123456xyz789";
39const char kSharedSecret[] = "1234-1234-5678";
40const char kSharedSecretBad[] = "0000-0000-0001";
41
42} // namespace
43
44namespace remoting {
45namespace protocol {
46
47class ThirdPartyAuthenticatorTest : public AuthenticatorTestBase {
sergeyu1acf67ba2016-03-10 02:59:1448 class FakeTokenFetcher {
[email protected]9a6361d02013-03-23 16:27:5249 public:
dcheng562aba52014-10-21 12:30:1450 void FetchThirdPartyToken(
sergeyu1acf67ba2016-03-10 02:59:1451 const std::string& token_url,
[email protected]9a6361d02013-03-23 16:27:5252 const std::string& scope,
sergeyu1acf67ba2016-03-10 02:59:1453 const ThirdPartyTokenFetchedCallback& token_fetched_callback) {
54 ASSERT_EQ(token_url, kTokenUrl);
55 ASSERT_EQ(scope, kTokenScope);
56 ASSERT_FALSE(token_fetched_callback.is_null());
57 on_token_fetched_ = token_fetched_callback;
[email protected]9a6361d02013-03-23 16:27:5258 }
59
60 void OnTokenFetched(const std::string& token,
61 const std::string& shared_secret) {
62 ASSERT_FALSE(on_token_fetched_.is_null());
sergeyud9bdcb62015-04-25 00:18:0863 base::ResetAndReturn(&on_token_fetched_).Run(token, shared_secret);
[email protected]9a6361d02013-03-23 16:27:5264 }
65
66 private:
sergeyu1acf67ba2016-03-10 02:59:1467 ThirdPartyTokenFetchedCallback on_token_fetched_;
[email protected]9a6361d02013-03-23 16:27:5268 };
69
[email protected]d95ee262014-02-26 06:30:3170 class FakeTokenValidator : public TokenValidator {
[email protected]9a6361d02013-03-23 16:27:5271 public:
72 FakeTokenValidator()
73 : token_url_(kTokenUrl),
74 token_scope_(kTokenScope) {}
75
Chris Watkins6fe52aa2017-11-28 03:24:0576 ~FakeTokenValidator() override = default;
[email protected]9a6361d02013-03-23 16:27:5277
dcheng562aba52014-10-21 12:30:1478 void ValidateThirdPartyToken(
[email protected]9a6361d02013-03-23 16:27:5279 const std::string& token,
mostynb4faccee2014-10-09 09:33:2580 const TokenValidatedCallback& token_validated_callback) override {
[email protected]9a6361d02013-03-23 16:27:5281 ASSERT_FALSE(token_validated_callback.is_null());
82 on_token_validated_ = token_validated_callback;
83 }
84
85 void OnTokenValidated(const std::string& shared_secret) {
86 ASSERT_FALSE(on_token_validated_.is_null());
sergeyud9bdcb62015-04-25 00:18:0887 base::ResetAndReturn(&on_token_validated_).Run(shared_secret);
[email protected]9a6361d02013-03-23 16:27:5288 }
89
dcheng562aba52014-10-21 12:30:1490 const GURL& token_url() const override { return token_url_; }
[email protected]9a6361d02013-03-23 16:27:5291
dcheng562aba52014-10-21 12:30:1492 const std::string& token_scope() const override { return token_scope_; }
[email protected]9a6361d02013-03-23 16:27:5293
94 private:
95 GURL token_url_;
96 std::string token_scope_;
97 base::Callback<void(const std::string& shared_secret)> on_token_validated_;
98 };
99
100 public:
Chris Watkins6fe52aa2017-11-28 03:24:05101 ThirdPartyAuthenticatorTest() = default;
102 ~ThirdPartyAuthenticatorTest() override = default;
[email protected]9a6361d02013-03-23 16:27:52103
104 protected:
105 void InitAuthenticators() {
sergeyu12e320a2016-03-08 18:10:28106 token_validator_ = new FakeTokenValidator();
[email protected]9a6361d02013-03-23 16:27:52107 host_.reset(new ThirdPartyHostAuthenticator(
sergeyu12e320a2016-03-08 18:10:28108 base::Bind(&V2Authenticator::CreateForHost, host_cert_, key_pair_),
dcheng0765c492016-04-06 22:41:53109 base::WrapUnique(token_validator_)));
sergeyu12e320a2016-03-08 18:10:28110 client_.reset(new ThirdPartyClientAuthenticator(
111 base::Bind(&V2Authenticator::CreateForClient),
sergeyu1acf67ba2016-03-10 02:59:14112 base::Bind(&FakeTokenFetcher::FetchThirdPartyToken,
113 base::Unretained(&token_fetcher_))));
[email protected]9a6361d02013-03-23 16:27:52114 }
115
sergeyu1acf67ba2016-03-10 02:59:14116 FakeTokenFetcher token_fetcher_;
[email protected]9a6361d02013-03-23 16:27:52117 FakeTokenValidator* token_validator_;
118
119 private:
120 DISALLOW_COPY_AND_ASSIGN(ThirdPartyAuthenticatorTest);
121};
122
[email protected]591cffcd2014-08-18 20:02:30123TEST_F(ThirdPartyAuthenticatorTest, SuccessfulAuth) {
[email protected]9a6361d02013-03-23 16:27:52124 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
125 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
126 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state());
sergeyu1acf67ba2016-03-10 02:59:14127 ASSERT_NO_FATAL_FAILURE(token_fetcher_.OnTokenFetched(kToken, kSharedSecret));
[email protected]9a6361d02013-03-23 16:27:52128 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state());
sergeyu1acf67ba2016-03-10 02:59:14129 ASSERT_NO_FATAL_FAILURE(token_validator_->OnTokenValidated(kSharedSecret));
[email protected]9a6361d02013-03-23 16:27:52130
131 // Both sides have finished.
132 ASSERT_EQ(Authenticator::ACCEPTED, host_->state());
133 ASSERT_EQ(Authenticator::ACCEPTED, client_->state());
134
135 // An authenticated channel can be created after the authentication.
136 client_auth_ = client_->CreateChannelAuthenticator();
137 host_auth_ = host_->CreateChannelAuthenticator();
138 RunChannelAuth(false);
139
140 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
141 kMessageSize, kMessages);
142
143 tester.Start();
fdoray2ad58be2016-06-22 20:36:16144 base::RunLoop().Run();
[email protected]9a6361d02013-03-23 16:27:52145 tester.CheckResults();
146}
147
[email protected]591cffcd2014-08-18 20:02:30148TEST_F(ThirdPartyAuthenticatorTest, ClientNoSecret) {
[email protected]9a6361d02013-03-23 16:27:52149 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
150 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
151 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state());
sergeyu1acf67ba2016-03-10 02:59:14152 ASSERT_NO_FATAL_FAILURE(token_fetcher_.OnTokenFetched(kToken, std::string()));
[email protected]9a6361d02013-03-23 16:27:52153
154 // The end result is that the client rejected the connection, since it
155 // couldn't fetch the secret.
156 ASSERT_EQ(Authenticator::REJECTED, client_->state());
157}
158
[email protected]591cffcd2014-08-18 20:02:30159TEST_F(ThirdPartyAuthenticatorTest, InvalidToken) {
[email protected]9a6361d02013-03-23 16:27:52160 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
161 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
162 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state());
sergeyu1acf67ba2016-03-10 02:59:14163 ASSERT_NO_FATAL_FAILURE(token_fetcher_.OnTokenFetched(
[email protected]9a6361d02013-03-23 16:27:52164 kToken, kSharedSecret));
165 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state());
[email protected]007b3f82013-04-09 08:46:45166 ASSERT_NO_FATAL_FAILURE(token_validator_->OnTokenValidated(std::string()));
[email protected]9a6361d02013-03-23 16:27:52167
168 // The end result is that the host rejected the token.
169 ASSERT_EQ(Authenticator::REJECTED, host_->state());
170}
171
[email protected]591cffcd2014-08-18 20:02:30172TEST_F(ThirdPartyAuthenticatorTest, CannotFetchToken) {
[email protected]9a6361d02013-03-23 16:27:52173 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
174 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
175 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state());
[email protected]007b3f82013-04-09 08:46:45176 ASSERT_NO_FATAL_FAILURE(
sergeyu1acf67ba2016-03-10 02:59:14177 token_fetcher_.OnTokenFetched(std::string(), std::string()));
[email protected]9a6361d02013-03-23 16:27:52178
179 // The end result is that the client rejected the connection, since it
180 // couldn't fetch the token.
181 ASSERT_EQ(Authenticator::REJECTED, client_->state());
182}
183
184// Test that negotiation stops when the fake authentication is rejected.
[email protected]591cffcd2014-08-18 20:02:30185TEST_F(ThirdPartyAuthenticatorTest, HostBadSecret) {
[email protected]9a6361d02013-03-23 16:27:52186 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
187 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
188 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state());
sergeyu1acf67ba2016-03-10 02:59:14189 ASSERT_NO_FATAL_FAILURE(token_fetcher_.OnTokenFetched(kToken, kSharedSecret));
[email protected]9a6361d02013-03-23 16:27:52190 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state());
191 ASSERT_NO_FATAL_FAILURE(
192 token_validator_->OnTokenValidated(kSharedSecretBad));
193
194 // The end result is that the host rejected the fake authentication.
195 ASSERT_EQ(Authenticator::REJECTED, client_->state());
196}
197
[email protected]591cffcd2014-08-18 20:02:30198TEST_F(ThirdPartyAuthenticatorTest, ClientBadSecret) {
[email protected]9a6361d02013-03-23 16:27:52199 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
200 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
201 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state());
202 ASSERT_NO_FATAL_FAILURE(
sergeyu1acf67ba2016-03-10 02:59:14203 token_fetcher_.OnTokenFetched(kToken, kSharedSecretBad));
[email protected]9a6361d02013-03-23 16:27:52204 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state());
205 ASSERT_NO_FATAL_FAILURE(
206 token_validator_->OnTokenValidated(kSharedSecret));
207
208 // The end result is that the host rejected the fake authentication.
209 ASSERT_EQ(Authenticator::REJECTED, client_->state());
210}
211
212} // namespace protocol
213} // namespace remoting