| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 HttpAuth::Target target, | 41 HttpAuth::Target target, |
| 42 const GURL& origin, | 42 const GURL& origin, |
| 43 CreateReason reason, | 43 CreateReason reason, |
| 44 int digest_nonce_count, | 44 int digest_nonce_count, |
| 45 const BoundNetLog& net_log, | 45 const BoundNetLog& net_log, |
| 46 scoped_ptr<HttpAuthHandler>* handler) { | 46 scoped_ptr<HttpAuthHandler>* handler) { |
| 47 #if defined(OS_WIN) | 47 #if defined(OS_WIN) |
| 48 if (is_unsupported_ || reason == CREATE_PREEMPTIVE) | 48 if (is_unsupported_ || reason == CREATE_PREEMPTIVE) |
| 49 return ERR_UNSUPPORTED_AUTH_SCHEME; | 49 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 50 if (max_token_length_ == 0) { | 50 if (max_token_length_ == 0) { |
| 51 int rv = DetermineMaxTokenLength(auth_library_.get(), NEGOSSP_NAME, | 51 int rv = DetermineMaxTokenLength( |
| 52 &max_token_length_); | 52 auth_library_.get(), NEGOSSP_NAME, &max_token_length_); |
| 53 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) | 53 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) |
| 54 is_unsupported_ = true; | 54 is_unsupported_ = true; |
| 55 if (rv != OK) | 55 if (rv != OK) |
| 56 return rv; | 56 return rv; |
| 57 } | 57 } |
| 58 // TODO(cbentzel): Move towards model of parsing in the factory | 58 // TODO(cbentzel): Move towards model of parsing in the factory |
| 59 // method and only constructing when valid. | 59 // method and only constructing when valid. |
| 60 scoped_ptr<HttpAuthHandler> tmp_handler( | 60 scoped_ptr<HttpAuthHandler> tmp_handler( |
| 61 new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_, | 61 new HttpAuthHandlerNegotiate(auth_library_.get(), |
| 62 url_security_manager(), resolver_, | 62 max_token_length_, |
| 63 disable_cname_lookup_, use_port_)); | 63 url_security_manager(), |
| 64 resolver_, |
| 65 disable_cname_lookup_, |
| 66 use_port_)); |
| 64 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 67 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
| 65 return ERR_INVALID_RESPONSE; | 68 return ERR_INVALID_RESPONSE; |
| 66 handler->swap(tmp_handler); | 69 handler->swap(tmp_handler); |
| 67 return OK; | 70 return OK; |
| 68 #elif defined(OS_POSIX) | 71 #elif defined(OS_POSIX) |
| 69 if (is_unsupported_) | 72 if (is_unsupported_) |
| 70 return ERR_UNSUPPORTED_AUTH_SCHEME; | 73 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 71 if (!auth_library_->Init()) { | 74 if (!auth_library_->Init()) { |
| 72 is_unsupported_ = true; | 75 is_unsupported_ = true; |
| 73 return ERR_UNSUPPORTED_AUTH_SCHEME; | 76 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 74 } | 77 } |
| 75 // TODO(ahendrickson): Move towards model of parsing in the factory | 78 // TODO(ahendrickson): Move towards model of parsing in the factory |
| 76 // method and only constructing when valid. | 79 // method and only constructing when valid. |
| 77 scoped_ptr<HttpAuthHandler> tmp_handler( | 80 scoped_ptr<HttpAuthHandler> tmp_handler( |
| 78 new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(), | 81 new HttpAuthHandlerNegotiate(auth_library_.get(), |
| 79 resolver_, disable_cname_lookup_, | 82 url_security_manager(), |
| 83 resolver_, |
| 84 disable_cname_lookup_, |
| 80 use_port_)); | 85 use_port_)); |
| 81 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 86 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
| 82 return ERR_INVALID_RESPONSE; | 87 return ERR_INVALID_RESPONSE; |
| 83 handler->swap(tmp_handler); | 88 handler->swap(tmp_handler); |
| 84 return OK; | 89 return OK; |
| 85 #endif | 90 #endif |
| 86 } | 91 } |
| 87 | 92 |
| 88 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( | 93 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( |
| 89 AuthLibrary* auth_library, | 94 AuthLibrary* auth_library, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 105 already_called_(false), | 110 already_called_(false), |
| 106 has_credentials_(false), | 111 has_credentials_(false), |
| 107 auth_token_(NULL), | 112 auth_token_(NULL), |
| 108 next_state_(STATE_NONE), | 113 next_state_(STATE_NONE), |
| 109 url_security_manager_(url_security_manager) { | 114 url_security_manager_(url_security_manager) { |
| 110 } | 115 } |
| 111 | 116 |
| 112 HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() { | 117 HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() { |
| 113 } | 118 } |
| 114 | 119 |
| 115 std::string HttpAuthHandlerNegotiate::CreateSPN( | 120 std::string HttpAuthHandlerNegotiate::CreateSPN(const AddressList& address_list, |
| 116 const AddressList& address_list, const GURL& origin) { | 121 const GURL& origin) { |
| 117 // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI, | 122 // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI, |
| 118 // and in the form HTTP@<host>:<port> through GSSAPI | 123 // and in the form HTTP@<host>:<port> through GSSAPI |
| 119 // http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx | 124 // http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx |
| 120 // | 125 // |
| 121 // However, reality differs from the specification. A good description of | 126 // However, reality differs from the specification. A good description of |
| 122 // the problems can be found here: | 127 // the problems can be found here: |
| 123 // http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-k
b911149-and-kb908209-are-not-the-soluton.aspx | 128 // http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-k
b911149-and-kb908209-are-not-the-soluton.aspx |
| 124 // | 129 // |
| 125 // Typically the <host> portion should be the canonical FQDN for the service. | 130 // Typically the <host> portion should be the canonical FQDN for the service. |
| 126 // If this could not be resolved, the original hostname in the URL will be | 131 // If this could not be resolved, the original hostname in the URL will be |
| (...skipping 19 matching lines...) Expand all Loading... |
| 146 int port = origin.EffectiveIntPort(); | 151 int port = origin.EffectiveIntPort(); |
| 147 std::string server = address_list.canonical_name(); | 152 std::string server = address_list.canonical_name(); |
| 148 if (server.empty()) | 153 if (server.empty()) |
| 149 server = origin.host(); | 154 server = origin.host(); |
| 150 #if defined(OS_WIN) | 155 #if defined(OS_WIN) |
| 151 static const char kSpnSeparator = '/'; | 156 static const char kSpnSeparator = '/'; |
| 152 #elif defined(OS_POSIX) | 157 #elif defined(OS_POSIX) |
| 153 static const char kSpnSeparator = '@'; | 158 static const char kSpnSeparator = '@'; |
| 154 #endif | 159 #endif |
| 155 if (port != 80 && port != 443 && use_port_) { | 160 if (port != 80 && port != 443 && use_port_) { |
| 156 return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(), | 161 return base::StringPrintf( |
| 157 port); | 162 "HTTP%c%s:%d", kSpnSeparator, server.c_str(), port); |
| 158 } else { | 163 } else { |
| 159 return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str()); | 164 return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str()); |
| 160 } | 165 } |
| 161 } | 166 } |
| 162 | 167 |
| 163 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge( | 168 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge( |
| 164 HttpAuthChallengeTokenizer* challenge) { | 169 HttpAuthChallengeTokenizer* challenge) { |
| 165 return auth_system_.ParseChallenge(challenge); | 170 return auth_system_.ParseChallenge(challenge); |
| 166 } | 171 } |
| 167 | 172 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 auth_system_.Delegate(); | 206 auth_system_.Delegate(); |
| 202 auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE; | 207 auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE; |
| 203 score_ = 4; | 208 score_ = 4; |
| 204 properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED; | 209 properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED; |
| 205 HttpAuth::AuthorizationResult auth_result = | 210 HttpAuth::AuthorizationResult auth_result = |
| 206 auth_system_.ParseChallenge(challenge); | 211 auth_system_.ParseChallenge(challenge); |
| 207 return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT); | 212 return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT); |
| 208 } | 213 } |
| 209 | 214 |
| 210 int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl( | 215 int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl( |
| 211 const AuthCredentials* credentials, const HttpRequestInfo* request, | 216 const AuthCredentials* credentials, |
| 212 const CompletionCallback& callback, std::string* auth_token) { | 217 const HttpRequestInfo* request, |
| 218 const CompletionCallback& callback, |
| 219 std::string* auth_token) { |
| 213 DCHECK(callback_.is_null()); | 220 DCHECK(callback_.is_null()); |
| 214 DCHECK(auth_token_ == NULL); | 221 DCHECK(auth_token_ == NULL); |
| 215 auth_token_ = auth_token; | 222 auth_token_ = auth_token; |
| 216 if (already_called_) { | 223 if (already_called_) { |
| 217 DCHECK((!has_credentials_ && credentials == NULL) || | 224 DCHECK((!has_credentials_ && credentials == NULL) || |
| 218 (has_credentials_ && credentials->Equals(credentials_))); | 225 (has_credentials_ && credentials->Equals(credentials_))); |
| 219 next_state_ = STATE_GENERATE_AUTH_TOKEN; | 226 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| 220 } else { | 227 } else { |
| 221 already_called_ = true; | 228 already_called_ = true; |
| 222 if (credentials) { | 229 if (credentials) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 bool HttpAuthHandlerNegotiate::CanDelegate() const { | 335 bool HttpAuthHandlerNegotiate::CanDelegate() const { |
| 329 // TODO(cbentzel): Should delegation be allowed on proxies? | 336 // TODO(cbentzel): Should delegation be allowed on proxies? |
| 330 if (target_ == HttpAuth::AUTH_PROXY) | 337 if (target_ == HttpAuth::AUTH_PROXY) |
| 331 return false; | 338 return false; |
| 332 if (!url_security_manager_) | 339 if (!url_security_manager_) |
| 333 return false; | 340 return false; |
| 334 return url_security_manager_->CanDelegate(origin_); | 341 return url_security_manager_->CanDelegate(origin_); |
| 335 } | 342 } |
| 336 | 343 |
| 337 } // namespace net | 344 } // namespace net |
| OLD | NEW |