Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: net/http/http_auth_handler_negotiate.cc

Issue 6339012: More net/ method ordering. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More done while waiting for previous patch to clear Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_auth_handler_negotiate.h ('k') | net/http/http_auth_handler_ntlm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "net/http/http_auth_handler_negotiate.h" 5 #include "net/http/http_auth_handler_negotiate.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/stringprintf.h" 9 #include "base/stringprintf.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "net/base/address_family.h" 11 #include "net/base/address_family.h"
12 #include "net/base/host_resolver.h" 12 #include "net/base/host_resolver.h"
13 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
14 #include "net/http/http_auth_filter.h" 14 #include "net/http/http_auth_filter.h"
15 #include "net/http/url_security_manager.h" 15 #include "net/http/url_security_manager.h"
16 16
17 namespace net { 17 namespace net {
18 18
19 HttpAuthHandlerNegotiate::Factory::Factory()
20 : disable_cname_lookup_(false),
21 use_port_(false),
22 #if defined(OS_WIN)
23 max_token_length_(0),
24 first_creation_(true),
25 is_unsupported_(false),
26 #endif
27 auth_library_(NULL) {
28 }
29
30 HttpAuthHandlerNegotiate::Factory::~Factory() {
31 }
32
33 void HttpAuthHandlerNegotiate::Factory::set_host_resolver(
34 HostResolver* resolver) {
35 resolver_ = resolver;
36 }
37
38 int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
39 HttpAuth::ChallengeTokenizer* challenge,
40 HttpAuth::Target target,
41 const GURL& origin,
42 CreateReason reason,
43 int digest_nonce_count,
44 const BoundNetLog& net_log,
45 scoped_ptr<HttpAuthHandler>* handler) {
46 #if defined(OS_WIN)
47 if (is_unsupported_ || reason == CREATE_PREEMPTIVE)
48 return ERR_UNSUPPORTED_AUTH_SCHEME;
49 if (max_token_length_ == 0) {
50 int rv = DetermineMaxTokenLength(auth_library_.get(), NEGOSSP_NAME,
51 &max_token_length_);
52 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME)
53 is_unsupported_ = true;
54 if (rv != OK)
55 return rv;
56 }
57 // TODO(cbentzel): Move towards model of parsing in the factory
58 // method and only constructing when valid.
59 scoped_ptr<HttpAuthHandler> tmp_handler(
60 new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_,
61 url_security_manager(), resolver_,
62 disable_cname_lookup_, use_port_));
63 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
64 return ERR_INVALID_RESPONSE;
65 handler->swap(tmp_handler);
66 return OK;
67 #elif defined(OS_POSIX)
68 // TODO(ahendrickson): Move towards model of parsing in the factory
69 // method and only constructing when valid.
70 scoped_ptr<HttpAuthHandler> tmp_handler(
71 new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(),
72 resolver_, disable_cname_lookup_,
73 use_port_));
74 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
75 return ERR_INVALID_RESPONSE;
76 handler->swap(tmp_handler);
77 return OK;
78 #endif
79 }
80
19 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( 81 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate(
20 AuthLibrary* auth_library, 82 AuthLibrary* auth_library,
21 #if defined(OS_WIN) 83 #if defined(OS_WIN)
22 ULONG max_token_length, 84 ULONG max_token_length,
23 #endif 85 #endif
24 URLSecurityManager* url_security_manager, 86 URLSecurityManager* url_security_manager,
25 HostResolver* resolver, 87 HostResolver* resolver,
26 bool disable_cname_lookup, 88 bool disable_cname_lookup,
27 bool use_port) 89 bool use_port)
28 #if defined(OS_WIN) 90 #if defined(OS_WIN)
(...skipping 10 matching lines...) Expand all
39 has_username_and_password_(false), 101 has_username_and_password_(false),
40 user_callback_(NULL), 102 user_callback_(NULL),
41 auth_token_(NULL), 103 auth_token_(NULL),
42 next_state_(STATE_NONE), 104 next_state_(STATE_NONE),
43 url_security_manager_(url_security_manager) { 105 url_security_manager_(url_security_manager) {
44 } 106 }
45 107
46 HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() { 108 HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() {
47 } 109 }
48 110
49 int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl(
50 const string16* username,
51 const string16* password,
52 const HttpRequestInfo* request,
53 CompletionCallback* callback,
54 std::string* auth_token) {
55 DCHECK(user_callback_ == NULL);
56 DCHECK((username == NULL) == (password == NULL));
57 DCHECK(auth_token_ == NULL);
58 auth_token_ = auth_token;
59 if (already_called_) {
60 DCHECK((!has_username_and_password_ && username == NULL) ||
61 (has_username_and_password_ && *username == username_ &&
62 *password == password_));
63 next_state_ = STATE_GENERATE_AUTH_TOKEN;
64 } else {
65 already_called_ = true;
66 if (username) {
67 has_username_and_password_ = true;
68 username_ = *username;
69 password_ = *password;
70 }
71 next_state_ = STATE_RESOLVE_CANONICAL_NAME;
72 }
73 int rv = DoLoop(OK);
74 if (rv == ERR_IO_PENDING)
75 user_callback_ = callback;
76 return rv;
77 }
78
79 // The Negotiate challenge header looks like:
80 // WWW-Authenticate: NEGOTIATE auth-data
81 bool HttpAuthHandlerNegotiate::Init(HttpAuth::ChallengeTokenizer* challenge) {
82 #if defined(OS_POSIX)
83 if (!auth_system_.Init()) {
84 VLOG(1) << "can't initialize GSSAPI library";
85 return false;
86 }
87 // GSSAPI does not provide a way to enter username/password to
88 // obtain a TGT. If the default credentials are not allowed for
89 // a particular site (based on whitelist), fall back to a
90 // different scheme.
91 if (!AllowsDefaultCredentials())
92 return false;
93 #endif
94 if (CanDelegate())
95 auth_system_.Delegate();
96 auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE;
97 score_ = 4;
98 properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED;
99 HttpAuth::AuthorizationResult auth_result =
100 auth_system_.ParseChallenge(challenge);
101 return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT);
102 }
103
104 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge(
105 HttpAuth::ChallengeTokenizer* challenge) {
106 return auth_system_.ParseChallenge(challenge);
107 }
108
109 // Require identity on first pass instead of second.
110 bool HttpAuthHandlerNegotiate::NeedsIdentity() {
111 return auth_system_.NeedsIdentity();
112 }
113
114 bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() {
115 if (target_ == HttpAuth::AUTH_PROXY)
116 return true;
117 if (!url_security_manager_)
118 return false;
119 return url_security_manager_->CanUseDefaultCredentials(origin_);
120 }
121
122 bool HttpAuthHandlerNegotiate::CanDelegate() const {
123 // TODO(cbentzel): Should delegation be allowed on proxies?
124 if (target_ == HttpAuth::AUTH_PROXY)
125 return false;
126 if (!url_security_manager_)
127 return false;
128 return url_security_manager_->CanDelegate(origin_);
129 }
130
131 std::wstring HttpAuthHandlerNegotiate::CreateSPN( 111 std::wstring HttpAuthHandlerNegotiate::CreateSPN(
132 const AddressList& address_list, const GURL& origin) { 112 const AddressList& address_list, const GURL& origin) {
133 // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI, 113 // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI,
134 // and in the form HTTP@<host>:<port> through GSSAPI 114 // and in the form HTTP@<host>:<port> through GSSAPI
135 // http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx 115 // http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx
136 // 116 //
137 // However, reality differs from the specification. A good description of 117 // However, reality differs from the specification. A good description of
138 // the problems can be found here: 118 // the problems can be found here:
139 // http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-k b911149-and-kb908209-are-not-the-soluton.aspx 119 // http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-k b911149-and-kb908209-are-not-the-soluton.aspx
140 // 120 //
(...skipping 29 matching lines...) Expand all
170 #endif 150 #endif
171 if (port != 80 && port != 443 && use_port_) { 151 if (port != 80 && port != 443 && use_port_) {
172 return ASCIIToWide(base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, 152 return ASCIIToWide(base::StringPrintf("HTTP%c%s:%d", kSpnSeparator,
173 server.c_str(), port)); 153 server.c_str(), port));
174 } else { 154 } else {
175 return ASCIIToWide(base::StringPrintf("HTTP%c%s", kSpnSeparator, 155 return ASCIIToWide(base::StringPrintf("HTTP%c%s", kSpnSeparator,
176 server.c_str())); 156 server.c_str()));
177 } 157 }
178 } 158 }
179 159
160 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge(
161 HttpAuth::ChallengeTokenizer* challenge) {
162 return auth_system_.ParseChallenge(challenge);
163 }
164
165 // Require identity on first pass instead of second.
166 bool HttpAuthHandlerNegotiate::NeedsIdentity() {
167 return auth_system_.NeedsIdentity();
168 }
169
170 bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() {
171 if (target_ == HttpAuth::AUTH_PROXY)
172 return true;
173 if (!url_security_manager_)
174 return false;
175 return url_security_manager_->CanUseDefaultCredentials(origin_);
176 }
177
178 // The Negotiate challenge header looks like:
179 // WWW-Authenticate: NEGOTIATE auth-data
180 bool HttpAuthHandlerNegotiate::Init(HttpAuth::ChallengeTokenizer* challenge) {
181 #if defined(OS_POSIX)
182 if (!auth_system_.Init()) {
183 VLOG(1) << "can't initialize GSSAPI library";
184 return false;
185 }
186 // GSSAPI does not provide a way to enter username/password to
187 // obtain a TGT. If the default credentials are not allowed for
188 // a particular site (based on whitelist), fall back to a
189 // different scheme.
190 if (!AllowsDefaultCredentials())
191 return false;
192 #endif
193 if (CanDelegate())
194 auth_system_.Delegate();
195 auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE;
196 score_ = 4;
197 properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED;
198 HttpAuth::AuthorizationResult auth_result =
199 auth_system_.ParseChallenge(challenge);
200 return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT);
201 }
202
203 int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl(
204 const string16* username,
205 const string16* password,
206 const HttpRequestInfo* request,
207 CompletionCallback* callback,
208 std::string* auth_token) {
209 DCHECK(user_callback_ == NULL);
210 DCHECK((username == NULL) == (password == NULL));
211 DCHECK(auth_token_ == NULL);
212 auth_token_ = auth_token;
213 if (already_called_) {
214 DCHECK((!has_username_and_password_ && username == NULL) ||
215 (has_username_and_password_ && *username == username_ &&
216 *password == password_));
217 next_state_ = STATE_GENERATE_AUTH_TOKEN;
218 } else {
219 already_called_ = true;
220 if (username) {
221 has_username_and_password_ = true;
222 username_ = *username;
223 password_ = *password;
224 }
225 next_state_ = STATE_RESOLVE_CANONICAL_NAME;
226 }
227 int rv = DoLoop(OK);
228 if (rv == ERR_IO_PENDING)
229 user_callback_ = callback;
230 return rv;
231 }
232
233 void HttpAuthHandlerNegotiate::OnIOComplete(int result) {
234 int rv = DoLoop(result);
235 if (rv != ERR_IO_PENDING)
236 DoCallback(rv);
237 }
238
239 void HttpAuthHandlerNegotiate::DoCallback(int rv) {
240 DCHECK(rv != ERR_IO_PENDING);
241 DCHECK(user_callback_);
242 CompletionCallback* callback = user_callback_;
243 user_callback_ = NULL;
244 callback->Run(rv);
245 }
246
180 int HttpAuthHandlerNegotiate::DoLoop(int result) { 247 int HttpAuthHandlerNegotiate::DoLoop(int result) {
181 DCHECK(next_state_ != STATE_NONE); 248 DCHECK(next_state_ != STATE_NONE);
182 249
183 int rv = result; 250 int rv = result;
184 do { 251 do {
185 State state = next_state_; 252 State state = next_state_;
186 next_state_ = STATE_NONE; 253 next_state_ = STATE_NONE;
187 switch (state) { 254 switch (state) {
188 case STATE_RESOLVE_CANONICAL_NAME: 255 case STATE_RESOLVE_CANONICAL_NAME:
189 DCHECK_EQ(OK, rv); 256 DCHECK_EQ(OK, rv);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 // TODO(cbentzel): This should possibly be done async. 313 // TODO(cbentzel): This should possibly be done async.
247 return auth_system_.GenerateAuthToken(username, password, spn_, auth_token_); 314 return auth_system_.GenerateAuthToken(username, password, spn_, auth_token_);
248 } 315 }
249 316
250 int HttpAuthHandlerNegotiate::DoGenerateAuthTokenComplete(int rv) { 317 int HttpAuthHandlerNegotiate::DoGenerateAuthTokenComplete(int rv) {
251 DCHECK_NE(ERR_IO_PENDING, rv); 318 DCHECK_NE(ERR_IO_PENDING, rv);
252 auth_token_ = NULL; 319 auth_token_ = NULL;
253 return rv; 320 return rv;
254 } 321 }
255 322
256 void HttpAuthHandlerNegotiate::OnIOComplete(int result) { 323 bool HttpAuthHandlerNegotiate::CanDelegate() const {
257 int rv = DoLoop(result); 324 // TODO(cbentzel): Should delegation be allowed on proxies?
258 if (rv != ERR_IO_PENDING) 325 if (target_ == HttpAuth::AUTH_PROXY)
259 DoCallback(rv); 326 return false;
260 } 327 if (!url_security_manager_)
261 328 return false;
262 void HttpAuthHandlerNegotiate::DoCallback(int rv) { 329 return url_security_manager_->CanDelegate(origin_);
263 DCHECK(rv != ERR_IO_PENDING);
264 DCHECK(user_callback_);
265 CompletionCallback* callback = user_callback_;
266 user_callback_ = NULL;
267 callback->Run(rv);
268 }
269
270 HttpAuthHandlerNegotiate::Factory::Factory()
271 : disable_cname_lookup_(false),
272 use_port_(false),
273 #if defined(OS_WIN)
274 max_token_length_(0),
275 first_creation_(true),
276 is_unsupported_(false),
277 #endif
278 auth_library_(NULL) {
279 }
280
281 HttpAuthHandlerNegotiate::Factory::~Factory() {
282 }
283
284 void HttpAuthHandlerNegotiate::Factory::set_host_resolver(
285 HostResolver* resolver) {
286 resolver_ = resolver;
287 }
288
289 int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
290 HttpAuth::ChallengeTokenizer* challenge,
291 HttpAuth::Target target,
292 const GURL& origin,
293 CreateReason reason,
294 int digest_nonce_count,
295 const BoundNetLog& net_log,
296 scoped_ptr<HttpAuthHandler>* handler) {
297 #if defined(OS_WIN)
298 if (is_unsupported_ || reason == CREATE_PREEMPTIVE)
299 return ERR_UNSUPPORTED_AUTH_SCHEME;
300 if (max_token_length_ == 0) {
301 int rv = DetermineMaxTokenLength(auth_library_.get(), NEGOSSP_NAME,
302 &max_token_length_);
303 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME)
304 is_unsupported_ = true;
305 if (rv != OK)
306 return rv;
307 }
308 // TODO(cbentzel): Move towards model of parsing in the factory
309 // method and only constructing when valid.
310 scoped_ptr<HttpAuthHandler> tmp_handler(
311 new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_,
312 url_security_manager(), resolver_,
313 disable_cname_lookup_, use_port_));
314 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
315 return ERR_INVALID_RESPONSE;
316 handler->swap(tmp_handler);
317 return OK;
318 #elif defined(OS_POSIX)
319 // TODO(ahendrickson): Move towards model of parsing in the factory
320 // method and only constructing when valid.
321 scoped_ptr<HttpAuthHandler> tmp_handler(
322 new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(),
323 resolver_, disable_cname_lookup_,
324 use_port_));
325 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
326 return ERR_INVALID_RESPONSE;
327 handler->swap(tmp_handler);
328 return OK;
329 #endif
330 } 330 }
331 331
332 } // namespace net 332 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_handler_negotiate.h ('k') | net/http/http_auth_handler_ntlm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698