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...) 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...) 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 |