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
3 // found in the LICENSE file.
6 #include "base/callback_helpers.h"
7 #include "net/base/net_errors.h"
8 #include "remoting/base/rsa_key_pair.h"
9 #include "remoting/protocol/authenticator_test_base.h"
10 #include "remoting/protocol/channel_authenticator.h"
11 #include "remoting/protocol/connection_tester.h"
12 #include "remoting/protocol/fake_authenticator.h"
13 #include "remoting/protocol/third_party_authenticator_base.h"
14 #include "remoting/protocol/third_party_client_authenticator.h"
15 #include "remoting/protocol/third_party_host_authenticator.h"
16 #include "remoting/protocol/token_validator.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
22 using testing::DeleteArg
;
23 using testing::SaveArg
;
27 const int kMessageSize
= 100;
28 const int kMessages
= 1;
30 const char kTokenUrl
[] = "https://example.com/Issue";
31 const char kTokenScope
[] = "host:a@b.com/1 client:a@b.com/2";
32 const char kToken
[] = "abc123456xyz789";
33 const char kSharedSecret
[] = "1234-1234-5678";
34 const char kSharedSecretBad
[] = "0000-0000-0001";
41 class ThirdPartyAuthenticatorTest
: public AuthenticatorTestBase
{
42 class FakeTokenFetcher
: public ThirdPartyClientAuthenticator::TokenFetcher
{
44 void FetchThirdPartyToken(
45 const GURL
& token_url
,
46 const std::string
& scope
,
47 const TokenFetchedCallback
& token_fetched_callback
) override
{
48 ASSERT_EQ(token_url
.spec(), kTokenUrl
);
49 ASSERT_EQ(scope
, kTokenScope
);
50 ASSERT_FALSE(token_fetched_callback
.is_null());
51 on_token_fetched_
= token_fetched_callback
;
54 void OnTokenFetched(const std::string
& token
,
55 const std::string
& shared_secret
) {
56 ASSERT_FALSE(on_token_fetched_
.is_null());
57 base::ResetAndReturn(&on_token_fetched_
).Run(token
, shared_secret
);
61 TokenFetchedCallback on_token_fetched_
;
64 class FakeTokenValidator
: public TokenValidator
{
67 : token_url_(kTokenUrl
),
68 token_scope_(kTokenScope
) {}
70 ~FakeTokenValidator() override
{}
72 void ValidateThirdPartyToken(
73 const std::string
& token
,
74 const TokenValidatedCallback
& token_validated_callback
) override
{
75 ASSERT_FALSE(token_validated_callback
.is_null());
76 on_token_validated_
= token_validated_callback
;
79 void OnTokenValidated(const std::string
& shared_secret
) {
80 ASSERT_FALSE(on_token_validated_
.is_null());
81 base::ResetAndReturn(&on_token_validated_
).Run(shared_secret
);
84 const GURL
& token_url() const override
{ return token_url_
; }
86 const std::string
& token_scope() const override
{ return token_scope_
; }
90 std::string token_scope_
;
91 base::Callback
<void(const std::string
& shared_secret
)> on_token_validated_
;
95 ThirdPartyAuthenticatorTest() {}
96 ~ThirdPartyAuthenticatorTest() override
{}
99 void InitAuthenticators() {
100 scoped_ptr
<TokenValidator
> token_validator(new FakeTokenValidator());
101 token_validator_
= static_cast<FakeTokenValidator
*>(token_validator
.get());
102 host_
.reset(new ThirdPartyHostAuthenticator(
103 host_cert_
, key_pair_
, token_validator
.Pass()));
104 scoped_ptr
<ThirdPartyClientAuthenticator::TokenFetcher
>
105 token_fetcher(new FakeTokenFetcher());
106 token_fetcher_
= static_cast<FakeTokenFetcher
*>(token_fetcher
.get());
107 client_
.reset(new ThirdPartyClientAuthenticator(token_fetcher
.Pass()));
110 FakeTokenFetcher
* token_fetcher_
;
111 FakeTokenValidator
* token_validator_
;
114 DISALLOW_COPY_AND_ASSIGN(ThirdPartyAuthenticatorTest
);
117 TEST_F(ThirdPartyAuthenticatorTest
, SuccessfulAuth
) {
118 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
119 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
120 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, client_
->state());
121 ASSERT_NO_FATAL_FAILURE(token_fetcher_
->OnTokenFetched(
122 kToken
, kSharedSecret
));
123 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, host_
->state());
124 ASSERT_NO_FATAL_FAILURE(
125 token_validator_
->OnTokenValidated(kSharedSecret
));
127 // Both sides have finished.
128 ASSERT_EQ(Authenticator::ACCEPTED
, host_
->state());
129 ASSERT_EQ(Authenticator::ACCEPTED
, client_
->state());
131 // An authenticated channel can be created after the authentication.
132 client_auth_
= client_
->CreateChannelAuthenticator();
133 host_auth_
= host_
->CreateChannelAuthenticator();
134 RunChannelAuth(false);
136 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
137 kMessageSize
, kMessages
);
141 tester
.CheckResults();
144 TEST_F(ThirdPartyAuthenticatorTest
, ClientNoSecret
) {
145 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
146 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
147 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, client_
->state());
148 ASSERT_NO_FATAL_FAILURE(
149 token_fetcher_
->OnTokenFetched(kToken
, std::string()));
151 // The end result is that the client rejected the connection, since it
152 // couldn't fetch the secret.
153 ASSERT_EQ(Authenticator::REJECTED
, client_
->state());
156 TEST_F(ThirdPartyAuthenticatorTest
, InvalidToken
) {
157 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
158 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
159 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, client_
->state());
160 ASSERT_NO_FATAL_FAILURE(token_fetcher_
->OnTokenFetched(
161 kToken
, kSharedSecret
));
162 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, host_
->state());
163 ASSERT_NO_FATAL_FAILURE(token_validator_
->OnTokenValidated(std::string()));
165 // The end result is that the host rejected the token.
166 ASSERT_EQ(Authenticator::REJECTED
, host_
->state());
169 TEST_F(ThirdPartyAuthenticatorTest
, CannotFetchToken
) {
170 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
171 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
172 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, client_
->state());
173 ASSERT_NO_FATAL_FAILURE(
174 token_fetcher_
->OnTokenFetched(std::string(), std::string()));
176 // The end result is that the client rejected the connection, since it
177 // couldn't fetch the token.
178 ASSERT_EQ(Authenticator::REJECTED
, client_
->state());
181 // Test that negotiation stops when the fake authentication is rejected.
182 TEST_F(ThirdPartyAuthenticatorTest
, HostBadSecret
) {
183 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
184 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
185 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, client_
->state());
186 ASSERT_NO_FATAL_FAILURE(token_fetcher_
->OnTokenFetched(
187 kToken
, kSharedSecret
));
188 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, host_
->state());
189 ASSERT_NO_FATAL_FAILURE(
190 token_validator_
->OnTokenValidated(kSharedSecretBad
));
192 // The end result is that the host rejected the fake authentication.
193 ASSERT_EQ(Authenticator::REJECTED
, client_
->state());
196 TEST_F(ThirdPartyAuthenticatorTest
, ClientBadSecret
) {
197 ASSERT_NO_FATAL_FAILURE(InitAuthenticators());
198 ASSERT_NO_FATAL_FAILURE(RunHostInitiatedAuthExchange());
199 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, client_
->state());
200 ASSERT_NO_FATAL_FAILURE(
201 token_fetcher_
->OnTokenFetched(kToken
, kSharedSecretBad
));
202 ASSERT_EQ(Authenticator::PROCESSING_MESSAGE
, host_
->state());
203 ASSERT_NO_FATAL_FAILURE(
204 token_validator_
->OnTokenValidated(kSharedSecret
));
206 // The end result is that the host rejected the fake authentication.
207 ASSERT_EQ(Authenticator::REJECTED
, client_
->state());
210 } // namespace protocol
211 } // namespace remoting