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 |