Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: net/http/http_auth.cc

Issue 28144: Implement the NTLM authentication scheme by porting... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Final upload before checkin Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_auth.h ('k') | net/http/http_auth_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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.h" 5 #include "net/http/http_auth.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "net/http/http_auth_handler_basic.h" 11 #include "net/http/http_auth_handler_basic.h"
12 #include "net/http/http_auth_handler_digest.h" 12 #include "net/http/http_auth_handler_digest.h"
13 #include "net/http/http_auth_handler_ntlm.h"
13 #include "net/http/http_response_headers.h" 14 #include "net/http/http_response_headers.h"
14 #include "net/http/http_util.h" 15 #include "net/http/http_util.h"
15 16
16 namespace net { 17 namespace net {
17 18
18 // static 19 // static
19 void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers, 20 void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers,
20 Target target, 21 Target target,
21 scoped_refptr<HttpAuthHandler>* handler) { 22 scoped_refptr<HttpAuthHandler>* handler) {
23 // A connection-based authentication scheme must continue to use the
24 // existing handler object in |*handler|.
25 if (*handler && (*handler)->is_connection_based()) {
26 const std::string header_name = GetChallengeHeaderName(target);
27 std::string challenge;
28 void* iter = NULL;
29 while (headers->EnumerateHeader(&iter, header_name, &challenge)) {
30 ChallengeTokenizer props(challenge.begin(), challenge.end());
31 if (LowerCaseEqualsASCII(props.scheme(), (*handler)->scheme().c_str()) &&
32 (*handler)->InitFromChallenge(challenge.begin(), challenge.end(),
33 target))
34 return;
35 }
36 }
37
22 // Choose the challenge whose authentication handler gives the maximum score. 38 // Choose the challenge whose authentication handler gives the maximum score.
23 scoped_refptr<HttpAuthHandler> best; 39 scoped_refptr<HttpAuthHandler> best;
24 const std::string header_name = GetChallengeHeaderName(target); 40 const std::string header_name = GetChallengeHeaderName(target);
25 std::string cur_challenge; 41 std::string cur_challenge;
26 void* iter = NULL; 42 void* iter = NULL;
27 while (headers->EnumerateHeader(&iter, header_name, &cur_challenge)) { 43 while (headers->EnumerateHeader(&iter, header_name, &cur_challenge)) {
28 scoped_refptr<HttpAuthHandler> cur; 44 scoped_refptr<HttpAuthHandler> cur;
29 CreateAuthHandler(cur_challenge, target, &cur); 45 CreateAuthHandler(cur_challenge, target, &cur);
30 if (cur && (!best || best->score() < cur->score())) 46 if (cur && (!best || best->score() < cur->score()))
31 best.swap(cur); 47 best.swap(cur);
32 } 48 }
33 handler->swap(best); 49 handler->swap(best);
34 } 50 }
35 51
36 // static 52 // static
37 void HttpAuth::CreateAuthHandler(const std::string& challenge, 53 void HttpAuth::CreateAuthHandler(const std::string& challenge,
38 Target target, 54 Target target,
39 scoped_refptr<HttpAuthHandler>* handler) { 55 scoped_refptr<HttpAuthHandler>* handler) {
40 // Find the right auth handler for the challenge's scheme. 56 // Find the right auth handler for the challenge's scheme.
41 ChallengeTokenizer props(challenge.begin(), challenge.end()); 57 ChallengeTokenizer props(challenge.begin(), challenge.end());
42 scoped_refptr<HttpAuthHandler> tmp_handler; 58 scoped_refptr<HttpAuthHandler> tmp_handler;
43 59
44 if (LowerCaseEqualsASCII(props.scheme(), "basic")) { 60 if (LowerCaseEqualsASCII(props.scheme(), "basic")) {
45 tmp_handler = new HttpAuthHandlerBasic(); 61 tmp_handler = new HttpAuthHandlerBasic();
46 } else if (LowerCaseEqualsASCII(props.scheme(), "digest")) { 62 } else if (LowerCaseEqualsASCII(props.scheme(), "digest")) {
47 tmp_handler = new HttpAuthHandlerDigest(); 63 tmp_handler = new HttpAuthHandlerDigest();
64 } else if (LowerCaseEqualsASCII(props.scheme(), "ntlm")) {
65 tmp_handler = new HttpAuthHandlerNTLM();
48 } 66 }
49 if (tmp_handler) { 67 if (tmp_handler) {
50 if (!tmp_handler->InitFromChallenge(challenge.begin(), challenge.end(), 68 if (!tmp_handler->InitFromChallenge(challenge.begin(), challenge.end(),
51 target)) { 69 target)) {
52 // Invalid/unsupported challenge. 70 // Invalid/unsupported challenge.
53 tmp_handler = NULL; 71 tmp_handler = NULL;
54 } 72 }
55 } 73 }
56 handler->swap(tmp_handler); 74 handler->swap(tmp_handler);
57 } 75 }
58 76
59 void HttpAuth::ChallengeTokenizer::Init(std::string::const_iterator begin, 77 void HttpAuth::ChallengeTokenizer::Init(std::string::const_iterator begin,
60 std::string::const_iterator end) { 78 std::string::const_iterator end) {
61 // The first space-separated token is the auth-scheme. 79 // The first space-separated token is the auth-scheme.
62 // NOTE: we are more permissive than RFC 2617 which says auth-scheme 80 // NOTE: we are more permissive than RFC 2617 which says auth-scheme
63 // is separated by 1*SP. 81 // is separated by 1*SP.
64 StringTokenizer tok(begin, end, HTTP_LWS); 82 StringTokenizer tok(begin, end, HTTP_LWS);
65 if (!tok.GetNext()) { 83 if (!tok.GetNext()) {
66 valid_ = false; 84 valid_ = false;
67 return; 85 return;
68 } 86 }
69 87
70 // Save the scheme's position. 88 // Save the scheme's position.
71 scheme_begin_ = tok.token_begin(); 89 scheme_begin_ = tok.token_begin();
72 scheme_end_ = tok.token_end(); 90 scheme_end_ = tok.token_end();
73 91
74 // Everything past scheme_end_ is a (comma separated) value list. 92 // Everything past scheme_end_ is a (comma separated) value list.
75 if (scheme_end_ != end) 93 props_ = HttpUtil::ValuesIterator(scheme_end_, end, ',');
76 props_ = HttpUtil::ValuesIterator(scheme_end_ + 1, end, ',');
77 } 94 }
78 95
79 // We expect properties to be formatted as one of: 96 // We expect properties to be formatted as one of:
80 // name="value" 97 // name="value"
81 // name=value 98 // name=value
82 // name= 99 // name=
83 bool HttpAuth::ChallengeTokenizer::GetNext() { 100 bool HttpAuth::ChallengeTokenizer::GetNext() {
84 if (!props_.GetNext()) 101 if (!props_.GetNext())
85 return false; 102 return false;
86 103
87 // Set the value as everything. Next we will split out the name. 104 // Set the value as everything. Next we will split out the name.
88 value_begin_ = props_.value_begin(); 105 value_begin_ = props_.value_begin();
89 value_end_ = props_.value_end(); 106 value_end_ = props_.value_end();
90 name_begin_ = name_end_ = value_end_; 107 name_begin_ = name_end_ = value_end_;
91 108
92 // Scan for the equals sign. 109 // Scan for the equals sign.
93 std::string::const_iterator equals = std::find(value_begin_, value_end_, '='); 110 std::string::const_iterator equals = std::find(value_begin_, value_end_, '=');
94 if (equals == value_end_ || equals == value_begin_) 111 if (equals == value_end_ || equals == value_begin_)
95 return valid_ = false; // Malformed 112 return valid_ = false; // Malformed
96 113
97 // Verify that the equals sign we found wasn't inside of quote marks. 114 // Verify that the equals sign we found wasn't inside of quote marks.
98 for (std::string::const_iterator it = value_begin_; it != equals; ++it) { 115 for (std::string::const_iterator it = value_begin_; it != equals; ++it) {
99 if (HttpUtil::IsQuote(*it)) 116 if (HttpUtil::IsQuote(*it))
100 return valid_ = false; // Malformed 117 return valid_ = false; // Malformed
101 } 118 }
102 119
103 name_begin_ = value_begin_; 120 name_begin_ = value_begin_;
104 name_end_ = equals; 121 name_end_ = equals;
105 value_begin_ = equals + 1; 122 value_begin_ = equals + 1;
106 123
107 if (value_begin_ != value_end_ && HttpUtil::IsQuote(*value_begin_)) { 124 if (value_begin_ != value_end_ && HttpUtil::IsQuote(*value_begin_)) {
108 // Trim surrounding quotemarks off the value 125 // Trim surrounding quotemarks off the value
109 if (*value_begin_ != *(value_end_ - 1)) 126 if (*value_begin_ != *(value_end_ - 1))
110 return valid_ = false; // Malformed -- mismatching quotes. 127 return valid_ = false; // Malformed -- mismatching quotes.
111 value_is_quoted_ = true; 128 value_is_quoted_ = true;
112 } else { 129 } else {
113 value_is_quoted_ = false; 130 value_is_quoted_ = false;
114 } 131 }
115 return true; 132 return true;
116 } 133 }
117 134
118 // If value() has quotemarks, unquote it. 135 // If value() has quotemarks, unquote it.
119 std::string HttpAuth::ChallengeTokenizer::unquoted_value() const { 136 std::string HttpAuth::ChallengeTokenizer::unquoted_value() const {
120 return HttpUtil::Unquote(value_begin_, value_end_); 137 return HttpUtil::Unquote(value_begin_, value_end_);
121 } 138 }
122 139
123 // static 140 // static
124 std::string HttpAuth::GetChallengeHeaderName(Target target) { 141 std::string HttpAuth::GetChallengeHeaderName(Target target) {
125 switch(target) { 142 switch (target) {
126 case AUTH_PROXY: 143 case AUTH_PROXY:
127 return "Proxy-Authenticate"; 144 return "Proxy-Authenticate";
128 case AUTH_SERVER: 145 case AUTH_SERVER:
129 return "WWW-Authenticate"; 146 return "WWW-Authenticate";
130 default: 147 default:
131 NOTREACHED(); 148 NOTREACHED();
132 return ""; 149 return "";
133 } 150 }
134 } 151 }
135 152
136 // static 153 // static
137 std::string HttpAuth::GetAuthorizationHeaderName(Target target) { 154 std::string HttpAuth::GetAuthorizationHeaderName(Target target) {
138 switch(target) { 155 switch (target) {
139 case AUTH_PROXY: 156 case AUTH_PROXY:
140 return "Proxy-Authorization"; 157 return "Proxy-Authorization";
141 case AUTH_SERVER: 158 case AUTH_SERVER:
142 return "Authorization"; 159 return "Authorization";
143 default: 160 default:
144 NOTREACHED(); 161 NOTREACHED();
145 return ""; 162 return "";
146 } 163 }
147 } 164 }
148 165
149 } // namespace net 166 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth.h ('k') | net/http/http_auth_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698