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/v2_authenticator.h" | 16 #include "remoting/protocol/v2_authenticator.h" |
17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
18 | 18 |
19 namespace remoting { | 19 namespace remoting { |
20 namespace protocol { | 20 namespace protocol { |
21 | 21 |
22 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator( | 22 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator( |
23 const std::string& local_cert, | 23 const std::string& local_cert, |
| 24 scoped_refptr<RsaKeyPair> key_pair) |
| 25 : NegotiatingAuthenticatorBase(WAITING_MESSAGE), |
| 26 local_cert_(local_cert), |
| 27 local_key_pair_(key_pair) { |
| 28 } |
| 29 |
| 30 // static |
| 31 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithSharedSecret( |
| 32 const std::string& local_cert, |
24 scoped_refptr<RsaKeyPair> key_pair, | 33 scoped_refptr<RsaKeyPair> key_pair, |
25 const std::string& shared_secret_hash, | 34 const std::string& shared_secret_hash, |
26 AuthenticationMethod::HashFunction hash_function) | 35 AuthenticationMethod::HashFunction hash_function) { |
27 : NegotiatingAuthenticatorBase(WAITING_MESSAGE), | 36 scoped_ptr<NegotiatingHostAuthenticator> result( |
28 local_cert_(local_cert), | 37 new NegotiatingHostAuthenticator(local_cert, key_pair)); |
29 local_key_pair_(key_pair), | 38 result->shared_secret_hash_ = shared_secret_hash; |
30 shared_secret_hash_(shared_secret_hash) { | 39 result->AddMethod(AuthenticationMethod::Spake2(hash_function)); |
| 40 return scoped_ptr<Authenticator>(result.Pass()); |
| 41 } |
31 | 42 |
32 AddMethod(AuthenticationMethod::Spake2(hash_function)); | 43 // static |
| 44 scoped_ptr<Authenticator> |
| 45 NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( |
| 46 const std::string& local_cert, |
| 47 scoped_refptr<RsaKeyPair> key_pair, |
| 48 scoped_ptr<ThirdPartyHostAuthenticator::TokenValidator> token_validator) { |
| 49 scoped_ptr<NegotiatingHostAuthenticator> result( |
| 50 new NegotiatingHostAuthenticator(local_cert, key_pair)); |
| 51 result->token_validator_ = token_validator.Pass(); |
| 52 result->AddMethod(AuthenticationMethod::ThirdParty()); |
| 53 return scoped_ptr<Authenticator>(result.Pass()); |
33 } | 54 } |
34 | 55 |
35 NegotiatingHostAuthenticator::~NegotiatingHostAuthenticator() { | 56 NegotiatingHostAuthenticator::~NegotiatingHostAuthenticator() { |
36 } | 57 } |
37 | 58 |
38 void NegotiatingHostAuthenticator::ProcessMessage( | 59 void NegotiatingHostAuthenticator::ProcessMessage( |
39 const buzz::XmlElement* message, | 60 const buzz::XmlElement* message, |
40 const base::Closure& resume_callback) { | 61 const base::Closure& resume_callback) { |
41 DCHECK_EQ(state(), WAITING_MESSAGE); | 62 DCHECK_EQ(state(), WAITING_MESSAGE); |
42 | 63 |
43 std::string method_attr = message->Attr(kMethodAttributeQName); | 64 std::string method_attr = message->Attr(kMethodAttributeQName); |
44 AuthenticationMethod method = AuthenticationMethod::FromString(method_attr); | 65 AuthenticationMethod method = AuthenticationMethod::FromString(method_attr); |
45 | 66 |
46 // If the host has already chosen a method, it can't be changed by the client. | 67 // If the host has already chosen a method, it can't be changed by the client. |
47 if (current_method_.is_valid() && method != current_method_) { | 68 if (current_method_.is_valid() && method != current_method_) { |
48 state_ = REJECTED; | 69 state_ = REJECTED; |
49 rejection_reason_ = PROTOCOL_ERROR; | 70 rejection_reason_ = PROTOCOL_ERROR; |
50 resume_callback.Run(); | 71 resume_callback.Run(); |
51 return; | 72 return; |
52 } | 73 } |
53 | 74 |
54 // If the client did not specify auth method or specified unknown method, | 75 // If the client did not specify auth method or specified unknown method, |
55 // then select the first known method from the supported-methods attribute. | 76 // then select the first known method from the supported-methods attribute. |
56 if (!method.is_valid() || | 77 if (!method.is_valid() || |
57 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { | 78 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { |
58 | |
59 method = AuthenticationMethod::Invalid(); | 79 method = AuthenticationMethod::Invalid(); |
60 | 80 |
61 std::string supported_methods_attr = | 81 std::string supported_methods_attr = |
62 message->Attr(kSupportedMethodsAttributeQName); | 82 message->Attr(kSupportedMethodsAttributeQName); |
63 if (supported_methods_attr.empty()) { | 83 if (supported_methods_attr.empty()) { |
64 // Message contains neither method nor supported-methods attributes. | 84 // Message contains neither method nor supported-methods attributes. |
65 state_ = REJECTED; | 85 state_ = REJECTED; |
66 rejection_reason_ = PROTOCOL_ERROR; | 86 rejection_reason_ = PROTOCOL_ERROR; |
67 resume_callback.Run(); | 87 resume_callback.Run(); |
68 return; | 88 return; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 ProcessMessageInternal(message, resume_callback); | 139 ProcessMessageInternal(message, resume_callback); |
120 } | 140 } |
121 | 141 |
122 scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() { | 142 scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() { |
123 return GetNextMessageInternal(); | 143 return GetNextMessageInternal(); |
124 } | 144 } |
125 | 145 |
126 void NegotiatingHostAuthenticator::CreateAuthenticator( | 146 void NegotiatingHostAuthenticator::CreateAuthenticator( |
127 Authenticator::State preferred_initial_state, | 147 Authenticator::State preferred_initial_state, |
128 const base::Closure& resume_callback) { | 148 const base::Closure& resume_callback) { |
129 current_authenticator_ = V2Authenticator::CreateForHost( | 149 DCHECK(current_method_.is_valid()); |
130 local_cert_, local_key_pair_, shared_secret_hash_, | 150 |
131 preferred_initial_state); | 151 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { |
| 152 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. |
| 153 // The authentication method negotiation logic should guarantee that only |
| 154 // one |ThirdPartyHostAuthenticator| will need to be created per session. |
| 155 DCHECK(token_validator_); |
| 156 current_authenticator_.reset(new ThirdPartyHostAuthenticator( |
| 157 local_cert_, local_key_pair_, token_validator_.Pass())); |
| 158 } else { |
| 159 current_authenticator_ = V2Authenticator::CreateForHost( |
| 160 local_cert_, local_key_pair_, shared_secret_hash_, |
| 161 preferred_initial_state); |
| 162 } |
| 163 |
132 resume_callback.Run(); | 164 resume_callback.Run(); |
133 } | 165 } |
134 | 166 |
135 } // namespace protocol | 167 } // namespace protocol |
136 } // namespace remoting | 168 } // namespace remoting |
OLD | NEW |