| 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/i18n/icu_string_conversions.h" | 9 #include "base/i18n/icu_string_conversions.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 return (original_realm_ != original_realm) ? | 130 return (original_realm_ != original_realm) ? |
| 131 HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM : | 131 HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM : |
| 132 HttpAuth::AUTHORIZATION_RESULT_REJECT; | 132 HttpAuth::AUTHORIZATION_RESULT_REJECT; |
| 133 } | 133 } |
| 134 | 134 |
| 135 bool HttpAuthHandlerDigest::Init(HttpAuth::ChallengeTokenizer* challenge) { | 135 bool HttpAuthHandlerDigest::Init(HttpAuth::ChallengeTokenizer* challenge) { |
| 136 return ParseChallenge(challenge); | 136 return ParseChallenge(challenge); |
| 137 } | 137 } |
| 138 | 138 |
| 139 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( | 139 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( |
| 140 const string16* username, | 140 const AuthCredentials* credentials, |
| 141 const string16* password, | |
| 142 const HttpRequestInfo* request, | 141 const HttpRequestInfo* request, |
| 143 OldCompletionCallback* callback, | 142 OldCompletionCallback* callback, |
| 144 std::string* auth_token) { | 143 std::string* auth_token) { |
| 145 // Generate a random client nonce. | 144 // Generate a random client nonce. |
| 146 std::string cnonce = nonce_generator_->GenerateNonce(); | 145 std::string cnonce = nonce_generator_->GenerateNonce(); |
| 147 | 146 |
| 148 // Extract the request method and path -- the meaning of 'path' is overloaded | 147 // Extract the request method and path -- the meaning of 'path' is overloaded |
| 149 // in certain cases, to be a hostname. | 148 // in certain cases, to be a hostname. |
| 150 std::string method; | 149 std::string method; |
| 151 std::string path; | 150 std::string path; |
| 152 GetRequestMethodAndPath(request, &method, &path); | 151 GetRequestMethodAndPath(request, &method, &path); |
| 153 | 152 |
| 154 *auth_token = AssembleCredentials(method, path, | 153 *auth_token = AssembleCredentials(method, path, *credentials, |
| 155 *username, | |
| 156 *password, | |
| 157 cnonce, nonce_count_); | 154 cnonce, nonce_count_); |
| 158 return OK; | 155 return OK; |
| 159 } | 156 } |
| 160 | 157 |
| 161 HttpAuthHandlerDigest::HttpAuthHandlerDigest( | 158 HttpAuthHandlerDigest::HttpAuthHandlerDigest( |
| 162 int nonce_count, const NonceGenerator* nonce_generator) | 159 int nonce_count, const NonceGenerator* nonce_generator) |
| 163 : stale_(false), | 160 : stale_(false), |
| 164 algorithm_(ALGORITHM_UNSPECIFIED), | 161 algorithm_(ALGORITHM_UNSPECIFIED), |
| 165 qop_(QOP_UNSPECIFIED), | 162 qop_(QOP_UNSPECIFIED), |
| 166 nonce_count_(nonce_count), | 163 nonce_count_(nonce_count), |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 *path = GetHostAndPort(url); | 310 *path = GetHostAndPort(url); |
| 314 } else { | 311 } else { |
| 315 *method = request->method; | 312 *method = request->method; |
| 316 *path = HttpUtil::PathForRequest(url); | 313 *path = HttpUtil::PathForRequest(url); |
| 317 } | 314 } |
| 318 } | 315 } |
| 319 | 316 |
| 320 std::string HttpAuthHandlerDigest::AssembleResponseDigest( | 317 std::string HttpAuthHandlerDigest::AssembleResponseDigest( |
| 321 const std::string& method, | 318 const std::string& method, |
| 322 const std::string& path, | 319 const std::string& path, |
| 323 const string16& username, | 320 const AuthCredentials& credentials, |
| 324 const string16& password, | |
| 325 const std::string& cnonce, | 321 const std::string& cnonce, |
| 326 const std::string& nc) const { | 322 const std::string& nc) const { |
| 327 // ha1 = MD5(A1) | 323 // ha1 = MD5(A1) |
| 328 // TODO(eroman): is this the right encoding? | 324 // TODO(eroman): is this the right encoding? |
| 329 std::string ha1 = base::MD5String(UTF16ToUTF8(username) + ":" + | 325 std::string ha1 = base::MD5String(UTF16ToUTF8(credentials.username()) + ":" + |
| 330 original_realm_ + ":" + | 326 original_realm_ + ":" + |
| 331 UTF16ToUTF8(password)); | 327 UTF16ToUTF8(credentials.password())); |
| 332 if (algorithm_ == HttpAuthHandlerDigest::ALGORITHM_MD5_SESS) | 328 if (algorithm_ == HttpAuthHandlerDigest::ALGORITHM_MD5_SESS) |
| 333 ha1 = base::MD5String(ha1 + ":" + nonce_ + ":" + cnonce); | 329 ha1 = base::MD5String(ha1 + ":" + nonce_ + ":" + cnonce); |
| 334 | 330 |
| 335 // ha2 = MD5(A2) | 331 // ha2 = MD5(A2) |
| 336 // TODO(eroman): need to add MD5(req-entity-body) for qop=auth-int. | 332 // TODO(eroman): need to add MD5(req-entity-body) for qop=auth-int. |
| 337 std::string ha2 = base::MD5String(method + ":" + path); | 333 std::string ha2 = base::MD5String(method + ":" + path); |
| 338 | 334 |
| 339 std::string nc_part; | 335 std::string nc_part; |
| 340 if (qop_ != HttpAuthHandlerDigest::QOP_UNSPECIFIED) { | 336 if (qop_ != HttpAuthHandlerDigest::QOP_UNSPECIFIED) { |
| 341 nc_part = nc + ":" + cnonce + ":" + QopToString(qop_) + ":"; | 337 nc_part = nc + ":" + cnonce + ":" + QopToString(qop_) + ":"; |
| 342 } | 338 } |
| 343 | 339 |
| 344 return base::MD5String(ha1 + ":" + nonce_ + ":" + nc_part + ha2); | 340 return base::MD5String(ha1 + ":" + nonce_ + ":" + nc_part + ha2); |
| 345 } | 341 } |
| 346 | 342 |
| 347 std::string HttpAuthHandlerDigest::AssembleCredentials( | 343 std::string HttpAuthHandlerDigest::AssembleCredentials( |
| 348 const std::string& method, | 344 const std::string& method, |
| 349 const std::string& path, | 345 const std::string& path, |
| 350 const string16& username, | 346 const AuthCredentials& credentials, |
| 351 const string16& password, | |
| 352 const std::string& cnonce, | 347 const std::string& cnonce, |
| 353 int nonce_count) const { | 348 int nonce_count) const { |
| 354 // the nonce-count is an 8 digit hex string. | 349 // the nonce-count is an 8 digit hex string. |
| 355 std::string nc = base::StringPrintf("%08x", nonce_count); | 350 std::string nc = base::StringPrintf("%08x", nonce_count); |
| 356 | 351 |
| 357 // TODO(eroman): is this the right encoding? | 352 // TODO(eroman): is this the right encoding? |
| 358 std::string authorization = (std::string("Digest username=") + | 353 std::string authorization = (std::string("Digest username=") + |
| 359 HttpUtil::Quote(UTF16ToUTF8(username))); | 354 HttpUtil::Quote( |
| 355 UTF16ToUTF8(credentials.username()))); |
| 360 authorization += ", realm=" + HttpUtil::Quote(original_realm_); | 356 authorization += ", realm=" + HttpUtil::Quote(original_realm_); |
| 361 authorization += ", nonce=" + HttpUtil::Quote(nonce_); | 357 authorization += ", nonce=" + HttpUtil::Quote(nonce_); |
| 362 authorization += ", uri=" + HttpUtil::Quote(path); | 358 authorization += ", uri=" + HttpUtil::Quote(path); |
| 363 | 359 |
| 364 if (algorithm_ != ALGORITHM_UNSPECIFIED) { | 360 if (algorithm_ != ALGORITHM_UNSPECIFIED) { |
| 365 authorization += ", algorithm=" + AlgorithmToString(algorithm_); | 361 authorization += ", algorithm=" + AlgorithmToString(algorithm_); |
| 366 } | 362 } |
| 367 std::string response = AssembleResponseDigest(method, path, username, | 363 std::string response = AssembleResponseDigest(method, path, credentials, |
| 368 password, cnonce, nc); | 364 cnonce, nc); |
| 369 // No need to call HttpUtil::Quote() as the response digest cannot contain | 365 // No need to call HttpUtil::Quote() as the response digest cannot contain |
| 370 // any characters needing to be escaped. | 366 // any characters needing to be escaped. |
| 371 authorization += ", response=\"" + response + "\""; | 367 authorization += ", response=\"" + response + "\""; |
| 372 | 368 |
| 373 if (!opaque_.empty()) { | 369 if (!opaque_.empty()) { |
| 374 authorization += ", opaque=" + HttpUtil::Quote(opaque_); | 370 authorization += ", opaque=" + HttpUtil::Quote(opaque_); |
| 375 } | 371 } |
| 376 if (qop_ != QOP_UNSPECIFIED) { | 372 if (qop_ != QOP_UNSPECIFIED) { |
| 377 // TODO(eroman): Supposedly IIS server requires quotes surrounding qop. | 373 // TODO(eroman): Supposedly IIS server requires quotes surrounding qop. |
| 378 authorization += ", qop=" + QopToString(qop_); | 374 authorization += ", qop=" + QopToString(qop_); |
| 379 authorization += ", nc=" + nc; | 375 authorization += ", nc=" + nc; |
| 380 authorization += ", cnonce=" + HttpUtil::Quote(cnonce); | 376 authorization += ", cnonce=" + HttpUtil::Quote(cnonce); |
| 381 } | 377 } |
| 382 | 378 |
| 383 return authorization; | 379 return authorization; |
| 384 } | 380 } |
| 385 | 381 |
| 386 } // namespace net | 382 } // namespace net |
| OLD | NEW |