Chromium Code Reviews| 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 bool parsed_success; | 21 bool parsed_success; |
| 22 // The expected values that were parsed. | 22 // The expected values that were parsed. |
| 23 const char* parsed_realm; | 23 const char* parsed_realm; |
| 24 const char* parsed_nonce; | 24 const char* parsed_nonce; |
| 25 const char* parsed_domain; | 25 const char* parsed_domain; |
| 26 const char* parsed_opaque; | 26 const char* parsed_opaque; |
| 27 bool parsed_stale; | 27 bool parsed_stale; |
| 28 int parsed_algorithm; | 28 int parsed_algorithm; |
| 29 int parsed_qop; | 29 int parsed_qop; |
| 30 } tests[] = { | 30 } tests[] = { |
| 31 { | 31 { // Check that a minimal challenge works correctly. |
| 32 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\"", | 32 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\"", |
| 33 true, | 33 true, |
| 34 "Thunder Bluff", | 34 "Thunder Bluff", |
| 35 "xyz", | 35 "xyz", |
| 36 "", | 36 "", |
| 37 "", | 37 "", |
| 38 false, | 38 false, |
| 39 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | 39 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 40 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 40 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 41 }, | 41 }, |
| 42 | 42 |
| 43 { // Realm does not need to be quoted, even though RFC2617 requires it. | |
| 44 "Digest nonce=\"xyz\", realm=ThunderBluff", | |
|
eroman
2010/11/11 23:02:58
... I must have been playing WoW when I initially
| |
| 45 true, | |
| 46 "ThunderBluff", | |
| 47 "xyz", | |
| 48 "", | |
| 49 "", | |
| 50 false, | |
| 51 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 52 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 53 }, | |
| 54 | |
| 55 { // We allow the realm to be omitted, and will default it to empty string. | |
| 56 // See http://crbug.com/20984. | |
| 57 "Digest nonce=\"xyz\"", | |
| 58 true, | |
| 59 "", | |
| 60 "xyz", | |
| 61 "", | |
| 62 "", | |
| 63 false, | |
| 64 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 65 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 66 }, | |
| 67 | |
| 68 { // Try with realm set to empty string. | |
| 69 "Digest realm=\"\", nonce=\"xyz\"", | |
| 70 true, | |
| 71 "", | |
| 72 "xyz", | |
| 73 "", | |
| 74 "", | |
| 75 false, | |
| 76 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 77 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 78 }, | |
| 79 | |
| 80 { // At a minimum, a nonce must be provided. | |
| 81 "Digest realm=\"Thunder Bluff\"", | |
| 82 false, | |
| 83 "", | |
| 84 "", | |
| 85 "", | |
| 86 "", | |
| 87 false, | |
| 88 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 89 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 90 }, | |
| 91 | |
| 92 { // The nonce does not need to be quoted, even though RFC2617 | |
| 93 // requires it. | |
| 94 "Digest nonce=xyz, realm=\"Thunder Bluff\"", | |
| 95 true, | |
| 96 "Thunder Bluff", | |
| 97 "xyz", | |
| 98 "", | |
| 99 "", | |
| 100 false, | |
| 101 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 102 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 103 }, | |
| 104 | |
| 105 { // Unknown authentication parameters are ignored. | |
| 106 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", foo=\"bar\"", | |
| 107 true, | |
| 108 "Thunder Bluff", | |
| 109 "xyz", | |
| 110 "", | |
| 111 "", | |
| 112 false, | |
| 113 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 114 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 115 }, | |
| 116 | |
| 43 { // Check that when algorithm has an unsupported value, parsing fails. | 117 { // Check that when algorithm has an unsupported value, parsing fails. |
| 44 "Digest nonce=\"xyz\", algorithm=\"awezum\", realm=\"Thunder\"", | 118 "Digest nonce=\"xyz\", algorithm=\"awezum\", realm=\"Thunder\"", |
| 45 false, | 119 false, |
| 46 // The remaining values don't matter (but some have been set already). | 120 // The remaining values don't matter (but some have been set already). |
| 47 "", | 121 "", |
| 48 "xyz", | 122 "xyz", |
| 49 "", | 123 "", |
| 50 "", | 124 "", |
| 51 false, | 125 false, |
| 52 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | 126 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 53 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 127 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 54 }, | 128 }, |
| 55 | 129 |
| 56 { // Check that algorithm's value is case insensitive. | 130 { // Check that algorithm's value is case insensitive, and that MD5 is |
| 131 // a supported algorithm. | |
| 57 "Digest nonce=\"xyz\", algorithm=\"mD5\", realm=\"Oblivion\"", | 132 "Digest nonce=\"xyz\", algorithm=\"mD5\", realm=\"Oblivion\"", |
| 58 true, | 133 true, |
| 59 "Oblivion", | 134 "Oblivion", |
| 60 "xyz", | 135 "xyz", |
| 61 "", | 136 "", |
| 62 "", | 137 "", |
| 63 false, | 138 false, |
| 64 HttpAuthHandlerDigest::ALGORITHM_MD5, | 139 HttpAuthHandlerDigest::ALGORITHM_MD5, |
| 65 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 140 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 66 }, | 141 }, |
| 67 | 142 |
| 68 { // Check that md5-sess is recognized, as is single QOP | 143 { // Check that md5-sess is a supported algorithm. |
| 69 "Digest nonce=\"xyz\", algorithm=\"md5-sess\", " | 144 "Digest nonce=\"xyz\", algorithm=\"md5-sess\", realm=\"Oblivion\"", |
| 70 "realm=\"Oblivion\", qop=\"auth\"", | |
| 71 true, | 145 true, |
| 72 "Oblivion", | 146 "Oblivion", |
| 73 "xyz", | 147 "xyz", |
| 74 "", | 148 "", |
| 75 "", | 149 "", |
| 76 false, | 150 false, |
| 77 HttpAuthHandlerDigest::ALGORITHM_MD5_SESS, | 151 HttpAuthHandlerDigest::ALGORITHM_MD5_SESS, |
| 152 HttpAuthHandlerDigest::QOP_UNSPECIFIED, | |
| 153 }, | |
| 154 | |
| 155 { // Check that qop's value is case insensitive, and that auth is known. | |
| 156 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"aUth\"", | |
| 157 true, | |
| 158 "Oblivion", | |
| 159 "xyz", | |
| 160 "", | |
| 161 "", | |
| 162 false, | |
| 163 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 78 HttpAuthHandlerDigest::QOP_AUTH | 164 HttpAuthHandlerDigest::QOP_AUTH |
| 79 }, | 165 }, |
| 80 | 166 |
| 81 { // We allow the realm to be omitted, and will default it to empty string. | 167 { // Check that a qop value of auth-int results in no handler, |
| 82 // See http://crbug.com/20984. | 168 // since Chrome's digest handler currently does not handle |
| 83 "Digest nonce=\"xyz\"", | 169 // auth-int correctly. |
| 84 true, | 170 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth-int\"", |
| 171 false, | |
| 85 "", | 172 "", |
| 86 "xyz", | 173 "", |
| 87 "", | 174 "", |
| 88 "", | 175 "", |
| 89 false, | 176 false, |
| 90 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | 177 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 91 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 178 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 92 }, | 179 }, |
| 93 | 180 |
| 94 { // Try with realm set to empty string. | 181 { // Unknown qop values are ignored. |
| 95 "Digest realm=\"\", nonce=\"xyz\"", | 182 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,foo\"", |
| 96 true, | 183 true, |
| 97 "", | 184 "Oblivion", |
| 98 "xyz", | 185 "xyz", |
| 99 "", | 186 "", |
| 100 "", | 187 "", |
| 101 false, | 188 false, |
| 102 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | 189 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 190 HttpAuthHandlerDigest::QOP_AUTH | |
| 191 }, | |
| 192 | |
| 193 { // If auth-int is included with auth, then use auth. | |
| 194 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,auth-int\"", | |
| 195 true, | |
| 196 "Oblivion", | |
| 197 "xyz", | |
| 198 "", | |
| 199 "", | |
| 200 false, | |
| 201 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 202 HttpAuthHandlerDigest::QOP_AUTH | |
| 203 }, | |
| 204 | |
| 205 { // Opaque parameter parsing should work correctly. | |
| 206 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=\"foobar\"", | |
| 207 true, | |
| 208 "Thunder Bluff", | |
| 209 "xyz", | |
| 210 "", | |
| 211 "foobar", | |
| 212 false, | |
| 213 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 103 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 214 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 104 } | 215 }, |
| 216 | |
| 217 { // Opaque parameters do not need to be quoted, even though RFC2617 | |
| 218 // seems to require it. | |
| 219 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=foobar", | |
| 220 true, | |
| 221 "Thunder Bluff", | |
| 222 "xyz", | |
| 223 "", | |
| 224 "foobar", | |
| 225 false, | |
| 226 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 227 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 228 }, | |
| 229 | |
| 230 { // Domain can be parsed. | |
| 231 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", " | |
| 232 "domain=\"http://intranet.example.com/protection\"", | |
| 233 true, | |
| 234 "Thunder Bluff", | |
| 235 "xyz", | |
| 236 "http://intranet.example.com/protection", | |
| 237 "", | |
| 238 false, | |
| 239 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 240 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 241 }, | |
| 242 | |
| 243 { // Multiple domains can be parsed. | |
| 244 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", " | |
| 245 "domain=\"http://intranet.example.com/protection http://www.google.com\"", | |
| 246 true, | |
| 247 "Thunder Bluff", | |
| 248 "xyz", | |
| 249 "http://intranet.example.com/protection http://www.google.com", | |
| 250 "", | |
| 251 false, | |
| 252 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 253 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 254 }, | |
| 255 | |
| 256 { // If a non-Digest scheme is somehow passed in, it should be rejected. | |
| 257 "Basic realm=\"foo\"", | |
| 258 false, | |
| 259 "", | |
| 260 "", | |
| 261 "", | |
| 262 "", | |
| 263 false, | |
| 264 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 265 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 266 }, | |
| 105 }; | 267 }; |
| 106 | 268 |
| 107 GURL origin("http://www.example.com"); | 269 GURL origin("http://www.example.com"); |
| 108 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 270 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 109 new HttpAuthHandlerDigest::Factory()); | 271 new HttpAuthHandlerDigest::Factory()); |
| 110 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 272 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 111 scoped_ptr<HttpAuthHandler> handler; | 273 scoped_ptr<HttpAuthHandler> handler; |
| 112 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge, | 274 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge, |
| 113 HttpAuth::AUTH_SERVER, | 275 HttpAuth::AUTH_SERVER, |
| 114 origin, | 276 origin, |
| 115 BoundNetLog(), | 277 BoundNetLog(), |
| 116 &handler); | 278 &handler); |
| 117 if (tests[i].parsed_success) { | 279 if (tests[i].parsed_success) { |
| 118 EXPECT_EQ(OK, rv); | 280 EXPECT_EQ(OK, rv); |
| 119 } else { | 281 } else { |
| 120 EXPECT_NE(OK, rv); | 282 EXPECT_NE(OK, rv); |
| 283 EXPECT_TRUE(handler.get() == NULL); | |
| 121 continue; | 284 continue; |
| 122 } | 285 } |
| 123 ASSERT_TRUE(handler != NULL); | 286 ASSERT_TRUE(handler.get() != NULL); |
| 124 HttpAuthHandlerDigest* digest = | 287 HttpAuthHandlerDigest* digest = |
| 125 static_cast<HttpAuthHandlerDigest*>(handler.get()); | 288 static_cast<HttpAuthHandlerDigest*>(handler.get()); |
| 126 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); | 289 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); |
| 127 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); | 290 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); |
| 128 EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str()); | 291 EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str()); |
| 129 EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str()); | 292 EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str()); |
| 130 EXPECT_EQ(tests[i].parsed_stale, digest->stale_); | 293 EXPECT_EQ(tests[i].parsed_stale, digest->stale_); |
| 131 EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_); | 294 EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_); |
| 132 EXPECT_EQ(tests[i].parsed_qop, digest->qop_); | 295 EXPECT_EQ(tests[i].parsed_qop, digest->qop_); |
| 133 } | 296 } |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 tests[i].req_path, | 447 tests[i].req_path, |
| 285 ASCIIToUTF16(tests[i].username), | 448 ASCIIToUTF16(tests[i].username), |
| 286 ASCIIToUTF16(tests[i].password), | 449 ASCIIToUTF16(tests[i].password), |
| 287 tests[i].cnonce, | 450 tests[i].cnonce, |
| 288 tests[i].nonce_count); | 451 tests[i].nonce_count); |
| 289 | 452 |
| 290 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); | 453 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); |
| 291 } | 454 } |
| 292 } | 455 } |
| 293 | 456 |
| 294 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge_Failed) { | 457 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { |
| 295 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 458 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 296 new HttpAuthHandlerDigest::Factory()); | 459 new HttpAuthHandlerDigest::Factory()); |
| 297 scoped_ptr<HttpAuthHandler> handler; | 460 scoped_ptr<HttpAuthHandler> handler; |
| 298 std::string default_challenge = | 461 std::string default_challenge = |
| 299 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; | 462 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; |
| 300 GURL origin("intranet.google.com"); | 463 GURL origin("intranet.google.com"); |
| 301 int rv = factory->CreateAuthHandlerFromString( | 464 int rv = factory->CreateAuthHandlerFromString( |
| 302 default_challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), | 465 default_challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), |
| 303 &handler); | 466 &handler); |
| 304 EXPECT_EQ(OK, rv); | 467 EXPECT_EQ(OK, rv); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 315 handler->HandleAnotherChallenge(&tok_stale)); | 478 handler->HandleAnotherChallenge(&tok_stale)); |
| 316 | 479 |
| 317 std::string stale_false_challenge = default_challenge + ", stale=false"; | 480 std::string stale_false_challenge = default_challenge + ", stale=false"; |
| 318 HttpAuth::ChallengeTokenizer tok_stale_false(stale_false_challenge.begin(), | 481 HttpAuth::ChallengeTokenizer tok_stale_false(stale_false_challenge.begin(), |
| 319 stale_false_challenge.end()); | 482 stale_false_challenge.end()); |
| 320 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, | 483 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, |
| 321 handler->HandleAnotherChallenge(&tok_stale_false)); | 484 handler->HandleAnotherChallenge(&tok_stale_false)); |
| 322 } | 485 } |
| 323 | 486 |
| 324 } // namespace net | 487 } // namespace net |
| OLD | NEW |