blob: 738c1b8d7d01f782779e0d0409c2b599a913a1fe [file] [log] [blame]
[email protected]87c99b6a2011-05-13 20:06:481// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]c3b35c22008-09-27 03:19:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/http/http_auth.h"
6
7#include <algorithm>
8
[email protected]f4ebe772013-02-02 00:21:399#include "base/strings/string_tokenizer.h"
[email protected]125ef482013-06-11 18:32:4710#include "base/strings/string_util.h"
[email protected]fa55e192010-02-15 14:25:5011#include "net/base/net_errors.h"
[email protected]df41d0d82014-03-13 00:43:2412#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]40ecae222011-08-24 20:59:5613#include "net/http/http_auth_handler.h"
14#include "net/http/http_auth_handler_factory.h"
aberentbba302d2015-12-03 10:20:1915#include "net/http/http_auth_scheme.h"
[email protected]87c99b6a2011-05-13 20:06:4816#include "net/http/http_request_headers.h"
[email protected]c3b35c22008-09-27 03:19:4217#include "net/http/http_response_headers.h"
18#include "net/http/http_util.h"
19
20namespace net {
21
[email protected]2858bbf2010-10-05 23:46:0222HttpAuth::Identity::Identity() : source(IDENT_SRC_NONE), invalid(true) {}
23
[email protected]c3b35c22008-09-27 03:19:4224// static
[email protected]fa55e192010-02-15 14:25:5025void HttpAuth::ChooseBestChallenge(
26 HttpAuthHandlerFactory* http_auth_handler_factory,
asanka5ffd5d72016-03-23 16:20:4927 const HttpResponseHeaders& response_headers,
28 const SSLInfo& ssl_info,
[email protected]fa55e192010-02-15 14:25:5029 Target target,
30 const GURL& origin,
[email protected]547fc792011-01-13 13:31:1731 const std::set<Scheme>& disabled_schemes,
[email protected]ac5c06e2010-05-27 15:07:3832 const BoundNetLog& net_log,
danakj1fd259a02016-04-16 03:17:0933 std::unique_ptr<HttpAuthHandler>* handler) {
[email protected]fa55e192010-02-15 14:25:5034 DCHECK(http_auth_handler_factory);
[email protected]eca50e122010-09-11 14:03:3035 DCHECK(handler->get() == NULL);
[email protected]3f918782009-02-28 01:29:2436
[email protected]c3b35c22008-09-27 03:19:4237 // Choose the challenge whose authentication handler gives the maximum score.
danakj1fd259a02016-04-16 03:17:0938 std::unique_ptr<HttpAuthHandler> best;
[email protected]c3b35c22008-09-27 03:19:4239 const std::string header_name = GetChallengeHeaderName(target);
40 std::string cur_challenge;
olli.raulaee489a52016-01-25 08:37:1041 size_t iter = 0;
asanka5ffd5d72016-03-23 16:20:4942 while (response_headers.EnumerateHeader(&iter, header_name, &cur_challenge)) {
danakj1fd259a02016-04-16 03:17:0943 std::unique_ptr<HttpAuthHandler> cur;
[email protected]fa55e192010-02-15 14:25:5044 int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
asanka5ffd5d72016-03-23 16:20:4945 cur_challenge, target, ssl_info, origin, net_log, &cur);
[email protected]fa55e192010-02-15 14:25:5046 if (rv != OK) {
[email protected]b30a3f52010-10-16 01:05:4647 VLOG(1) << "Unable to create AuthHandler. Status: "
48 << ErrorToString(rv) << " Challenge: " << cur_challenge;
[email protected]fa55e192010-02-15 14:25:5049 continue;
50 }
[email protected]17be1a62010-07-27 19:20:2351 if (cur.get() && (!best.get() || best->score() < cur->score()) &&
[email protected]547fc792011-01-13 13:31:1752 (disabled_schemes.find(cur->auth_scheme()) == disabled_schemes.end()))
[email protected]17be1a62010-07-27 19:20:2353 best.swap(cur);
[email protected]c3b35c22008-09-27 03:19:4254 }
[email protected]f9ee6b52008-11-08 06:46:2355 handler->swap(best);
[email protected]c3b35c22008-09-27 03:19:4256}
57
[email protected]eca50e122010-09-11 14:03:3058// static
59HttpAuth::AuthorizationResult HttpAuth::HandleChallengeResponse(
60 HttpAuthHandler* handler,
asanka5ffd5d72016-03-23 16:20:4961 const HttpResponseHeaders& response_headers,
[email protected]eca50e122010-09-11 14:03:3062 Target target,
[email protected]547fc792011-01-13 13:31:1763 const std::set<Scheme>& disabled_schemes,
[email protected]c4857e02010-09-16 13:41:3664 std::string* challenge_used) {
[email protected]d66f8812010-10-20 16:52:1565 DCHECK(handler);
[email protected]c4857e02010-09-16 13:41:3666 DCHECK(challenge_used);
[email protected]d66f8812010-10-20 16:52:1567 challenge_used->clear();
[email protected]547fc792011-01-13 13:31:1768 HttpAuth::Scheme current_scheme = handler->auth_scheme();
[email protected]eca50e122010-09-11 14:03:3069 if (disabled_schemes.find(current_scheme) != disabled_schemes.end())
70 return HttpAuth::AUTHORIZATION_RESULT_REJECT;
[email protected]547fc792011-01-13 13:31:1771 std::string current_scheme_name = SchemeToString(current_scheme);
[email protected]eca50e122010-09-11 14:03:3072 const std::string header_name = GetChallengeHeaderName(target);
olli.raulaee489a52016-01-25 08:37:1073 size_t iter = 0;
[email protected]eca50e122010-09-11 14:03:3074 std::string challenge;
75 HttpAuth::AuthorizationResult authorization_result =
76 HttpAuth::AUTHORIZATION_RESULT_INVALID;
asanka5ffd5d72016-03-23 16:20:4977 while (response_headers.EnumerateHeader(&iter, header_name, &challenge)) {
[email protected]df41d0d82014-03-13 00:43:2478 HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end());
brettwbc17d2c82015-06-09 22:39:0879 if (!base::LowerCaseEqualsASCII(props.scheme(),
80 current_scheme_name.c_str()))
[email protected]eca50e122010-09-11 14:03:3081 continue;
82 authorization_result = handler->HandleAnotherChallenge(&props);
[email protected]c4857e02010-09-16 13:41:3683 if (authorization_result != HttpAuth::AUTHORIZATION_RESULT_INVALID) {
84 *challenge_used = challenge;
[email protected]eca50e122010-09-11 14:03:3085 return authorization_result;
[email protected]c4857e02010-09-16 13:41:3686 }
[email protected]eca50e122010-09-11 14:03:3087 }
[email protected]c4857e02010-09-16 13:41:3688 // Finding no matches is equivalent to rejection.
[email protected]eca50e122010-09-11 14:03:3089 return HttpAuth::AUTHORIZATION_RESULT_REJECT;
90}
91
[email protected]c3b35c22008-09-27 03:19:4292// static
93std::string HttpAuth::GetChallengeHeaderName(Target target) {
[email protected]3f918782009-02-28 01:29:2494 switch (target) {
[email protected]c3b35c22008-09-27 03:19:4295 case AUTH_PROXY:
96 return "Proxy-Authenticate";
97 case AUTH_SERVER:
98 return "WWW-Authenticate";
99 default:
100 NOTREACHED();
[email protected]007b3f82013-04-09 08:46:45101 return std::string();
[email protected]c3b35c22008-09-27 03:19:42102 }
103}
104
105// static
106std::string HttpAuth::GetAuthorizationHeaderName(Target target) {
[email protected]3f918782009-02-28 01:29:24107 switch (target) {
[email protected]c3b35c22008-09-27 03:19:42108 case AUTH_PROXY:
[email protected]87c99b6a2011-05-13 20:06:48109 return HttpRequestHeaders::kProxyAuthorization;
[email protected]c3b35c22008-09-27 03:19:42110 case AUTH_SERVER:
[email protected]87c99b6a2011-05-13 20:06:48111 return HttpRequestHeaders::kAuthorization;
[email protected]c3b35c22008-09-27 03:19:42112 default:
113 NOTREACHED();
[email protected]007b3f82013-04-09 08:46:45114 return std::string();
[email protected]c3b35c22008-09-27 03:19:42115 }
116}
117
[email protected]228404f2010-06-24 04:31:41118// static
[email protected]547fc792011-01-13 13:31:17119std::string HttpAuth::GetAuthTargetString(Target target) {
120 switch (target) {
121 case AUTH_PROXY:
122 return "proxy";
123 case AUTH_SERVER:
124 return "server";
125 default:
126 NOTREACHED();
[email protected]007b3f82013-04-09 08:46:45127 return std::string();
[email protected]547fc792011-01-13 13:31:17128 }
129}
130
131// static
132const char* HttpAuth::SchemeToString(Scheme scheme) {
133 static const char* const kSchemeNames[] = {
aberentbba302d2015-12-03 10:20:19134 kBasicAuthScheme, kDigestAuthScheme, kNtlmAuthScheme,
135 kNegotiateAuthScheme, kSpdyProxyAuthScheme, kMockAuthScheme};
mostynb91e0da982015-01-20 19:17:27136 static_assert(arraysize(kSchemeNames) == AUTH_SCHEME_MAX,
137 "http auth scheme names incorrect size");
[email protected]547fc792011-01-13 13:31:17138 if (scheme < AUTH_SCHEME_BASIC || scheme >= AUTH_SCHEME_MAX) {
139 NOTREACHED();
140 return "invalid_scheme";
141 }
142 return kSchemeNames[scheme];
[email protected]228404f2010-06-24 04:31:41143}
144
[email protected]c3b35c22008-09-27 03:19:42145} // namespace net