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", |
| 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 { // auth-int is not handled, but will fall back to default qop. |
82 // See http://crbug.com/20984. | 168 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth-int\"", |
83 "Digest nonce=\"xyz\"", | |
84 true, | 169 true, |
85 "", | 170 "Oblivion", |
86 "xyz", | 171 "xyz", |
87 "", | 172 "", |
88 "", | 173 "", |
89 false, | 174 false, |
90 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | 175 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
91 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 176 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
92 }, | 177 }, |
93 | 178 |
94 { // Try with realm set to empty string. | 179 { // Unknown qop values are ignored. |
95 "Digest realm=\"\", nonce=\"xyz\"", | 180 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,foo\"", |
96 true, | 181 true, |
97 "", | 182 "Oblivion", |
98 "xyz", | 183 "xyz", |
99 "", | 184 "", |
100 "", | 185 "", |
101 false, | 186 false, |
102 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | 187 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 188 HttpAuthHandlerDigest::QOP_AUTH |
| 189 }, |
| 190 |
| 191 { // If auth-int is included with auth, then use auth. |
| 192 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,auth-int\"", |
| 193 true, |
| 194 "Oblivion", |
| 195 "xyz", |
| 196 "", |
| 197 "", |
| 198 false, |
| 199 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 200 HttpAuthHandlerDigest::QOP_AUTH |
| 201 }, |
| 202 |
| 203 { // Opaque parameter parsing should work correctly. |
| 204 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=\"foobar\"", |
| 205 true, |
| 206 "Thunder Bluff", |
| 207 "xyz", |
| 208 "", |
| 209 "foobar", |
| 210 false, |
| 211 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
103 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 212 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
104 } | 213 }, |
| 214 |
| 215 { // Opaque parameters do not need to be quoted, even though RFC2617 |
| 216 // seems to require it. |
| 217 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=foobar", |
| 218 true, |
| 219 "Thunder Bluff", |
| 220 "xyz", |
| 221 "", |
| 222 "foobar", |
| 223 false, |
| 224 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 225 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 226 }, |
| 227 |
| 228 { // Domain can be parsed. |
| 229 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", " |
| 230 "domain=\"http://intranet.example.com/protection\"", |
| 231 true, |
| 232 "Thunder Bluff", |
| 233 "xyz", |
| 234 "http://intranet.example.com/protection", |
| 235 "", |
| 236 false, |
| 237 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 238 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 239 }, |
| 240 |
| 241 { // Multiple domains can be parsed. |
| 242 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", " |
| 243 "domain=\"http://intranet.example.com/protection http://www.google.com\"", |
| 244 true, |
| 245 "Thunder Bluff", |
| 246 "xyz", |
| 247 "http://intranet.example.com/protection http://www.google.com", |
| 248 "", |
| 249 false, |
| 250 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 251 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 252 }, |
| 253 |
| 254 { // If a non-Digest scheme is somehow passed in, it should be rejected. |
| 255 "Basic realm=\"foo\"", |
| 256 false, |
| 257 "", |
| 258 "", |
| 259 "", |
| 260 "", |
| 261 false, |
| 262 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 263 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 264 }, |
105 }; | 265 }; |
106 | 266 |
107 GURL origin("http://www.example.com"); | 267 GURL origin("http://www.example.com"); |
108 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 268 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
109 new HttpAuthHandlerDigest::Factory()); | 269 new HttpAuthHandlerDigest::Factory()); |
110 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 270 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
111 scoped_ptr<HttpAuthHandler> handler; | 271 scoped_ptr<HttpAuthHandler> handler; |
112 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge, | 272 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge, |
113 HttpAuth::AUTH_SERVER, | 273 HttpAuth::AUTH_SERVER, |
114 origin, | 274 origin, |
115 BoundNetLog(), | 275 BoundNetLog(), |
116 &handler); | 276 &handler); |
117 if (tests[i].parsed_success) { | 277 if (tests[i].parsed_success) { |
118 EXPECT_EQ(OK, rv); | 278 EXPECT_EQ(OK, rv); |
119 } else { | 279 } else { |
120 EXPECT_NE(OK, rv); | 280 EXPECT_NE(OK, rv); |
| 281 EXPECT_TRUE(handler.get() == NULL); |
121 continue; | 282 continue; |
122 } | 283 } |
123 ASSERT_TRUE(handler != NULL); | 284 ASSERT_TRUE(handler.get() != NULL); |
124 HttpAuthHandlerDigest* digest = | 285 HttpAuthHandlerDigest* digest = |
125 static_cast<HttpAuthHandlerDigest*>(handler.get()); | 286 static_cast<HttpAuthHandlerDigest*>(handler.get()); |
126 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); | 287 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); |
127 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); | 288 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); |
128 EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str()); | 289 EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str()); |
129 EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str()); | 290 EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str()); |
130 EXPECT_EQ(tests[i].parsed_stale, digest->stale_); | 291 EXPECT_EQ(tests[i].parsed_stale, digest->stale_); |
131 EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_); | 292 EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_); |
132 EXPECT_EQ(tests[i].parsed_qop, digest->qop_); | 293 EXPECT_EQ(tests[i].parsed_qop, digest->qop_); |
133 } | 294 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 tests[i].req_path, | 445 tests[i].req_path, |
285 ASCIIToUTF16(tests[i].username), | 446 ASCIIToUTF16(tests[i].username), |
286 ASCIIToUTF16(tests[i].password), | 447 ASCIIToUTF16(tests[i].password), |
287 tests[i].cnonce, | 448 tests[i].cnonce, |
288 tests[i].nonce_count); | 449 tests[i].nonce_count); |
289 | 450 |
290 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); | 451 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); |
291 } | 452 } |
292 } | 453 } |
293 | 454 |
294 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge_Failed) { | 455 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { |
295 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 456 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
296 new HttpAuthHandlerDigest::Factory()); | 457 new HttpAuthHandlerDigest::Factory()); |
297 scoped_ptr<HttpAuthHandler> handler; | 458 scoped_ptr<HttpAuthHandler> handler; |
298 std::string default_challenge = | 459 std::string default_challenge = |
299 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; | 460 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; |
300 GURL origin("intranet.google.com"); | 461 GURL origin("intranet.google.com"); |
301 int rv = factory->CreateAuthHandlerFromString( | 462 int rv = factory->CreateAuthHandlerFromString( |
302 default_challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), | 463 default_challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), |
303 &handler); | 464 &handler); |
304 EXPECT_EQ(OK, rv); | 465 EXPECT_EQ(OK, rv); |
(...skipping 10 matching lines...) Expand all Loading... |
315 handler->HandleAnotherChallenge(&tok_stale)); | 476 handler->HandleAnotherChallenge(&tok_stale)); |
316 | 477 |
317 std::string stale_false_challenge = default_challenge + ", stale=false"; | 478 std::string stale_false_challenge = default_challenge + ", stale=false"; |
318 HttpAuth::ChallengeTokenizer tok_stale_false(stale_false_challenge.begin(), | 479 HttpAuth::ChallengeTokenizer tok_stale_false(stale_false_challenge.begin(), |
319 stale_false_challenge.end()); | 480 stale_false_challenge.end()); |
320 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, | 481 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, |
321 handler->HandleAnotherChallenge(&tok_stale_false)); | 482 handler->HandleAnotherChallenge(&tok_stale_false)); |
322 } | 483 } |
323 | 484 |
324 } // namespace net | 485 } // namespace net |
OLD | NEW |