OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // 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 | |
9 #include "base/basictypes.h" | |
10 #include "base/strings/string_tokenizer.h" | |
11 #include "base/strings/string_util.h" | |
12 #include "net/base/net_errors.h" | |
13 #include "net/http/http_auth_challenge_tokenizer.h" | |
14 #include "net/http/http_auth_handler.h" | |
15 #include "net/http/http_auth_handler_factory.h" | |
16 #include "net/http/http_request_headers.h" | |
17 #include "net/http/http_response_headers.h" | |
18 #include "net/http/http_util.h" | |
19 | |
20 namespace net { | |
21 | |
22 HttpAuth::Identity::Identity() : source(IDENT_SRC_NONE), invalid(true) {} | |
23 | |
24 // static | |
25 void HttpAuth::ChooseBestChallenge( | |
26 HttpAuthHandlerFactory* http_auth_handler_factory, | |
27 const HttpResponseHeaders* headers, | |
28 Target target, | |
29 const GURL& origin, | |
30 const std::set<Scheme>& disabled_schemes, | |
31 const BoundNetLog& net_log, | |
32 scoped_ptr<HttpAuthHandler>* handler) { | |
33 DCHECK(http_auth_handler_factory); | |
34 DCHECK(handler->get() == NULL); | |
35 | |
36 // Choose the challenge whose authentication handler gives the maximum score. | |
37 scoped_ptr<HttpAuthHandler> best; | |
38 const std::string header_name = GetChallengeHeaderName(target); | |
39 std::string cur_challenge; | |
40 void* iter = NULL; | |
41 while (headers->EnumerateHeader(&iter, header_name, &cur_challenge)) { | |
42 scoped_ptr<HttpAuthHandler> cur; | |
43 int rv = http_auth_handler_factory->CreateAuthHandlerFromString( | |
44 cur_challenge, target, origin, net_log, &cur); | |
45 if (rv != OK) { | |
46 VLOG(1) << "Unable to create AuthHandler. Status: " | |
47 << ErrorToString(rv) << " Challenge: " << cur_challenge; | |
48 continue; | |
49 } | |
50 if (cur.get() && (!best.get() || best->score() < cur->score()) && | |
51 (disabled_schemes.find(cur->auth_scheme()) == disabled_schemes.end())) | |
52 best.swap(cur); | |
53 } | |
54 handler->swap(best); | |
55 } | |
56 | |
57 // static | |
58 HttpAuth::AuthorizationResult HttpAuth::HandleChallengeResponse( | |
59 HttpAuthHandler* handler, | |
60 const HttpResponseHeaders* headers, | |
61 Target target, | |
62 const std::set<Scheme>& disabled_schemes, | |
63 std::string* challenge_used) { | |
64 DCHECK(handler); | |
65 DCHECK(headers); | |
66 DCHECK(challenge_used); | |
67 challenge_used->clear(); | |
68 HttpAuth::Scheme current_scheme = handler->auth_scheme(); | |
69 if (disabled_schemes.find(current_scheme) != disabled_schemes.end()) | |
70 return HttpAuth::AUTHORIZATION_RESULT_REJECT; | |
71 std::string current_scheme_name = SchemeToString(current_scheme); | |
72 const std::string header_name = GetChallengeHeaderName(target); | |
73 void* iter = NULL; | |
74 std::string challenge; | |
75 HttpAuth::AuthorizationResult authorization_result = | |
76 HttpAuth::AUTHORIZATION_RESULT_INVALID; | |
77 while (headers->EnumerateHeader(&iter, header_name, &challenge)) { | |
78 HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end()); | |
79 if (!LowerCaseEqualsASCII(props.scheme(), current_scheme_name.c_str())) | |
80 continue; | |
81 authorization_result = handler->HandleAnotherChallenge(&props); | |
82 if (authorization_result != HttpAuth::AUTHORIZATION_RESULT_INVALID) { | |
83 *challenge_used = challenge; | |
84 return authorization_result; | |
85 } | |
86 } | |
87 // Finding no matches is equivalent to rejection. | |
88 return HttpAuth::AUTHORIZATION_RESULT_REJECT; | |
89 } | |
90 | |
91 // static | |
92 std::string HttpAuth::GetChallengeHeaderName(Target target) { | |
93 switch (target) { | |
94 case AUTH_PROXY: | |
95 return "Proxy-Authenticate"; | |
96 case AUTH_SERVER: | |
97 return "WWW-Authenticate"; | |
98 default: | |
99 NOTREACHED(); | |
100 return std::string(); | |
101 } | |
102 } | |
103 | |
104 // static | |
105 std::string HttpAuth::GetAuthorizationHeaderName(Target target) { | |
106 switch (target) { | |
107 case AUTH_PROXY: | |
108 return HttpRequestHeaders::kProxyAuthorization; | |
109 case AUTH_SERVER: | |
110 return HttpRequestHeaders::kAuthorization; | |
111 default: | |
112 NOTREACHED(); | |
113 return std::string(); | |
114 } | |
115 } | |
116 | |
117 // static | |
118 std::string HttpAuth::GetAuthTargetString(Target target) { | |
119 switch (target) { | |
120 case AUTH_PROXY: | |
121 return "proxy"; | |
122 case AUTH_SERVER: | |
123 return "server"; | |
124 default: | |
125 NOTREACHED(); | |
126 return std::string(); | |
127 } | |
128 } | |
129 | |
130 // static | |
131 const char* HttpAuth::SchemeToString(Scheme scheme) { | |
132 static const char* const kSchemeNames[] = { | |
133 "basic", | |
134 "digest", | |
135 "ntlm", | |
136 "negotiate", | |
137 "spdyproxy", | |
138 "mock", | |
139 }; | |
140 static_assert(arraysize(kSchemeNames) == AUTH_SCHEME_MAX, | |
141 "http auth scheme names incorrect size"); | |
142 if (scheme < AUTH_SCHEME_BASIC || scheme >= AUTH_SCHEME_MAX) { | |
143 NOTREACHED(); | |
144 return "invalid_scheme"; | |
145 } | |
146 return kSchemeNames[scheme]; | |
147 } | |
148 | |
149 } // namespace net | |
OLD | NEW |