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