| OLD | NEW |
| 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 "net/base/address_family.h" | 8 #include "net/base/address_family.h" |
| 9 #include "net/base/host_resolver.h" | 9 #include "net/base/host_resolver.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| 11 #include "net/http/http_auth_filter.h" | 11 #include "net/http/http_auth_filter.h" |
| 12 #include "net/http/url_security_manager.h" | 12 #include "net/http/url_security_manager.h" |
| 13 | 13 |
| 14 namespace net { | 14 namespace net { |
| 15 | 15 |
| 16 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( | 16 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( |
| 17 AuthLibrary* auth_library, |
| 17 #if defined(OS_WIN) | 18 #if defined(OS_WIN) |
| 18 SSPILibrary* library, | |
| 19 ULONG max_token_length, | 19 ULONG max_token_length, |
| 20 #endif | 20 #endif |
| 21 #if defined(OS_POSIX) | |
| 22 GSSAPILibrary* library, | |
| 23 #endif | |
| 24 URLSecurityManager* url_security_manager, | 21 URLSecurityManager* url_security_manager, |
| 25 HostResolver* resolver, | 22 HostResolver* resolver, |
| 26 bool disable_cname_lookup, | 23 bool disable_cname_lookup, |
| 27 bool use_port) | 24 bool use_port) |
| 28 #if defined(OS_WIN) | 25 #if defined(OS_WIN) |
| 29 : auth_system_(library, "Negotiate", NEGOSSP_NAME, max_token_length), | 26 : auth_system_(auth_library, "Negotiate", NEGOSSP_NAME, max_token_length), |
| 30 #endif | 27 #elif defined(OS_POSIX) |
| 31 #if defined(OS_POSIX) | 28 : auth_system_(auth_library, "Negotiate", CHROME_GSS_KRB5_MECH_OID_DESC), |
| 32 : auth_system_(library, "Negotiate", CHROME_GSS_KRB5_MECH_OID_DESC), | |
| 33 #endif | 29 #endif |
| 34 disable_cname_lookup_(disable_cname_lookup), | 30 disable_cname_lookup_(disable_cname_lookup), |
| 35 use_port_(use_port), | 31 use_port_(use_port), |
| 36 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( | 32 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
| 37 this, &HttpAuthHandlerNegotiate::OnIOComplete)), | 33 this, &HttpAuthHandlerNegotiate::OnIOComplete)), |
| 38 resolver_(resolver), | 34 resolver_(resolver), |
| 39 already_called_(false), | 35 already_called_(false), |
| 40 has_username_and_password_(false), | 36 has_username_and_password_(false), |
| 41 user_callback_(NULL), | 37 user_callback_(NULL), |
| 42 auth_token_(NULL), | 38 auth_token_(NULL), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } | 74 } |
| 79 | 75 |
| 80 // The Negotiate challenge header looks like: | 76 // The Negotiate challenge header looks like: |
| 81 // WWW-Authenticate: NEGOTIATE auth-data | 77 // WWW-Authenticate: NEGOTIATE auth-data |
| 82 bool HttpAuthHandlerNegotiate::Init(HttpAuth::ChallengeTokenizer* challenge) { | 78 bool HttpAuthHandlerNegotiate::Init(HttpAuth::ChallengeTokenizer* challenge) { |
| 83 #if defined(OS_POSIX) | 79 #if defined(OS_POSIX) |
| 84 if (!auth_system_.Init()) { | 80 if (!auth_system_.Init()) { |
| 85 LOG(INFO) << "can't initialize GSSAPI library"; | 81 LOG(INFO) << "can't initialize GSSAPI library"; |
| 86 return false; | 82 return false; |
| 87 } | 83 } |
| 84 // GSSAPI does not provide a way to enter username/password to |
| 85 // obtain a TGT. If the default credentials are not allowed for |
| 86 // a particular site (based on whitelist), fall back to a |
| 87 // different scheme. |
| 88 if (!AllowsDefaultCredentials()) |
| 89 return false; |
| 88 #endif | 90 #endif |
| 89 scheme_ = "negotiate"; | 91 scheme_ = "negotiate"; |
| 90 score_ = 4; | 92 score_ = 4; |
| 91 properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED; | 93 properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED; |
| 92 return auth_system_.ParseChallenge(challenge); | 94 return auth_system_.ParseChallenge(challenge); |
| 93 } | 95 } |
| 94 | 96 |
| 95 // Require identity on first pass instead of second. | 97 // Require identity on first pass instead of second. |
| 96 bool HttpAuthHandlerNegotiate::NeedsIdentity() { | 98 bool HttpAuthHandlerNegotiate::NeedsIdentity() { |
| 97 return auth_system_.NeedsIdentity(); | 99 return auth_system_.NeedsIdentity(); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 callback->Run(rv); | 242 callback->Run(rv); |
| 241 } | 243 } |
| 242 | 244 |
| 243 HttpAuthHandlerNegotiate::Factory::Factory() | 245 HttpAuthHandlerNegotiate::Factory::Factory() |
| 244 : disable_cname_lookup_(false), | 246 : disable_cname_lookup_(false), |
| 245 use_port_(false), | 247 use_port_(false), |
| 246 #if defined(OS_WIN) | 248 #if defined(OS_WIN) |
| 247 max_token_length_(0), | 249 max_token_length_(0), |
| 248 first_creation_(true), | 250 first_creation_(true), |
| 249 is_unsupported_(false), | 251 is_unsupported_(false), |
| 250 sspi_library_(SSPILibrary::GetDefault()) { | 252 auth_library_(SSPILibrary::GetDefault()) { |
| 251 #endif | 253 #elif defined(OS_POSIX) |
| 252 #if defined(OS_POSIX) | 254 auth_library_(GSSAPILibrary::GetDefault()) { |
| 253 gssapi_library_(GSSAPILibrary::GetDefault()) { | |
| 254 #endif | 255 #endif |
| 255 } | 256 } |
| 256 | 257 |
| 257 HttpAuthHandlerNegotiate::Factory::~Factory() { | 258 HttpAuthHandlerNegotiate::Factory::~Factory() { |
| 258 } | 259 } |
| 259 | 260 |
| 260 void HttpAuthHandlerNegotiate::Factory::set_host_resolver( | 261 void HttpAuthHandlerNegotiate::Factory::set_host_resolver( |
| 261 HostResolver* resolver) { | 262 HostResolver* resolver) { |
| 262 resolver_ = resolver; | 263 resolver_ = resolver; |
| 263 } | 264 } |
| 264 | 265 |
| 265 int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( | 266 int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( |
| 266 HttpAuth::ChallengeTokenizer* challenge, | 267 HttpAuth::ChallengeTokenizer* challenge, |
| 267 HttpAuth::Target target, | 268 HttpAuth::Target target, |
| 268 const GURL& origin, | 269 const GURL& origin, |
| 269 CreateReason reason, | 270 CreateReason reason, |
| 270 int digest_nonce_count, | 271 int digest_nonce_count, |
| 271 const BoundNetLog& net_log, | 272 const BoundNetLog& net_log, |
| 272 scoped_ptr<HttpAuthHandler>* handler) { | 273 scoped_ptr<HttpAuthHandler>* handler) { |
| 273 #if defined(OS_WIN) | 274 #if defined(OS_WIN) |
| 274 if (is_unsupported_ || reason == CREATE_PREEMPTIVE) | 275 if (is_unsupported_ || reason == CREATE_PREEMPTIVE) |
| 275 return ERR_UNSUPPORTED_AUTH_SCHEME; | 276 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 276 if (max_token_length_ == 0) { | 277 if (max_token_length_ == 0) { |
| 277 int rv = DetermineMaxTokenLength(sspi_library_, NEGOSSP_NAME, | 278 int rv = DetermineMaxTokenLength(auth_library_, NEGOSSP_NAME, |
| 278 &max_token_length_); | 279 &max_token_length_); |
| 279 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) | 280 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) |
| 280 is_unsupported_ = true; | 281 is_unsupported_ = true; |
| 281 if (rv != OK) | 282 if (rv != OK) |
| 282 return rv; | 283 return rv; |
| 283 } | 284 } |
| 284 // TODO(cbentzel): Move towards model of parsing in the factory | 285 // TODO(cbentzel): Move towards model of parsing in the factory |
| 285 // method and only constructing when valid. | 286 // method and only constructing when valid. |
| 286 scoped_ptr<HttpAuthHandler> tmp_handler( | 287 scoped_ptr<HttpAuthHandler> tmp_handler( |
| 287 new HttpAuthHandlerNegotiate(sspi_library_, max_token_length_, | 288 new HttpAuthHandlerNegotiate(auth_library_, max_token_length_, |
| 288 url_security_manager(), resolver_, | 289 url_security_manager(), resolver_, |
| 289 disable_cname_lookup_, use_port_)); | 290 disable_cname_lookup_, use_port_)); |
| 290 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 291 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
| 291 return ERR_INVALID_RESPONSE; | 292 return ERR_INVALID_RESPONSE; |
| 292 handler->swap(tmp_handler); | 293 handler->swap(tmp_handler); |
| 293 return OK; | 294 return OK; |
| 294 #endif | 295 #elif defined(OS_POSIX) |
| 295 #if defined(OS_POSIX) | |
| 296 // TODO(ahendrickson): Move towards model of parsing in the factory | 296 // TODO(ahendrickson): Move towards model of parsing in the factory |
| 297 // method and only constructing when valid. | 297 // method and only constructing when valid. |
| 298 scoped_ptr<HttpAuthHandler> tmp_handler( | 298 scoped_ptr<HttpAuthHandler> tmp_handler( |
| 299 new HttpAuthHandlerNegotiate(gssapi_library_, url_security_manager(), | 299 new HttpAuthHandlerNegotiate(auth_library_, url_security_manager(), |
| 300 resolver_, disable_cname_lookup_, | 300 resolver_, disable_cname_lookup_, |
| 301 use_port_)); | 301 use_port_)); |
| 302 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 302 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
| 303 return ERR_INVALID_RESPONSE; | 303 return ERR_INVALID_RESPONSE; |
| 304 handler->swap(tmp_handler); | 304 handler->swap(tmp_handler); |
| 305 return OK; | 305 return OK; |
| 306 #endif | 306 #endif |
| 307 } | 307 } |
| 308 | 308 |
| 309 } // namespace net | 309 } // namespace net |
| OLD | NEW |