| 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" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 // | md5-sess | MD5(user:realm:password):nonce:cnonce | | 39 // | md5-sess | MD5(user:realm:password):nonce:cnonce | |
| 40 //==========+==========+==========================================+ | 40 //==========+==========+==========================================+ |
| 41 // qop |algorithm | A2 | | 41 // qop |algorithm | A2 | |
| 42 //==========+==========+==========================================+ | 42 //==========+==========+==========================================+ |
| 43 // ?, auth | | req-method:req-uri | | 43 // ?, auth | | req-method:req-uri | |
| 44 //----------+----------+------------------------------------------+ | 44 //----------+----------+------------------------------------------+ |
| 45 // auth-int | | req-method:req-uri:MD5(req-entity-body) | | 45 // auth-int | | req-method:req-uri:MD5(req-entity-body) | |
| 46 //=====================+==========================================+ | 46 //=====================+==========================================+ |
| 47 | 47 |
| 48 | 48 |
| 49 //static | 49 HttpAuthHandlerDigest::NonceGenerator::~NonceGenerator() { |
| 50 bool HttpAuthHandlerDigest::fixed_cnonce_ = false; | 50 } |
| 51 | 51 |
| 52 // static | 52 std::string HttpAuthHandlerDigest::DynamicNonceGenerator::GenerateNonce() |
| 53 std::string HttpAuthHandlerDigest::GenerateNonce() { | 53 const { |
| 54 // This is how mozilla generates their cnonce -- a 16 digit hex string. | 54 // This is how mozilla generates their cnonce -- a 16 digit hex string. |
| 55 static const char domain[] = "0123456789abcdef"; | 55 static const char domain[] = "0123456789abcdef"; |
| 56 if (fixed_cnonce_) | |
| 57 return std::string(domain); | |
| 58 std::string cnonce; | 56 std::string cnonce; |
| 59 cnonce.reserve(16); | 57 cnonce.reserve(16); |
| 60 for (int i = 0; i < 16; ++i) | 58 for (int i = 0; i < 16; ++i) |
| 61 cnonce.push_back(domain[base::RandInt(0, 15)]); | 59 cnonce.push_back(domain[base::RandInt(0, 15)]); |
| 62 return cnonce; | 60 return cnonce; |
| 63 } | 61 } |
| 64 | 62 |
| 63 HttpAuthHandlerDigest::FixedNonceGenerator::FixedNonceGenerator( |
| 64 const std::string& nonce) |
| 65 : nonce_(nonce) { |
| 66 } |
| 67 |
| 68 std::string HttpAuthHandlerDigest::FixedNonceGenerator::GenerateNonce() const { |
| 69 return nonce_; |
| 70 } |
| 71 |
| 65 // static | 72 // static |
| 66 std::string HttpAuthHandlerDigest::QopToString(QualityOfProtection qop) { | 73 std::string HttpAuthHandlerDigest::QopToString(QualityOfProtection qop) { |
| 67 switch (qop) { | 74 switch (qop) { |
| 68 case QOP_UNSPECIFIED: | 75 case QOP_UNSPECIFIED: |
| 69 return ""; | 76 return ""; |
| 70 case QOP_AUTH: | 77 case QOP_AUTH: |
| 71 return "auth"; | 78 return "auth"; |
| 72 default: | 79 default: |
| 73 NOTREACHED(); | 80 NOTREACHED(); |
| 74 return ""; | 81 return ""; |
| 75 } | 82 } |
| 76 } | 83 } |
| 77 | 84 |
| 78 // static | 85 // static |
| 79 std::string HttpAuthHandlerDigest::AlgorithmToString( | 86 std::string HttpAuthHandlerDigest::AlgorithmToString( |
| 80 DigestAlgorithm algorithm) { | 87 DigestAlgorithm algorithm) { |
| 81 switch (algorithm) { | 88 switch (algorithm) { |
| 82 case ALGORITHM_UNSPECIFIED: | 89 case ALGORITHM_UNSPECIFIED: |
| 83 return ""; | 90 return ""; |
| 84 case ALGORITHM_MD5: | 91 case ALGORITHM_MD5: |
| 85 return "MD5"; | 92 return "MD5"; |
| 86 case ALGORITHM_MD5_SESS: | 93 case ALGORITHM_MD5_SESS: |
| 87 return "MD5-sess"; | 94 return "MD5-sess"; |
| 88 default: | 95 default: |
| 89 NOTREACHED(); | 96 NOTREACHED(); |
| 90 return ""; | 97 return ""; |
| 91 } | 98 } |
| 92 } | 99 } |
| 93 | 100 |
| 94 HttpAuthHandlerDigest::HttpAuthHandlerDigest(int nonce_count) | 101 HttpAuthHandlerDigest::HttpAuthHandlerDigest( |
| 102 int nonce_count, const NonceGenerator* nonce_generator) |
| 95 : stale_(false), | 103 : stale_(false), |
| 96 algorithm_(ALGORITHM_UNSPECIFIED), | 104 algorithm_(ALGORITHM_UNSPECIFIED), |
| 97 qop_(QOP_UNSPECIFIED), | 105 qop_(QOP_UNSPECIFIED), |
| 98 nonce_count_(nonce_count) { | 106 nonce_count_(nonce_count), |
| 107 nonce_generator_(nonce_generator) { |
| 108 DCHECK(nonce_generator_); |
| 99 } | 109 } |
| 100 | 110 |
| 101 HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { | 111 HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { |
| 102 } | 112 } |
| 103 | 113 |
| 104 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( | 114 int HttpAuthHandlerDigest::GenerateAuthTokenImpl( |
| 105 const string16* username, | 115 const string16* username, |
| 106 const string16* password, | 116 const string16* password, |
| 107 const HttpRequestInfo* request, | 117 const HttpRequestInfo* request, |
| 108 CompletionCallback* callback, | 118 CompletionCallback* callback, |
| 109 std::string* auth_token) { | 119 std::string* auth_token) { |
| 110 // Generate a random client nonce. | 120 // Generate a random client nonce. |
| 111 std::string cnonce = GenerateNonce(); | 121 std::string cnonce = nonce_generator_->GenerateNonce(); |
| 112 | 122 |
| 113 // Extract the request method and path -- the meaning of 'path' is overloaded | 123 // Extract the request method and path -- the meaning of 'path' is overloaded |
| 114 // in certain cases, to be a hostname. | 124 // in certain cases, to be a hostname. |
| 115 std::string method; | 125 std::string method; |
| 116 std::string path; | 126 std::string path; |
| 117 GetRequestMethodAndPath(request, &method, &path); | 127 GetRequestMethodAndPath(request, &method, &path); |
| 118 | 128 |
| 119 *auth_token = AssembleCredentials(method, path, | 129 *auth_token = AssembleCredentials(method, path, |
| 120 *username, | 130 *username, |
| 121 *password, | 131 *password, |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 break; | 330 break; |
| 321 } | 331 } |
| 322 } | 332 } |
| 323 } else { | 333 } else { |
| 324 DVLOG(1) << "Skipping unrecognized digest property"; | 334 DVLOG(1) << "Skipping unrecognized digest property"; |
| 325 // TODO(eroman): perhaps we should fail instead of silently skipping? | 335 // TODO(eroman): perhaps we should fail instead of silently skipping? |
| 326 } | 336 } |
| 327 return true; | 337 return true; |
| 328 } | 338 } |
| 329 | 339 |
| 330 HttpAuthHandlerDigest::Factory::Factory() { | 340 HttpAuthHandlerDigest::Factory::Factory() |
| 341 : nonce_generator_(new DynamicNonceGenerator()) { |
| 331 } | 342 } |
| 332 | 343 |
| 333 HttpAuthHandlerDigest::Factory::~Factory() { | 344 HttpAuthHandlerDigest::Factory::~Factory() { |
| 334 } | 345 } |
| 335 | 346 |
| 347 void HttpAuthHandlerDigest::Factory::set_nonce_generator( |
| 348 const NonceGenerator* nonce_generator) { |
| 349 nonce_generator_.reset(nonce_generator); |
| 350 } |
| 351 |
| 336 int HttpAuthHandlerDigest::Factory::CreateAuthHandler( | 352 int HttpAuthHandlerDigest::Factory::CreateAuthHandler( |
| 337 HttpAuth::ChallengeTokenizer* challenge, | 353 HttpAuth::ChallengeTokenizer* challenge, |
| 338 HttpAuth::Target target, | 354 HttpAuth::Target target, |
| 339 const GURL& origin, | 355 const GURL& origin, |
| 340 CreateReason reason, | 356 CreateReason reason, |
| 341 int digest_nonce_count, | 357 int digest_nonce_count, |
| 342 const BoundNetLog& net_log, | 358 const BoundNetLog& net_log, |
| 343 scoped_ptr<HttpAuthHandler>* handler) { | 359 scoped_ptr<HttpAuthHandler>* handler) { |
| 344 // TODO(cbentzel): Move towards model of parsing in the factory | 360 // TODO(cbentzel): Move towards model of parsing in the factory |
| 345 // method and only constructing when valid. | 361 // method and only constructing when valid. |
| 346 scoped_ptr<HttpAuthHandler> tmp_handler( | 362 scoped_ptr<HttpAuthHandler> tmp_handler( |
| 347 new HttpAuthHandlerDigest(digest_nonce_count)); | 363 new HttpAuthHandlerDigest(digest_nonce_count, nonce_generator_.get())); |
| 348 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 364 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
| 349 return ERR_INVALID_RESPONSE; | 365 return ERR_INVALID_RESPONSE; |
| 350 handler->swap(tmp_handler); | 366 handler->swap(tmp_handler); |
| 351 return OK; | 367 return OK; |
| 352 } | 368 } |
| 353 | 369 |
| 354 } // namespace net | 370 } // namespace net |
| OLD | NEW |