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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 base::Unretained(this), base::Owned(new buzz::XmlElement(*message)), | 74 base::Unretained(this), base::Owned(new buzz::XmlElement(*message)), |
70 resume_callback); | 75 resume_callback); |
71 CreateAuthenticatorForCurrentMethod(WAITING_MESSAGE, callback); | 76 CreateAuthenticatorForCurrentMethod(WAITING_MESSAGE, callback); |
72 return; | 77 return; |
73 } | 78 } |
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); |
| 84 |
79 // This is the first message to the host, send a list of supported methods. | 85 // This is the first message to the host, send a list of supported methods. |
80 if (!current_method_.is_valid()) { | 86 if (!current_method_.is_valid()) { |
81 // If no authentication method has been chosen, see if we can optimistically | 87 // If no authentication method has been chosen, see if we can optimistically |
82 // choose one. | 88 // choose one. |
83 scoped_ptr<buzz::XmlElement> result; | 89 scoped_ptr<buzz::XmlElement> result; |
84 current_authenticator_ = CreatePreferredAuthenticator(); | 90 CreatePreferredAuthenticator(); |
85 if (current_authenticator_) { | 91 if (current_authenticator_) { |
86 DCHECK(current_authenticator_->state() == MESSAGE_READY); | 92 DCHECK(current_authenticator_->state() == MESSAGE_READY); |
87 result = GetNextMessageInternal(); | 93 result = GetNextMessageInternal(); |
88 } else { | 94 } else { |
89 result = CreateEmptyAuthenticatorMessage(); | 95 result = CreateEmptyAuthenticatorMessage(); |
90 } | 96 } |
91 | 97 |
92 // Include a list of supported methods. | 98 // Include a list of supported methods. |
93 std::stringstream supported_methods(std::stringstream::out); | 99 std::stringstream supported_methods(std::stringstream::out); |
94 for (std::vector<AuthenticationMethod>::iterator it = methods_.begin(); | 100 for (std::vector<AuthenticationMethod>::iterator it = methods_.begin(); |
(...skipping 15 matching lines...) Expand all Loading... |
110 DCHECK(current_method_.is_valid()); | 116 DCHECK(current_method_.is_valid()); |
111 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { | 117 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { |
112 // |ThirdPartyClientAuthenticator| takes ownership of |token_fetcher_|. | 118 // |ThirdPartyClientAuthenticator| takes ownership of |token_fetcher_|. |
113 // The authentication method negotiation logic should guarantee that only | 119 // The authentication method negotiation logic should guarantee that only |
114 // one |ThirdPartyClientAuthenticator| will need to be created per session. | 120 // one |ThirdPartyClientAuthenticator| will need to be created per session. |
115 DCHECK(token_fetcher_); | 121 DCHECK(token_fetcher_); |
116 current_authenticator_.reset(new ThirdPartyClientAuthenticator( | 122 current_authenticator_.reset(new ThirdPartyClientAuthenticator( |
117 token_fetcher_.Pass())); | 123 token_fetcher_.Pass())); |
118 resume_callback.Run(); | 124 resume_callback.Run(); |
119 } else { | 125 } else { |
| 126 DCHECK(current_method_.type() == AuthenticationMethod::SPAKE2 || |
| 127 current_method_.type() == AuthenticationMethod::SPAKE2_PAIR); |
| 128 // TODO(jamiewalch): Add a bool parameter to the fetch secret callback to |
| 129 // indicate whether or not to show the "remember me" checkbox. Set it to |
| 130 // (current_method_.type() == AuthenticationMethod::SPAKE2_PAIR). |
120 fetch_secret_callback_.Run(base::Bind( | 131 fetch_secret_callback_.Run(base::Bind( |
121 &NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret, | 132 &NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret, |
122 weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback)); | 133 weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback)); |
123 } | 134 } |
124 } | 135 } |
125 | 136 |
126 scoped_ptr<Authenticator> | 137 void NegotiatingClientAuthenticator::CreatePreferredAuthenticator() { |
127 NegotiatingClientAuthenticator::CreatePreferredAuthenticator() { | 138 if (!client_pairing_id_.empty() && !shared_secret_.empty() && |
128 NOTIMPLEMENTED(); | 139 std::find(methods_.begin(), methods_.end(), |
129 return scoped_ptr<Authenticator>(); | 140 AuthenticationMethod::Spake2Pair()) != methods_.end()) { |
| 141 // If the client specified a pairing id and shared secret, then create a |
| 142 // PairingAuthenticator. |
| 143 current_authenticator_.reset(new PairingClientAuthenticator( |
| 144 client_pairing_id_, shared_secret_, fetch_secret_callback_, |
| 145 authentication_tag_)); |
| 146 current_method_ = AuthenticationMethod::Spake2Pair(); |
| 147 } |
130 } | 148 } |
131 | 149 |
132 void NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret( | 150 void NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret( |
133 Authenticator::State initial_state, | 151 Authenticator::State initial_state, |
134 const base::Closure& resume_callback, | 152 const base::Closure& resume_callback, |
135 const std::string& shared_secret) { | 153 const std::string& shared_secret) { |
136 current_authenticator_ = V2Authenticator::CreateForClient( | 154 current_authenticator_ = V2Authenticator::CreateForClient( |
137 AuthenticationMethod::ApplyHashFunction( | 155 AuthenticationMethod::ApplyHashFunction( |
138 current_method_.hash_function(), authentication_tag_, shared_secret), | 156 current_method_.hash_function(), authentication_tag_, shared_secret), |
139 initial_state); | 157 initial_state); |
140 resume_callback.Run(); | 158 resume_callback.Run(); |
141 } | 159 } |
142 | 160 |
143 } // namespace protocol | 161 } // namespace protocol |
144 } // namespace remoting | 162 } // namespace remoting |
OLD | NEW |