| OLD | NEW |
| 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> | 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" |
| 11 #include "base/rand_util.h" | 11 #include "base/rand_util.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 16 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
| 17 #include "net/http/http_auth.h" | 17 #include "net/http/http_auth.h" |
| 18 #include "net/http/http_request_info.h" | 18 #include "net/http/http_request_info.h" |
| 19 #include "net/http/http_util.h" | 19 #include "net/http/http_util.h" |
| 20 | 20 |
| 21 // TODO(eroman): support qop=auth-int | |
| 22 | |
| 23 namespace net { | 21 namespace net { |
| 24 | 22 |
| 25 // Digest authentication is specified in RFC 2617. | 23 // Digest authentication is specified in RFC 2617. |
| 26 // The expanded derivations are listed in the tables below. | 24 // The expanded derivations are listed in the tables below. |
| 27 | 25 |
| 28 //==========+==========+==========================================+ | 26 //==========+==========+==========================================+ |
| 29 // qop |algorithm | response | | 27 // qop |algorithm | response | |
| 30 //==========+==========+==========================================+ | 28 //==========+==========+==========================================+ |
| 31 // ? | ?, md5, | MD5(MD5(A1):nonce:MD5(A2)) | | 29 // ? | ?, md5, | MD5(MD5(A1):nonce:MD5(A2)) | |
| 32 // | md5-sess | | | 30 // | md5-sess | | |
| (...skipping 25 matching lines...) Expand all Loading... |
| 58 if (fixed_cnonce_) | 56 if (fixed_cnonce_) |
| 59 return std::string(domain); | 57 return std::string(domain); |
| 60 std::string cnonce; | 58 std::string cnonce; |
| 61 cnonce.reserve(16); | 59 cnonce.reserve(16); |
| 62 for (int i = 0; i < 16; ++i) | 60 for (int i = 0; i < 16; ++i) |
| 63 cnonce.push_back(domain[base::RandInt(0, 15)]); | 61 cnonce.push_back(domain[base::RandInt(0, 15)]); |
| 64 return cnonce; | 62 return cnonce; |
| 65 } | 63 } |
| 66 | 64 |
| 67 // static | 65 // static |
| 68 std::string HttpAuthHandlerDigest::QopToString(int qop) { | 66 std::string HttpAuthHandlerDigest::QopToString(QualityOfProtection qop) { |
| 69 switch (qop) { | 67 switch (qop) { |
| 68 case QOP_UNSPECIFIED: |
| 69 return ""; |
| 70 case QOP_AUTH: | 70 case QOP_AUTH: |
| 71 return "auth"; | 71 return "auth"; |
| 72 case QOP_AUTH_INT: | |
| 73 return "auth-int"; | |
| 74 default: | 72 default: |
| 73 NOTREACHED(); |
| 75 return ""; | 74 return ""; |
| 76 } | 75 } |
| 77 } | 76 } |
| 78 | 77 |
| 79 // static | 78 // static |
| 80 std::string HttpAuthHandlerDigest::AlgorithmToString(int algorithm) { | 79 std::string HttpAuthHandlerDigest::AlgorithmToString( |
| 80 DigestAlgorithm algorithm) { |
| 81 switch (algorithm) { | 81 switch (algorithm) { |
| 82 case ALGORITHM_UNSPECIFIED: |
| 83 return ""; |
| 82 case ALGORITHM_MD5: | 84 case ALGORITHM_MD5: |
| 83 return "MD5"; | 85 return "MD5"; |
| 84 case ALGORITHM_MD5_SESS: | 86 case ALGORITHM_MD5_SESS: |
| 85 return "MD5-sess"; | 87 return "MD5-sess"; |
| 86 default: | 88 default: |
| 89 NOTREACHED(); |
| 87 return ""; | 90 return ""; |
| 88 } | 91 } |
| 89 } | 92 } |
| 90 | 93 |
| 91 HttpAuthHandlerDigest::HttpAuthHandlerDigest(int nonce_count) | 94 HttpAuthHandlerDigest::HttpAuthHandlerDigest(int nonce_count) |
| 92 : stale_(false), | 95 : stale_(false), |
| 93 algorithm_(ALGORITHM_UNSPECIFIED), | 96 algorithm_(ALGORITHM_UNSPECIFIED), |
| 94 qop_(0), | 97 qop_(QOP_UNSPECIFIED), |
| 95 nonce_count_(nonce_count) { | 98 nonce_count_(nonce_count) { |
| 96 } | 99 } |
| 97 | 100 |
| 98 HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { | 101 HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { |
| 99 } | 102 } |
| 100 | 103 |
| 101 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( | 104 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( |
| 102 const string16* username, | 105 const string16* username, |
| 103 const string16* password, | 106 const string16* password, |
| 104 const HttpRequestInfo* request, | 107 const HttpRequestInfo* request, |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 if (LowerCaseEqualsASCII(value, "md5")) { | 304 if (LowerCaseEqualsASCII(value, "md5")) { |
| 302 algorithm_ = ALGORITHM_MD5; | 305 algorithm_ = ALGORITHM_MD5; |
| 303 } else if (LowerCaseEqualsASCII(value, "md5-sess")) { | 306 } else if (LowerCaseEqualsASCII(value, "md5-sess")) { |
| 304 algorithm_ = ALGORITHM_MD5_SESS; | 307 algorithm_ = ALGORITHM_MD5_SESS; |
| 305 } else { | 308 } else { |
| 306 DVLOG(1) << "Unknown value of algorithm"; | 309 DVLOG(1) << "Unknown value of algorithm"; |
| 307 return false; // FAIL -- unsupported value of algorithm. | 310 return false; // FAIL -- unsupported value of algorithm. |
| 308 } | 311 } |
| 309 } else if (LowerCaseEqualsASCII(name, "qop")) { | 312 } else if (LowerCaseEqualsASCII(name, "qop")) { |
| 310 // Parse the comma separated list of qops. | 313 // Parse the comma separated list of qops. |
| 314 // auth is the only supported qop, and all other values are ignored. |
| 311 HttpUtil::ValuesIterator qop_values(value.begin(), value.end(), ','); | 315 HttpUtil::ValuesIterator qop_values(value.begin(), value.end(), ','); |
| 316 qop_ = QOP_UNSPECIFIED; |
| 312 while (qop_values.GetNext()) { | 317 while (qop_values.GetNext()) { |
| 313 if (LowerCaseEqualsASCII(qop_values.value(), "auth")) { | 318 if (LowerCaseEqualsASCII(qop_values.value(), "auth")) { |
| 314 qop_ |= QOP_AUTH; | 319 qop_ = QOP_AUTH; |
| 315 } else if (LowerCaseEqualsASCII(qop_values.value(), "auth-int")) { | 320 break; |
| 316 qop_ |= QOP_AUTH_INT; | |
| 317 } | 321 } |
| 318 } | 322 } |
| 319 } else { | 323 } else { |
| 320 DVLOG(1) << "Skipping unrecognized digest property"; | 324 DVLOG(1) << "Skipping unrecognized digest property"; |
| 321 // TODO(eroman): perhaps we should fail instead of silently skipping? | 325 // TODO(eroman): perhaps we should fail instead of silently skipping? |
| 322 } | 326 } |
| 323 return true; | 327 return true; |
| 324 } | 328 } |
| 325 | 329 |
| 326 HttpAuthHandlerDigest::Factory::Factory() { | 330 HttpAuthHandlerDigest::Factory::Factory() { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 341 // method and only constructing when valid. | 345 // method and only constructing when valid. |
| 342 scoped_ptr<HttpAuthHandler> tmp_handler( | 346 scoped_ptr<HttpAuthHandler> tmp_handler( |
| 343 new HttpAuthHandlerDigest(digest_nonce_count)); | 347 new HttpAuthHandlerDigest(digest_nonce_count)); |
| 344 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 348 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
| 345 return ERR_INVALID_RESPONSE; | 349 return ERR_INVALID_RESPONSE; |
| 346 handler->swap(tmp_handler); | 350 handler->swap(tmp_handler); |
| 347 return OK; | 351 return OK; |
| 348 } | 352 } |
| 349 | 353 |
| 350 } // namespace net | 354 } // namespace net |
| OLD | NEW |