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" |
11 #include "net/base/address_family.h" | 11 #include "net/base/address_family.h" |
12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
13 #include "net/dns/host_resolver.h" | 13 #include "net/dns/host_resolver.h" |
14 #include "net/dns/single_request_host_resolver.h" | 14 #include "net/dns/single_request_host_resolver.h" |
15 #include "net/http/http_auth_filter.h" | 15 #include "net/http/http_auth_filter.h" |
16 #include "net/http/url_security_manager.h" | 16 #include "net/http/http_auth_preferences.h" |
17 | 17 |
18 namespace net { | 18 namespace net { |
19 | 19 |
20 HttpAuthHandlerNegotiate::Factory::Factory() | 20 HttpAuthHandlerNegotiate::Factory::Factory() |
21 : disable_cname_lookup_(false), | 21 : resolver_(NULL), |
22 use_port_(false), | |
23 resolver_(NULL), | |
24 #if defined(OS_WIN) | 22 #if defined(OS_WIN) |
25 max_token_length_(0), | 23 max_token_length_(0), |
26 #endif | 24 #endif |
27 is_unsupported_(false) { | 25 is_unsupported_(false) { |
28 } | 26 } |
29 | 27 |
30 HttpAuthHandlerNegotiate::Factory::~Factory() { | 28 HttpAuthHandlerNegotiate::Factory::~Factory() { |
31 } | 29 } |
32 | 30 |
33 void HttpAuthHandlerNegotiate::Factory::set_host_resolver( | 31 void HttpAuthHandlerNegotiate::Factory::set_host_resolver( |
(...skipping 17 matching lines...) Expand all Loading... |
51 &max_token_length_); | 49 &max_token_length_); |
52 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) | 50 if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) |
53 is_unsupported_ = true; | 51 is_unsupported_ = true; |
54 if (rv != OK) | 52 if (rv != OK) |
55 return rv; | 53 return rv; |
56 } | 54 } |
57 // TODO(cbentzel): Move towards model of parsing in the factory | 55 // TODO(cbentzel): Move towards model of parsing in the factory |
58 // method and only constructing when valid. | 56 // method and only constructing when valid. |
59 scoped_ptr<HttpAuthHandler> tmp_handler( | 57 scoped_ptr<HttpAuthHandler> tmp_handler( |
60 new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_, | 58 new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_, |
61 url_security_manager(), resolver_, | 59 http_auth_preferences(), resolver_)); |
62 disable_cname_lookup_, use_port_)); | |
63 #elif defined(OS_ANDROID) | 60 #elif defined(OS_ANDROID) |
64 if (is_unsupported_ || auth_library_->empty() || reason == CREATE_PREEMPTIVE) | 61 if (is_unsupported_ || !http_auth_preferences() || |
| 62 http_auth_preferences()->AuthAndroidNegotiateAccountType().empty() || |
| 63 reason == CREATE_PREEMPTIVE) |
65 return ERR_UNSUPPORTED_AUTH_SCHEME; | 64 return ERR_UNSUPPORTED_AUTH_SCHEME; |
66 // TODO(cbentzel): Move towards model of parsing in the factory | 65 // TODO(cbentzel): Move towards model of parsing in the factory |
67 // method and only constructing when valid. | 66 // method and only constructing when valid. |
68 scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( | 67 scoped_ptr<HttpAuthHandler> tmp_handler( |
69 auth_library_.get(), url_security_manager(), resolver_, | 68 new HttpAuthHandlerNegotiate(http_auth_preferences(), resolver_)); |
70 disable_cname_lookup_, use_port_)); | |
71 #elif defined(OS_POSIX) | 69 #elif defined(OS_POSIX) |
72 if (is_unsupported_) | 70 if (is_unsupported_) |
73 return ERR_UNSUPPORTED_AUTH_SCHEME; | 71 return ERR_UNSUPPORTED_AUTH_SCHEME; |
74 if (!auth_library_->Init()) { | 72 if (!auth_library_->Init()) { |
75 is_unsupported_ = true; | 73 is_unsupported_ = true; |
76 return ERR_UNSUPPORTED_AUTH_SCHEME; | 74 return ERR_UNSUPPORTED_AUTH_SCHEME; |
77 } | 75 } |
78 // TODO(ahendrickson): Move towards model of parsing in the factory | 76 // TODO(ahendrickson): Move towards model of parsing in the factory |
79 // method and only constructing when valid. | 77 // method and only constructing when valid. |
80 scoped_ptr<HttpAuthHandler> tmp_handler( | 78 scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( |
81 new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(), | 79 auth_library_.get(), http_auth_preferences(), resolver_)); |
82 resolver_, disable_cname_lookup_, | |
83 use_port_)); | |
84 #endif | 80 #endif |
85 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 81 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
86 return ERR_INVALID_RESPONSE; | 82 return ERR_INVALID_RESPONSE; |
87 handler->swap(tmp_handler); | 83 handler->swap(tmp_handler); |
88 return OK; | 84 return OK; |
89 } | 85 } |
90 | 86 |
91 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( | 87 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( |
| 88 #if !defined(OS_ANDROID) |
92 AuthLibrary* auth_library, | 89 AuthLibrary* auth_library, |
| 90 #endif |
93 #if defined(OS_WIN) | 91 #if defined(OS_WIN) |
94 ULONG max_token_length, | 92 ULONG max_token_length, |
95 #endif | 93 #endif |
96 URLSecurityManager* url_security_manager, | 94 const HttpAuthPreferences* prefs, |
97 HostResolver* resolver, | 95 HostResolver* resolver) |
98 bool disable_cname_lookup, | |
99 bool use_port) | |
100 #if defined(OS_ANDROID) | 96 #if defined(OS_ANDROID) |
101 : auth_system_(*auth_library), | 97 : auth_system_(prefs), |
102 #elif defined(OS_WIN) | 98 #elif defined(OS_WIN) |
103 : auth_system_(auth_library, "Negotiate", NEGOSSP_NAME, max_token_length), | 99 : auth_system_(auth_library, "Negotiate", NEGOSSP_NAME, max_token_length), |
104 #elif defined(OS_POSIX) | 100 #elif defined(OS_POSIX) |
105 : auth_system_(auth_library, "Negotiate", CHROME_GSS_SPNEGO_MECH_OID_DESC), | 101 : auth_system_(auth_library, "Negotiate", CHROME_GSS_SPNEGO_MECH_OID_DESC), |
106 #endif | 102 #endif |
107 disable_cname_lookup_(disable_cname_lookup), | |
108 use_port_(use_port), | |
109 resolver_(resolver), | 103 resolver_(resolver), |
110 already_called_(false), | 104 already_called_(false), |
111 has_credentials_(false), | 105 has_credentials_(false), |
112 auth_token_(NULL), | 106 auth_token_(NULL), |
113 next_state_(STATE_NONE), | 107 next_state_(STATE_NONE), |
114 url_security_manager_(url_security_manager) { | 108 http_auth_preferences_(prefs) { |
115 } | 109 } |
116 | 110 |
117 HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() { | 111 HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() { |
118 } | 112 } |
119 | 113 |
120 std::string HttpAuthHandlerNegotiate::CreateSPN( | 114 std::string HttpAuthHandlerNegotiate::CreateSPN(const AddressList& address_list, |
121 const AddressList& address_list, const GURL& origin) { | 115 const GURL& origin) { |
122 // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI, | 116 // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI, |
123 // and in the form HTTP@<host>:<port> through GSSAPI | 117 // and in the form HTTP@<host>:<port> through GSSAPI |
124 // http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx | 118 // http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx |
125 // | 119 // |
126 // However, reality differs from the specification. A good description of | 120 // However, reality differs from the specification. A good description of |
127 // the problems can be found here: | 121 // the problems can be found here: |
128 // http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-k
b911149-and-kb908209-are-not-the-soluton.aspx | 122 // http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-k
b911149-and-kb908209-are-not-the-soluton.aspx |
129 // | 123 // |
130 // Typically the <host> portion should be the canonical FQDN for the service. | 124 // Typically the <host> portion should be the canonical FQDN for the service. |
131 // If this could not be resolved, the original hostname in the URL will be | 125 // If this could not be resolved, the original hostname in the URL will be |
(...skipping 18 matching lines...) Expand all Loading... |
150 // non-standard ports are included. | 144 // non-standard ports are included. |
151 int port = origin.EffectiveIntPort(); | 145 int port = origin.EffectiveIntPort(); |
152 std::string server = address_list.canonical_name(); | 146 std::string server = address_list.canonical_name(); |
153 if (server.empty()) | 147 if (server.empty()) |
154 server = origin.host(); | 148 server = origin.host(); |
155 #if defined(OS_WIN) | 149 #if defined(OS_WIN) |
156 static const char kSpnSeparator = '/'; | 150 static const char kSpnSeparator = '/'; |
157 #elif defined(OS_POSIX) | 151 #elif defined(OS_POSIX) |
158 static const char kSpnSeparator = '@'; | 152 static const char kSpnSeparator = '@'; |
159 #endif | 153 #endif |
160 if (port != 80 && port != 443 && use_port_) { | 154 if (port != 80 && port != 443 && |
| 155 (http_auth_preferences_ && |
| 156 http_auth_preferences_->NegotiateEnablePort())) { |
161 return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(), | 157 return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(), |
162 port); | 158 port); |
163 } else { | 159 } else { |
164 return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str()); | 160 return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str()); |
165 } | 161 } |
166 } | 162 } |
167 | 163 |
168 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge( | 164 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge( |
169 HttpAuthChallengeTokenizer* challenge) { | 165 HttpAuthChallengeTokenizer* challenge) { |
170 return auth_system_.ParseChallenge(challenge); | 166 return auth_system_.ParseChallenge(challenge); |
171 } | 167 } |
172 | 168 |
173 // Require identity on first pass instead of second. | 169 // Require identity on first pass instead of second. |
174 bool HttpAuthHandlerNegotiate::NeedsIdentity() { | 170 bool HttpAuthHandlerNegotiate::NeedsIdentity() { |
175 return auth_system_.NeedsIdentity(); | 171 return auth_system_.NeedsIdentity(); |
176 } | 172 } |
177 | 173 |
178 bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() { | 174 bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() { |
179 if (target_ == HttpAuth::AUTH_PROXY) | 175 if (target_ == HttpAuth::AUTH_PROXY) |
180 return true; | 176 return true; |
181 if (!url_security_manager_) | 177 if (!http_auth_preferences_) |
182 return false; | 178 return false; |
183 return url_security_manager_->CanUseDefaultCredentials(origin_); | 179 return http_auth_preferences_->CanUseDefaultCredentials(origin_); |
184 } | 180 } |
185 | 181 |
186 bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() { | 182 bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() { |
187 return auth_system_.AllowsExplicitCredentials(); | 183 return auth_system_.AllowsExplicitCredentials(); |
188 } | 184 } |
189 | 185 |
190 // The Negotiate challenge header looks like: | 186 // The Negotiate challenge header looks like: |
191 // WWW-Authenticate: NEGOTIATE auth-data | 187 // WWW-Authenticate: NEGOTIATE auth-data |
192 bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge) { | 188 bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge) { |
193 #if defined(OS_POSIX) | 189 #if defined(OS_POSIX) |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 rv = ERR_FAILED; | 273 rv = ERR_FAILED; |
278 break; | 274 break; |
279 } | 275 } |
280 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 276 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
281 | 277 |
282 return rv; | 278 return rv; |
283 } | 279 } |
284 | 280 |
285 int HttpAuthHandlerNegotiate::DoResolveCanonicalName() { | 281 int HttpAuthHandlerNegotiate::DoResolveCanonicalName() { |
286 next_state_ = STATE_RESOLVE_CANONICAL_NAME_COMPLETE; | 282 next_state_ = STATE_RESOLVE_CANONICAL_NAME_COMPLETE; |
287 if (disable_cname_lookup_ || !resolver_) | 283 if ((http_auth_preferences_ && |
| 284 http_auth_preferences_->NegotiateDisableCnameLookup()) || |
| 285 !resolver_) |
288 return OK; | 286 return OK; |
289 | 287 |
290 // TODO(cbentzel): Add reverse DNS lookup for numeric addresses. | 288 // TODO(cbentzel): Add reverse DNS lookup for numeric addresses. |
291 DCHECK(!single_resolve_.get()); | 289 DCHECK(!single_resolve_.get()); |
292 HostResolver::RequestInfo info(HostPortPair(origin_.host(), 0)); | 290 HostResolver::RequestInfo info(HostPortPair(origin_.host(), 0)); |
293 info.set_host_resolver_flags(HOST_RESOLVER_CANONNAME); | 291 info.set_host_resolver_flags(HOST_RESOLVER_CANONNAME); |
294 single_resolve_.reset(new SingleRequestHostResolver(resolver_)); | 292 single_resolve_.reset(new SingleRequestHostResolver(resolver_)); |
295 return single_resolve_->Resolve( | 293 return single_resolve_->Resolve( |
296 info, | 294 info, |
297 DEFAULT_PRIORITY, | 295 DEFAULT_PRIORITY, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 int HttpAuthHandlerNegotiate::DoGenerateAuthTokenComplete(int rv) { | 327 int HttpAuthHandlerNegotiate::DoGenerateAuthTokenComplete(int rv) { |
330 DCHECK_NE(ERR_IO_PENDING, rv); | 328 DCHECK_NE(ERR_IO_PENDING, rv); |
331 auth_token_ = NULL; | 329 auth_token_ = NULL; |
332 return rv; | 330 return rv; |
333 } | 331 } |
334 | 332 |
335 bool HttpAuthHandlerNegotiate::CanDelegate() const { | 333 bool HttpAuthHandlerNegotiate::CanDelegate() const { |
336 // TODO(cbentzel): Should delegation be allowed on proxies? | 334 // TODO(cbentzel): Should delegation be allowed on proxies? |
337 if (target_ == HttpAuth::AUTH_PROXY) | 335 if (target_ == HttpAuth::AUTH_PROXY) |
338 return false; | 336 return false; |
339 if (!url_security_manager_) | 337 if (!http_auth_preferences_) |
340 return false; | 338 return false; |
341 return url_security_manager_->CanDelegate(origin_); | 339 return http_auth_preferences_->CanDelegate(origin_); |
342 } | 340 } |
343 | 341 |
344 } // namespace net | 342 } // namespace net |
OLD | NEW |