OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/negotiating_host_authenticator.h" | 5 #include "remoting/protocol/negotiating_host_authenticator.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
14 #include "remoting/base/rsa_key_pair.h" | 14 #include "remoting/base/rsa_key_pair.h" |
15 #include "remoting/protocol/channel_authenticator.h" | 15 #include "remoting/protocol/channel_authenticator.h" |
| 16 #include "remoting/protocol/pairing_host_authenticator.h" |
| 17 #include "remoting/protocol/pairing_registry.h" |
16 #include "remoting/protocol/v2_authenticator.h" | 18 #include "remoting/protocol/v2_authenticator.h" |
17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 19 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
18 | 20 |
19 namespace remoting { | 21 namespace remoting { |
20 namespace protocol { | 22 namespace protocol { |
21 | 23 |
22 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator( | 24 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator( |
23 const std::string& local_cert, | 25 const std::string& local_cert, |
24 scoped_refptr<RsaKeyPair> key_pair) | 26 scoped_refptr<RsaKeyPair> key_pair) |
25 : NegotiatingAuthenticatorBase(WAITING_MESSAGE), | 27 : NegotiatingAuthenticatorBase(WAITING_MESSAGE), |
26 local_cert_(local_cert), | 28 local_cert_(local_cert), |
27 local_key_pair_(key_pair) { | 29 local_key_pair_(key_pair) { |
28 } | 30 } |
29 | 31 |
30 // static | 32 // static |
31 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithSharedSecret( | 33 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithSharedSecret( |
32 const std::string& local_cert, | 34 const std::string& local_cert, |
33 scoped_refptr<RsaKeyPair> key_pair, | 35 scoped_refptr<RsaKeyPair> key_pair, |
34 const std::string& shared_secret_hash, | 36 const std::string& shared_secret_hash, |
35 AuthenticationMethod::HashFunction hash_function) { | 37 AuthenticationMethod::HashFunction hash_function, |
| 38 scoped_refptr<PairingRegistry> pairing_registry) { |
36 scoped_ptr<NegotiatingHostAuthenticator> result( | 39 scoped_ptr<NegotiatingHostAuthenticator> result( |
37 new NegotiatingHostAuthenticator(local_cert, key_pair)); | 40 new NegotiatingHostAuthenticator(local_cert, key_pair)); |
38 result->shared_secret_hash_ = shared_secret_hash; | 41 result->shared_secret_hash_ = shared_secret_hash; |
| 42 result->pairing_registry_ = pairing_registry; |
39 result->AddMethod(AuthenticationMethod::Spake2(hash_function)); | 43 result->AddMethod(AuthenticationMethod::Spake2(hash_function)); |
| 44 if (pairing_registry) { |
| 45 result->AddMethod(AuthenticationMethod::Spake2Pair()); |
| 46 } |
40 return scoped_ptr<Authenticator>(result.Pass()); | 47 return scoped_ptr<Authenticator>(result.Pass()); |
41 } | 48 } |
42 | 49 |
43 // static | 50 // static |
44 scoped_ptr<Authenticator> | 51 scoped_ptr<Authenticator> |
45 NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( | 52 NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( |
46 const std::string& local_cert, | 53 const std::string& local_cert, |
47 scoped_refptr<RsaKeyPair> key_pair, | 54 scoped_refptr<RsaKeyPair> key_pair, |
48 scoped_ptr<ThirdPartyHostAuthenticator::TokenValidator> token_validator) { | 55 scoped_ptr<ThirdPartyHostAuthenticator::TokenValidator> token_validator) { |
49 scoped_ptr<NegotiatingHostAuthenticator> result( | 56 scoped_ptr<NegotiatingHostAuthenticator> result( |
(...skipping 15 matching lines...) Expand all Loading... |
65 AuthenticationMethod method = AuthenticationMethod::FromString(method_attr); | 72 AuthenticationMethod method = AuthenticationMethod::FromString(method_attr); |
66 | 73 |
67 // If the host has already chosen a method, it can't be changed by the client. | 74 // If the host has already chosen a method, it can't be changed by the client. |
68 if (current_method_.is_valid() && method != current_method_) { | 75 if (current_method_.is_valid() && method != current_method_) { |
69 state_ = REJECTED; | 76 state_ = REJECTED; |
70 rejection_reason_ = PROTOCOL_ERROR; | 77 rejection_reason_ = PROTOCOL_ERROR; |
71 resume_callback.Run(); | 78 resume_callback.Run(); |
72 return; | 79 return; |
73 } | 80 } |
74 | 81 |
75 // If the client did not specify auth method or specified unknown method, | 82 // If the client did not specify a preferred auth method, or specified an |
76 // then select the first known method from the supported-methods attribute. | 83 // unknown or unsupported method, then select the first known method from |
| 84 // the supported-methods attribute. |
77 if (!method.is_valid() || | 85 if (!method.is_valid() || |
78 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { | 86 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { |
79 method = AuthenticationMethod::Invalid(); | 87 method = AuthenticationMethod::Invalid(); |
80 | 88 |
81 std::string supported_methods_attr = | 89 std::string supported_methods_attr = |
82 message->Attr(kSupportedMethodsAttributeQName); | 90 message->Attr(kSupportedMethodsAttributeQName); |
83 if (supported_methods_attr.empty()) { | 91 if (supported_methods_attr.empty()) { |
84 // Message contains neither method nor supported-methods attributes. | 92 // Message contains neither method nor supported-methods attributes. |
85 state_ = REJECTED; | 93 state_ = REJECTED; |
86 rejection_reason_ = PROTOCOL_ERROR; | 94 rejection_reason_ = PROTOCOL_ERROR; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 const base::Closure& resume_callback) { | 156 const base::Closure& resume_callback) { |
149 DCHECK(current_method_.is_valid()); | 157 DCHECK(current_method_.is_valid()); |
150 | 158 |
151 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { | 159 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { |
152 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. | 160 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. |
153 // The authentication method negotiation logic should guarantee that only | 161 // The authentication method negotiation logic should guarantee that only |
154 // one |ThirdPartyHostAuthenticator| will need to be created per session. | 162 // one |ThirdPartyHostAuthenticator| will need to be created per session. |
155 DCHECK(token_validator_); | 163 DCHECK(token_validator_); |
156 current_authenticator_.reset(new ThirdPartyHostAuthenticator( | 164 current_authenticator_.reset(new ThirdPartyHostAuthenticator( |
157 local_cert_, local_key_pair_, token_validator_.Pass())); | 165 local_cert_, local_key_pair_, token_validator_.Pass())); |
| 166 } else if (current_method_ == AuthenticationMethod::Spake2Pair() && |
| 167 preferred_initial_state == WAITING_MESSAGE) { |
| 168 // If the client requested Spake2Pair and sent an initial message, attempt |
| 169 // the paired connection protocol. |
| 170 current_authenticator_.reset(new PairingHostAuthenticator( |
| 171 pairing_registry_, local_cert_, local_key_pair_, shared_secret_hash_)); |
158 } else { | 172 } else { |
| 173 // In all other cases, use the V2 protocol. Note that this includes the |
| 174 // case where the protocol is Spake2Pair but the client is not yet paired. |
| 175 // In this case, the on-the-wire protocol is plain Spake2, advertised as |
| 176 // Spake2Pair so that the client knows that the host supports pairing and |
| 177 // that it can therefore present the option to the user when they enter |
| 178 // the PIN. |
| 179 DCHECK(current_method_.type() == AuthenticationMethod::SPAKE2 || |
| 180 current_method_.type() == AuthenticationMethod::SPAKE2_PAIR); |
159 current_authenticator_ = V2Authenticator::CreateForHost( | 181 current_authenticator_ = V2Authenticator::CreateForHost( |
160 local_cert_, local_key_pair_, shared_secret_hash_, | 182 local_cert_, local_key_pair_, shared_secret_hash_, |
161 preferred_initial_state); | 183 preferred_initial_state); |
162 } | 184 } |
163 | |
164 resume_callback.Run(); | 185 resume_callback.Run(); |
165 } | 186 } |
166 | 187 |
167 } // namespace protocol | 188 } // namespace protocol |
168 } // namespace remoting | 189 } // namespace remoting |
OLD | NEW |