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_client_authenticator.h" | 5 #include "remoting/protocol/negotiating_client_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/protocol/channel_authenticator.h" | 14 #include "remoting/protocol/channel_authenticator.h" |
15 #include "remoting/protocol/pairing_client_authenticator.h" | |
15 #include "remoting/protocol/v2_authenticator.h" | 16 #include "remoting/protocol/v2_authenticator.h" |
16 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
17 | 18 |
18 namespace remoting { | 19 namespace remoting { |
19 namespace protocol { | 20 namespace protocol { |
20 | 21 |
21 NegotiatingClientAuthenticator::NegotiatingClientAuthenticator( | 22 NegotiatingClientAuthenticator::NegotiatingClientAuthenticator( |
23 const std::string& client_pairing_id, | |
24 const std::string& shared_secret, | |
22 const std::string& authentication_tag, | 25 const std::string& authentication_tag, |
23 const FetchSecretCallback& fetch_secret_callback, | 26 const FetchSecretCallback& fetch_secret_callback, |
24 scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher, | 27 scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher, |
25 const std::vector<AuthenticationMethod>& methods) | 28 const std::vector<AuthenticationMethod>& methods) |
26 : NegotiatingAuthenticatorBase(MESSAGE_READY), | 29 : NegotiatingAuthenticatorBase(MESSAGE_READY), |
30 client_pairing_id_(client_pairing_id), | |
31 shared_secret_(shared_secret), | |
27 authentication_tag_(authentication_tag), | 32 authentication_tag_(authentication_tag), |
28 fetch_secret_callback_(fetch_secret_callback), | 33 fetch_secret_callback_(fetch_secret_callback), |
29 token_fetcher_(token_fetcher.Pass()), | 34 token_fetcher_(token_fetcher.Pass()), |
30 method_set_by_host_(false), | 35 method_set_by_host_(false), |
31 weak_factory_(this) { | 36 weak_factory_(this) { |
32 DCHECK(!methods.empty()); | 37 DCHECK(!methods.empty()); |
33 for (std::vector<AuthenticationMethod>::const_iterator it = methods.begin(); | 38 for (std::vector<AuthenticationMethod>::const_iterator it = methods.begin(); |
34 it != methods.end(); ++it) { | 39 it != methods.end(); ++it) { |
35 AddMethod(*it); | 40 AddMethod(*it); |
36 } | 41 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 ProcessMessageInternal(message, resume_callback); | 79 ProcessMessageInternal(message, resume_callback); |
75 } | 80 } |
76 | 81 |
77 scoped_ptr<buzz::XmlElement> NegotiatingClientAuthenticator::GetNextMessage() { | 82 scoped_ptr<buzz::XmlElement> NegotiatingClientAuthenticator::GetNextMessage() { |
78 DCHECK_EQ(state(), MESSAGE_READY); | 83 DCHECK_EQ(state(), MESSAGE_READY); |
79 // This is the first message to the host, send a list of supported methods. | 84 // This is the first message to the host, send a list of supported methods. |
80 if (!current_method_.is_valid()) { | 85 if (!current_method_.is_valid()) { |
81 // If no authentication method has been chosen, see if we can optimistically | 86 // If no authentication method has been chosen, see if we can optimistically |
82 // choose one. | 87 // choose one. |
83 scoped_ptr<buzz::XmlElement> result; | 88 scoped_ptr<buzz::XmlElement> result; |
84 current_authenticator_ = CreatePreferredAuthenticator(); | 89 CreatePreferredAuthenticator(); |
85 if (current_authenticator_) { | 90 if (current_authenticator_) { |
86 DCHECK(current_authenticator_->state() == MESSAGE_READY); | 91 DCHECK(current_authenticator_->state() == MESSAGE_READY); |
87 result = GetNextMessageInternal(); | 92 result = GetNextMessageInternal(); |
88 } else { | 93 } else { |
89 result = CreateEmptyAuthenticatorMessage(); | 94 result = CreateEmptyAuthenticatorMessage(); |
90 } | 95 } |
91 | |
Sergey Ulanov
2013/05/17 01:57:17
nit: please keep this empty line
Jamie
2013/05/21 01:24:33
Done.
| |
92 // Include a list of supported methods. | 96 // Include a list of supported methods. |
93 std::stringstream supported_methods(std::stringstream::out); | 97 std::stringstream supported_methods(std::stringstream::out); |
94 for (std::vector<AuthenticationMethod>::iterator it = methods_.begin(); | 98 for (std::vector<AuthenticationMethod>::iterator it = methods_.begin(); |
95 it != methods_.end(); ++it) { | 99 it != methods_.end(); ++it) { |
96 if (it != methods_.begin()) | 100 if (it != methods_.begin()) |
97 supported_methods << kSupportedMethodsSeparator; | 101 supported_methods << kSupportedMethodsSeparator; |
98 supported_methods << it->ToString(); | 102 supported_methods << it->ToString(); |
99 } | 103 } |
100 result->AddAttr(kSupportedMethodsAttributeQName, supported_methods.str()); | 104 result->AddAttr(kSupportedMethodsAttributeQName, supported_methods.str()); |
101 state_ = WAITING_MESSAGE; | 105 state_ = WAITING_MESSAGE; |
102 return result.Pass(); | 106 return result.Pass(); |
103 } | 107 } |
104 return GetNextMessageInternal(); | 108 return GetNextMessageInternal(); |
105 } | 109 } |
106 | 110 |
107 void NegotiatingClientAuthenticator::CreateAuthenticatorForCurrentMethod( | 111 void NegotiatingClientAuthenticator::CreateAuthenticatorForCurrentMethod( |
108 Authenticator::State preferred_initial_state, | 112 Authenticator::State preferred_initial_state, |
109 const base::Closure& resume_callback) { | 113 const base::Closure& resume_callback) { |
110 DCHECK(current_method_.is_valid()); | 114 DCHECK(current_method_.is_valid()); |
111 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { | 115 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { |
112 // |ThirdPartyClientAuthenticator| takes ownership of |token_fetcher_|. | 116 // |ThirdPartyClientAuthenticator| takes ownership of |token_fetcher_|. |
113 // The authentication method negotiation logic should guarantee that only | 117 // The authentication method negotiation logic should guarantee that only |
114 // one |ThirdPartyClientAuthenticator| will need to be created per session. | 118 // one |ThirdPartyClientAuthenticator| will need to be created per session. |
115 DCHECK(token_fetcher_); | 119 DCHECK(token_fetcher_); |
116 current_authenticator_.reset(new ThirdPartyClientAuthenticator( | 120 current_authenticator_.reset(new ThirdPartyClientAuthenticator( |
117 token_fetcher_.Pass())); | 121 token_fetcher_.Pass())); |
118 resume_callback.Run(); | 122 resume_callback.Run(); |
119 } else { | 123 } else { |
Sergey Ulanov
2013/05/17 01:57:17
I think this should check that current_method_ is
rmsousa
2013/05/17 20:09:03
It's intentionally using this for the using-pairin
Jamie
2013/05/21 01:24:33
Please see the comment thread in response to Renat
| |
120 fetch_secret_callback_.Run(base::Bind( | 124 fetch_secret_callback_.Run(base::Bind( |
121 &NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret, | 125 &NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret, |
122 weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback)); | 126 weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback)); |
123 } | 127 } |
124 } | 128 } |
125 | 129 |
126 scoped_ptr<Authenticator> | 130 void NegotiatingClientAuthenticator::CreatePreferredAuthenticator() { |
127 NegotiatingClientAuthenticator::CreatePreferredAuthenticator() { | 131 if (!client_pairing_id_.empty() && !shared_secret_.empty()) { |
128 NOTIMPLEMENTED(); | 132 // If the client specified a pairing id and shared secret, then create a |
129 return scoped_ptr<Authenticator>(); | 133 // PairingAuthenticator. |
134 current_authenticator_.reset(new PairingClientAuthenticator( | |
135 client_pairing_id_, shared_secret_, fetch_secret_callback_, | |
136 authentication_tag_)); | |
137 current_method_ = AuthenticationMethod::Spake2Pair(); | |
Sergey Ulanov
2013/05/17 01:57:17
Please DCHECK here that pairing auth is in the lis
rmsousa
2013/05/17 20:09:03
Good point. Not just a DCHECK, IMO that test shoul
Jamie
2013/05/21 01:24:33
Agreed. I've made it explicit.
| |
138 } | |
130 } | 139 } |
131 | 140 |
132 void NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret( | 141 void NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret( |
133 Authenticator::State initial_state, | 142 Authenticator::State initial_state, |
134 const base::Closure& resume_callback, | 143 const base::Closure& resume_callback, |
135 const std::string& shared_secret) { | 144 const std::string& shared_secret) { |
136 current_authenticator_ = V2Authenticator::CreateForClient( | 145 current_authenticator_ = V2Authenticator::CreateForClient( |
137 AuthenticationMethod::ApplyHashFunction( | 146 AuthenticationMethod::ApplyHashFunction( |
138 current_method_.hash_function(), authentication_tag_, shared_secret), | 147 current_method_.hash_function(), authentication_tag_, shared_secret), |
139 initial_state); | 148 initial_state); |
140 resume_callback.Run(); | 149 resume_callback.Run(); |
141 } | 150 } |
142 | 151 |
143 } // namespace protocol | 152 } // namespace protocol |
144 } // namespace remoting | 153 } // namespace remoting |
OLD | NEW |