| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/md5.h" | 10 #include "base/md5.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 // for the new challenge. | 122 // for the new challenge. |
| 123 std::string original_realm; | 123 std::string original_realm; |
| 124 while (parameters.GetNext()) { | 124 while (parameters.GetNext()) { |
| 125 if (LowerCaseEqualsASCII(parameters.name(), "stale")) { | 125 if (LowerCaseEqualsASCII(parameters.name(), "stale")) { |
| 126 if (LowerCaseEqualsASCII(parameters.value(), "true")) | 126 if (LowerCaseEqualsASCII(parameters.value(), "true")) |
| 127 return HttpAuth::AUTHORIZATION_RESULT_STALE; | 127 return HttpAuth::AUTHORIZATION_RESULT_STALE; |
| 128 } else if (LowerCaseEqualsASCII(parameters.name(), "realm")) { | 128 } else if (LowerCaseEqualsASCII(parameters.name(), "realm")) { |
| 129 original_realm = parameters.value(); | 129 original_realm = parameters.value(); |
| 130 } | 130 } |
| 131 } | 131 } |
| 132 return (original_realm_ != original_realm) ? | 132 return (original_realm_ != original_realm) |
| 133 HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM : | 133 ? HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM |
| 134 HttpAuth::AUTHORIZATION_RESULT_REJECT; | 134 : HttpAuth::AUTHORIZATION_RESULT_REJECT; |
| 135 } | 135 } |
| 136 | 136 |
| 137 bool HttpAuthHandlerDigest::Init(HttpAuthChallengeTokenizer* challenge) { | 137 bool HttpAuthHandlerDigest::Init(HttpAuthChallengeTokenizer* challenge) { |
| 138 return ParseChallenge(challenge); | 138 return ParseChallenge(challenge); |
| 139 } | 139 } |
| 140 | 140 |
| 141 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( | 141 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( |
| 142 const AuthCredentials* credentials, const HttpRequestInfo* request, | 142 const AuthCredentials* credentials, |
| 143 const CompletionCallback& callback, std::string* auth_token) { | 143 const HttpRequestInfo* request, |
| 144 const CompletionCallback& callback, |
| 145 std::string* auth_token) { |
| 144 // Generate a random client nonce. | 146 // Generate a random client nonce. |
| 145 std::string cnonce = nonce_generator_->GenerateNonce(); | 147 std::string cnonce = nonce_generator_->GenerateNonce(); |
| 146 | 148 |
| 147 // Extract the request method and path -- the meaning of 'path' is overloaded | 149 // Extract the request method and path -- the meaning of 'path' is overloaded |
| 148 // in certain cases, to be a hostname. | 150 // in certain cases, to be a hostname. |
| 149 std::string method; | 151 std::string method; |
| 150 std::string path; | 152 std::string path; |
| 151 GetRequestMethodAndPath(request, &method, &path); | 153 GetRequestMethodAndPath(request, &method, &path); |
| 152 | 154 |
| 153 *auth_token = AssembleCredentials(method, path, *credentials, | 155 *auth_token = |
| 154 cnonce, nonce_count_); | 156 AssembleCredentials(method, path, *credentials, cnonce, nonce_count_); |
| 155 return OK; | 157 return OK; |
| 156 } | 158 } |
| 157 | 159 |
| 158 HttpAuthHandlerDigest::HttpAuthHandlerDigest( | 160 HttpAuthHandlerDigest::HttpAuthHandlerDigest( |
| 159 int nonce_count, const NonceGenerator* nonce_generator) | 161 int nonce_count, |
| 162 const NonceGenerator* nonce_generator) |
| 160 : stale_(false), | 163 : stale_(false), |
| 161 algorithm_(ALGORITHM_UNSPECIFIED), | 164 algorithm_(ALGORITHM_UNSPECIFIED), |
| 162 qop_(QOP_UNSPECIFIED), | 165 qop_(QOP_UNSPECIFIED), |
| 163 nonce_count_(nonce_count), | 166 nonce_count_(nonce_count), |
| 164 nonce_generator_(nonce_generator) { | 167 nonce_generator_(nonce_generator) { |
| 165 DCHECK(nonce_generator_); | 168 DCHECK(nonce_generator_); |
| 166 } | 169 } |
| 167 | 170 |
| 168 HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { | 171 HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { |
| 169 } | 172 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 200 | 203 |
| 201 // FAIL -- Couldn't match auth-scheme. | 204 // FAIL -- Couldn't match auth-scheme. |
| 202 if (!LowerCaseEqualsASCII(challenge->scheme(), "digest")) | 205 if (!LowerCaseEqualsASCII(challenge->scheme(), "digest")) |
| 203 return false; | 206 return false; |
| 204 | 207 |
| 205 HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs(); | 208 HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs(); |
| 206 | 209 |
| 207 // Loop through all the properties. | 210 // Loop through all the properties. |
| 208 while (parameters.GetNext()) { | 211 while (parameters.GetNext()) { |
| 209 // FAIL -- couldn't parse a property. | 212 // FAIL -- couldn't parse a property. |
| 210 if (!ParseChallengeProperty(parameters.name(), | 213 if (!ParseChallengeProperty(parameters.name(), parameters.value())) |
| 211 parameters.value())) | |
| 212 return false; | 214 return false; |
| 213 } | 215 } |
| 214 | 216 |
| 215 // Check if tokenizer failed. | 217 // Check if tokenizer failed. |
| 216 if (!parameters.valid()) | 218 if (!parameters.valid()) |
| 217 return false; | 219 return false; |
| 218 | 220 |
| 219 // Check that a minimum set of properties were provided. | 221 // Check that a minimum set of properties were provided. |
| 220 if (nonce_.empty()) | 222 if (nonce_.empty()) |
| 221 return false; | 223 return false; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 std::string HttpAuthHandlerDigest::AssembleCredentials( | 346 std::string HttpAuthHandlerDigest::AssembleCredentials( |
| 345 const std::string& method, | 347 const std::string& method, |
| 346 const std::string& path, | 348 const std::string& path, |
| 347 const AuthCredentials& credentials, | 349 const AuthCredentials& credentials, |
| 348 const std::string& cnonce, | 350 const std::string& cnonce, |
| 349 int nonce_count) const { | 351 int nonce_count) const { |
| 350 // the nonce-count is an 8 digit hex string. | 352 // the nonce-count is an 8 digit hex string. |
| 351 std::string nc = base::StringPrintf("%08x", nonce_count); | 353 std::string nc = base::StringPrintf("%08x", nonce_count); |
| 352 | 354 |
| 353 // TODO(eroman): is this the right encoding? | 355 // TODO(eroman): is this the right encoding? |
| 354 std::string authorization = (std::string("Digest username=") + | 356 std::string authorization = |
| 355 HttpUtil::Quote( | 357 (std::string("Digest username=") + |
| 356 base::UTF16ToUTF8(credentials.username()))); | 358 HttpUtil::Quote(base::UTF16ToUTF8(credentials.username()))); |
| 357 authorization += ", realm=" + HttpUtil::Quote(original_realm_); | 359 authorization += ", realm=" + HttpUtil::Quote(original_realm_); |
| 358 authorization += ", nonce=" + HttpUtil::Quote(nonce_); | 360 authorization += ", nonce=" + HttpUtil::Quote(nonce_); |
| 359 authorization += ", uri=" + HttpUtil::Quote(path); | 361 authorization += ", uri=" + HttpUtil::Quote(path); |
| 360 | 362 |
| 361 if (algorithm_ != ALGORITHM_UNSPECIFIED) { | 363 if (algorithm_ != ALGORITHM_UNSPECIFIED) { |
| 362 authorization += ", algorithm=" + AlgorithmToString(algorithm_); | 364 authorization += ", algorithm=" + AlgorithmToString(algorithm_); |
| 363 } | 365 } |
| 364 std::string response = AssembleResponseDigest(method, path, credentials, | 366 std::string response = |
| 365 cnonce, nc); | 367 AssembleResponseDigest(method, path, credentials, cnonce, nc); |
| 366 // No need to call HttpUtil::Quote() as the response digest cannot contain | 368 // No need to call HttpUtil::Quote() as the response digest cannot contain |
| 367 // any characters needing to be escaped. | 369 // any characters needing to be escaped. |
| 368 authorization += ", response=\"" + response + "\""; | 370 authorization += ", response=\"" + response + "\""; |
| 369 | 371 |
| 370 if (!opaque_.empty()) { | 372 if (!opaque_.empty()) { |
| 371 authorization += ", opaque=" + HttpUtil::Quote(opaque_); | 373 authorization += ", opaque=" + HttpUtil::Quote(opaque_); |
| 372 } | 374 } |
| 373 if (qop_ != QOP_UNSPECIFIED) { | 375 if (qop_ != QOP_UNSPECIFIED) { |
| 374 // TODO(eroman): Supposedly IIS server requires quotes surrounding qop. | 376 // TODO(eroman): Supposedly IIS server requires quotes surrounding qop. |
| 375 authorization += ", qop=" + QopToString(qop_); | 377 authorization += ", qop=" + QopToString(qop_); |
| 376 authorization += ", nc=" + nc; | 378 authorization += ", nc=" + nc; |
| 377 authorization += ", cnonce=" + HttpUtil::Quote(cnonce); | 379 authorization += ", cnonce=" + HttpUtil::Quote(cnonce); |
| 378 } | 380 } |
| 379 | 381 |
| 380 return authorization; | 382 return authorization; |
| 381 } | 383 } |
| 382 | 384 |
| 383 } // namespace net | 385 } // namespace net |
| OLD | NEW |