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

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

Issue 3040016: Net: Convert username and password to string16. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: address comments Created 10 years, 4 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_handler_digest.h ('k') | net/http/http_auth_handler_digest_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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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_digest.h" 5 #include "net/http/http_auth_handler_digest.h"
6 6
7 #include <string>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "base/md5.h" 10 #include "base/md5.h"
9 #include "base/rand_util.h" 11 #include "base/rand_util.h"
10 #include "base/string_util.h" 12 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
12 #include "net/base/net_errors.h" 14 #include "net/base/net_errors.h"
13 #include "net/base/net_util.h" 15 #include "net/base/net_util.h"
14 #include "net/http/http_auth.h" 16 #include "net/http/http_auth.h"
15 #include "net/http/http_request_info.h" 17 #include "net/http/http_request_info.h"
16 #include "net/http/http_util.h" 18 #include "net/http/http_util.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 case ALGORITHM_MD5: 81 case ALGORITHM_MD5:
80 return "MD5"; 82 return "MD5";
81 case ALGORITHM_MD5_SESS: 83 case ALGORITHM_MD5_SESS:
82 return "MD5-sess"; 84 return "MD5-sess";
83 default: 85 default:
84 return ""; 86 return "";
85 } 87 }
86 } 88 }
87 89
88 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( 90 int HttpAuthHandlerDigest::GenerateAuthTokenImpl(
89 const std::wstring* username, 91 const string16* username,
90 const std::wstring* password, 92 const string16* password,
91 const HttpRequestInfo* request, 93 const HttpRequestInfo* request,
92 CompletionCallback* callback, 94 CompletionCallback* callback,
93 std::string* auth_token) { 95 std::string* auth_token) {
94 // Generate a random client nonce. 96 // Generate a random client nonce.
95 std::string cnonce = GenerateNonce(); 97 std::string cnonce = GenerateNonce();
96 98
97 // Extract the request method and path -- the meaning of 'path' is overloaded 99 // Extract the request method and path -- the meaning of 'path' is overloaded
98 // in certain cases, to be a hostname. 100 // in certain cases, to be a hostname.
99 std::string method; 101 std::string method;
100 std::string path; 102 std::string path;
101 GetRequestMethodAndPath(request, &method, &path); 103 GetRequestMethodAndPath(request, &method, &path);
102 104
103 *auth_token = AssembleCredentials(method, path, 105 *auth_token = AssembleCredentials(method, path,
104 // TODO(eroman): is this the right encoding? 106 *username,
105 WideToUTF8(*username), 107 *password,
106 WideToUTF8(*password),
107 cnonce, nonce_count_); 108 cnonce, nonce_count_);
108 return OK; 109 return OK;
109 } 110 }
110 111
111 void HttpAuthHandlerDigest::GetRequestMethodAndPath( 112 void HttpAuthHandlerDigest::GetRequestMethodAndPath(
112 const HttpRequestInfo* request, 113 const HttpRequestInfo* request,
113 std::string* method, 114 std::string* method,
114 std::string* path) const { 115 std::string* path) const {
115 DCHECK(request); 116 DCHECK(request);
116 117
117 const GURL& url = request->url; 118 const GURL& url = request->url;
118 119
119 if (target_ == HttpAuth::AUTH_PROXY && url.SchemeIs("https")) { 120 if (target_ == HttpAuth::AUTH_PROXY && url.SchemeIs("https")) {
120 *method = "CONNECT"; 121 *method = "CONNECT";
121 *path = GetHostAndPort(url); 122 *path = GetHostAndPort(url);
122 } else { 123 } else {
123 *method = request->method; 124 *method = request->method;
124 *path = HttpUtil::PathForRequest(url); 125 *path = HttpUtil::PathForRequest(url);
125 } 126 }
126 } 127 }
127 128
128 std::string HttpAuthHandlerDigest::AssembleResponseDigest( 129 std::string HttpAuthHandlerDigest::AssembleResponseDigest(
129 const std::string& method, 130 const std::string& method,
130 const std::string& path, 131 const std::string& path,
131 const std::string& username, 132 const string16& username,
132 const std::string& password, 133 const string16& password,
133 const std::string& cnonce, 134 const std::string& cnonce,
134 const std::string& nc) const { 135 const std::string& nc) const {
135 // ha1 = MD5(A1) 136 // ha1 = MD5(A1)
136 std::string ha1 = MD5String(username + ":" + realm_ + ":" + password); 137 // TODO(eroman): is this the right encoding?
138 std::string ha1 = MD5String(UTF16ToUTF8(username) + ":" + realm_ + ":" +
139 UTF16ToUTF8(password));
137 if (algorithm_ == HttpAuthHandlerDigest::ALGORITHM_MD5_SESS) 140 if (algorithm_ == HttpAuthHandlerDigest::ALGORITHM_MD5_SESS)
138 ha1 = MD5String(ha1 + ":" + nonce_ + ":" + cnonce); 141 ha1 = MD5String(ha1 + ":" + nonce_ + ":" + cnonce);
139 142
140 // ha2 = MD5(A2) 143 // ha2 = MD5(A2)
141 // TODO(eroman): need to add MD5(req-entity-body) for qop=auth-int. 144 // TODO(eroman): need to add MD5(req-entity-body) for qop=auth-int.
142 std::string ha2 = MD5String(method + ":" + path); 145 std::string ha2 = MD5String(method + ":" + path);
143 146
144 std::string nc_part; 147 std::string nc_part;
145 if (qop_ != HttpAuthHandlerDigest::QOP_UNSPECIFIED) { 148 if (qop_ != HttpAuthHandlerDigest::QOP_UNSPECIFIED) {
146 nc_part = nc + ":" + cnonce + ":" + QopToString(qop_) + ":"; 149 nc_part = nc + ":" + cnonce + ":" + QopToString(qop_) + ":";
147 } 150 }
148 151
149 return MD5String(ha1 + ":" + nonce_ + ":" + nc_part + ha2); 152 return MD5String(ha1 + ":" + nonce_ + ":" + nc_part + ha2);
150 } 153 }
151 154
152 std::string HttpAuthHandlerDigest::AssembleCredentials( 155 std::string HttpAuthHandlerDigest::AssembleCredentials(
153 const std::string& method, 156 const std::string& method,
154 const std::string& path, 157 const std::string& path,
155 const std::string& username, 158 const string16& username,
156 const std::string& password, 159 const string16& password,
157 const std::string& cnonce, 160 const std::string& cnonce,
158 int nonce_count) const { 161 int nonce_count) const {
159 // the nonce-count is an 8 digit hex string. 162 // the nonce-count is an 8 digit hex string.
160 std::string nc = StringPrintf("%08x", nonce_count); 163 std::string nc = StringPrintf("%08x", nonce_count);
161 164
165 // TODO(eroman): is this the right encoding?
162 std::string authorization = std::string("Digest username=") + 166 std::string authorization = std::string("Digest username=") +
163 HttpUtil::Quote(username); 167 HttpUtil::Quote(UTF16ToUTF8(username));
164 authorization += ", realm=" + HttpUtil::Quote(realm_); 168 authorization += ", realm=" + HttpUtil::Quote(realm_);
165 authorization += ", nonce=" + HttpUtil::Quote(nonce_); 169 authorization += ", nonce=" + HttpUtil::Quote(nonce_);
166 authorization += ", uri=" + HttpUtil::Quote(path); 170 authorization += ", uri=" + HttpUtil::Quote(path);
167 171
168 if (algorithm_ != ALGORITHM_UNSPECIFIED) { 172 if (algorithm_ != ALGORITHM_UNSPECIFIED) {
169 authorization += ", algorithm=" + AlgorithmToString(algorithm_); 173 authorization += ", algorithm=" + AlgorithmToString(algorithm_);
170 } 174 }
171 std::string response = AssembleResponseDigest(method, path, username, 175 std::string response = AssembleResponseDigest(method, path, username,
172 password, cnonce, nc); 176 password, cnonce, nc);
173 // No need to call HttpUtil::Quote() as the response digest cannot contain 177 // No need to call HttpUtil::Quote() as the response digest cannot contain
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 properties_ = ENCRYPTS_IDENTITY; 216 properties_ = ENCRYPTS_IDENTITY;
213 217
214 // Initialize to defaults. 218 // Initialize to defaults.
215 stale_ = false; 219 stale_ = false;
216 algorithm_ = ALGORITHM_UNSPECIFIED; 220 algorithm_ = ALGORITHM_UNSPECIFIED;
217 qop_ = QOP_UNSPECIFIED; 221 qop_ = QOP_UNSPECIFIED;
218 realm_ = nonce_ = domain_ = opaque_ = std::string(); 222 realm_ = nonce_ = domain_ = opaque_ = std::string();
219 223
220 if (!challenge->valid() || 224 if (!challenge->valid() ||
221 !LowerCaseEqualsASCII(challenge->scheme(), "digest")) 225 !LowerCaseEqualsASCII(challenge->scheme(), "digest"))
222 return false; // FAIL -- Couldn't match auth-scheme. 226 return false; // FAIL -- Couldn't match auth-scheme.
223 227
224 // Loop through all the properties. 228 // Loop through all the properties.
225 while (challenge->GetNext()) { 229 while (challenge->GetNext()) {
226 if (challenge->value().empty()) { 230 if (challenge->value().empty()) {
227 DLOG(INFO) << "Invalid digest property"; 231 DLOG(INFO) << "Invalid digest property";
228 return false; 232 return false;
229 } 233 }
230 234
231 if (!ParseChallengeProperty(challenge->name(), challenge->unquoted_value())) 235 if (!ParseChallengeProperty(challenge->name(), challenge->unquoted_value()))
232 return false; // FAIL -- couldn't parse a property. 236 return false; // FAIL -- couldn't parse a property.
233 } 237 }
234 238
235 // Check if tokenizer failed. 239 // Check if tokenizer failed.
236 if (!challenge->valid()) 240 if (!challenge->valid())
237 return false; // FAIL 241 return false; // FAIL
238 242
239 // Check that a minimum set of properties were provided. 243 // Check that a minimum set of properties were provided.
240 if (nonce_.empty()) 244 if (nonce_.empty())
241 return false; // FAIL 245 return false; // FAIL
242 246
243 return true; 247 return true;
244 } 248 }
245 249
246 bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name, 250 bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name,
247 const std::string& value) { 251 const std::string& value) {
248 if (LowerCaseEqualsASCII(name, "realm")) { 252 if (LowerCaseEqualsASCII(name, "realm")) {
249 realm_ = value; 253 realm_ = value;
250 } else if (LowerCaseEqualsASCII(name, "nonce")) { 254 } else if (LowerCaseEqualsASCII(name, "nonce")) {
251 nonce_ = value; 255 nonce_ = value;
252 } else if (LowerCaseEqualsASCII(name, "domain")) { 256 } else if (LowerCaseEqualsASCII(name, "domain")) {
253 domain_ = value; 257 domain_ = value;
254 } else if (LowerCaseEqualsASCII(name, "opaque")) { 258 } else if (LowerCaseEqualsASCII(name, "opaque")) {
255 opaque_ = value; 259 opaque_ = value;
256 } else if (LowerCaseEqualsASCII(name, "stale")) { 260 } else if (LowerCaseEqualsASCII(name, "stale")) {
257 // Parse the stale boolean. 261 // Parse the stale boolean.
258 stale_ = LowerCaseEqualsASCII(value, "true"); 262 stale_ = LowerCaseEqualsASCII(value, "true");
259 } else if (LowerCaseEqualsASCII(name, "algorithm")) { 263 } else if (LowerCaseEqualsASCII(name, "algorithm")) {
260 // Parse the algorithm. 264 // Parse the algorithm.
261 if (LowerCaseEqualsASCII(value, "md5")) { 265 if (LowerCaseEqualsASCII(value, "md5")) {
262 algorithm_ = ALGORITHM_MD5; 266 algorithm_ = ALGORITHM_MD5;
263 } else if (LowerCaseEqualsASCII(value, "md5-sess")) { 267 } else if (LowerCaseEqualsASCII(value, "md5-sess")) {
264 algorithm_ = ALGORITHM_MD5_SESS; 268 algorithm_ = ALGORITHM_MD5_SESS;
265 } else { 269 } else {
266 DLOG(INFO) << "Unknown value of algorithm"; 270 DLOG(INFO) << "Unknown value of algorithm";
267 return false; // FAIL -- unsupported value of algorithm. 271 return false; // FAIL -- unsupported value of algorithm.
268 } 272 }
269 } else if (LowerCaseEqualsASCII(name, "qop")) { 273 } else if (LowerCaseEqualsASCII(name, "qop")) {
270 // Parse the comma separated list of qops. 274 // Parse the comma separated list of qops.
271 HttpUtil::ValuesIterator qop_values(value.begin(), value.end(), ','); 275 HttpUtil::ValuesIterator qop_values(value.begin(), value.end(), ',');
272 while (qop_values.GetNext()) { 276 while (qop_values.GetNext()) {
273 if (LowerCaseEqualsASCII(qop_values.value(), "auth")) { 277 if (LowerCaseEqualsASCII(qop_values.value(), "auth")) {
274 qop_ |= QOP_AUTH; 278 qop_ |= QOP_AUTH;
275 } else if (LowerCaseEqualsASCII(qop_values.value(), "auth-int")) { 279 } else if (LowerCaseEqualsASCII(qop_values.value(), "auth-int")) {
276 qop_ |= QOP_AUTH_INT; 280 qop_ |= QOP_AUTH_INT;
277 } 281 }
(...skipping 23 matching lines...) Expand all
301 // method and only constructing when valid. 305 // method and only constructing when valid.
302 scoped_ptr<HttpAuthHandler> tmp_handler( 306 scoped_ptr<HttpAuthHandler> tmp_handler(
303 new HttpAuthHandlerDigest(digest_nonce_count)); 307 new HttpAuthHandlerDigest(digest_nonce_count));
304 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) 308 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
305 return ERR_INVALID_RESPONSE; 309 return ERR_INVALID_RESPONSE;
306 handler->swap(tmp_handler); 310 handler->swap(tmp_handler);
307 return OK; 311 return OK;
308 } 312 }
309 313
310 } // namespace net 314 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_handler_digest.h ('k') | net/http/http_auth_handler_digest_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698