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 |