blob: 55ef56584195f86d6aeb2af992dd368adc352f13 [file] [log] [blame]
[email protected]79cb5c12011-09-12 13:12:041// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]c3b35c22008-09-27 03:19:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]13c8a092010-07-29 06:15:445#include <string>
[email protected]c3b35c22008-09-27 03:19:426
7#include "base/basictypes.h"
[email protected]13c8a092010-07-29 06:15:448#include "base/string_util.h"
[email protected]be1ce6a72010-08-03 14:35:229#include "base/utf_string_conversions.h"
[email protected]36c8e5f72010-06-07 14:17:1410#include "net/base/net_errors.h"
[email protected]5bd68b132010-11-19 18:17:1611#include "net/base/test_completion_callback.h"
[email protected]c3b35c22008-09-27 03:19:4212#include "net/http/http_auth_handler_digest.h"
[email protected]5bd68b132010-11-19 18:17:1613#include "net/http/http_request_info.h"
[email protected]13c8a092010-07-29 06:15:4414#include "testing/gtest/include/gtest/gtest.h"
[email protected]c3b35c22008-09-27 03:19:4215
16namespace net {
17
[email protected]e06306f2010-12-02 14:56:2318namespace {
19
20const char* const kSimpleChallenge =
21 "Digest realm=\"Oblivion\", nonce=\"nonce-value\"";
22
23// RespondToChallenge creates an HttpAuthHandlerDigest for the specified
24// |challenge|, and generates a response to the challenge which is returned in
25// |token|.
26//
27// The return value indicates whether the |token| was successfully created.
28//
29// If |target| is HttpAuth::AUTH_PROXY, then |proxy_name| specifies the source
30// of the |challenge|. Otherwise, the scheme and host and port of |request_url|
31// indicates the origin of the challenge.
32bool RespondToChallenge(HttpAuth::Target target,
33 const std::string& proxy_name,
34 const std::string& request_url,
35 const std::string& challenge,
36 std::string* token) {
37 // Input validation.
38 if (token == NULL) {
39 ADD_FAILURE() << "|token| must be non-NULL";
40 return false;
41 }
42 EXPECT_TRUE(target != HttpAuth::AUTH_PROXY || !proxy_name.empty());
43 EXPECT_FALSE(request_url.empty());
44 EXPECT_FALSE(challenge.empty());
45
46 token->clear();
47 scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
48 new HttpAuthHandlerDigest::Factory());
49 HttpAuthHandlerDigest::NonceGenerator* nonce_generator =
50 new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce");
51 factory->set_nonce_generator(nonce_generator);
52 scoped_ptr<HttpAuthHandler> handler;
53
54 // Create a handler for a particular challenge.
55 GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name);
56 int rv_create = factory->CreateAuthHandlerFromString(
57 challenge, target, url_origin.GetOrigin(), BoundNetLog(), &handler);
58 if (rv_create != OK || handler.get() == NULL) {
59 ADD_FAILURE() << "Unable to create auth handler.";
60 return false;
61 }
62
63 // Create a token in response to the challenge.
64 // NOTE: HttpAuthHandlerDigest's implementation of GenerateAuthToken always
65 // completes synchronously. That's why this test can get away with a
[email protected]49639fa2011-12-20 23:22:4166 // TestCompletionCallback without an IO thread.
67 TestCompletionCallback callback;
[email protected]e06306f2010-12-02 14:56:2368 scoped_ptr<HttpRequestInfo> request(new HttpRequestInfo());
69 request->url = GURL(request_url);
[email protected]f3cf9802011-10-28 18:44:5870 AuthCredentials credentials(ASCIIToUTF16("foo"), ASCIIToUTF16("bar"));
[email protected]e06306f2010-12-02 14:56:2371 int rv_generate = handler->GenerateAuthToken(
[email protected]49639fa2011-12-20 23:22:4172 &credentials, request.get(), callback.callback(), token);
[email protected]e06306f2010-12-02 14:56:2373 if (rv_generate != OK) {
74 ADD_FAILURE() << "Problems generating auth token";
75 return false;
76 }
77
78 return true;
79}
80
81} // namespace
82
83
[email protected]c3b35c22008-09-27 03:19:4284TEST(HttpAuthHandlerDigestTest, ParseChallenge) {
85 static const struct {
86 // The challenge string.
87 const char* challenge;
88 // Expected return value of ParseChallenge.
89 bool parsed_success;
90 // The expected values that were parsed.
91 const char* parsed_realm;
92 const char* parsed_nonce;
93 const char* parsed_domain;
94 const char* parsed_opaque;
95 bool parsed_stale;
96 int parsed_algorithm;
97 int parsed_qop;
98 } tests[] = {
[email protected]eb833112010-11-15 18:30:1499 { // Check that a minimal challenge works correctly.
[email protected]c3b35c22008-09-27 03:19:42100 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\"",
101 true,
102 "Thunder Bluff",
103 "xyz",
104 "",
105 "",
106 false,
107 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
108 HttpAuthHandlerDigest::QOP_UNSPECIFIED
109 },
[email protected]f0a51fb52009-03-05 12:46:38110
[email protected]eb833112010-11-15 18:30:14111 { // Realm does not need to be quoted, even though RFC2617 requires it.
112 "Digest nonce=\"xyz\", realm=ThunderBluff",
113 true,
114 "ThunderBluff",
[email protected]c3b35c22008-09-27 03:19:42115 "xyz",
116 "",
117 "",
118 false,
119 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
120 HttpAuthHandlerDigest::QOP_UNSPECIFIED
121 },
122
[email protected]22927ad2009-09-21 19:56:19123 { // We allow the realm to be omitted, and will default it to empty string.
124 // See http://crbug.com/20984.
[email protected]c3b35c22008-09-27 03:19:42125 "Digest nonce=\"xyz\"",
[email protected]22927ad2009-09-21 19:56:19126 true,
127 "",
128 "xyz",
129 "",
130 "",
131 false,
132 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
133 HttpAuthHandlerDigest::QOP_UNSPECIFIED
134 },
135
136 { // Try with realm set to empty string.
137 "Digest realm=\"\", nonce=\"xyz\"",
138 true,
[email protected]c3b35c22008-09-27 03:19:42139 "",
140 "xyz",
141 "",
142 "",
143 false,
144 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
145 HttpAuthHandlerDigest::QOP_UNSPECIFIED
[email protected]eb833112010-11-15 18:30:14146 },
147
[email protected]79cb5c12011-09-12 13:12:04148 // Handle ISO-8859-1 character as part of the realm. The realm is converted
149 // to UTF-8. However, the credentials will still use the original encoding.
150 {
151 "Digest nonce=\"xyz\", realm=\"foo-\xE5\"",
152 true,
153 "foo-\xC3\xA5",
154 "xyz",
155 "",
156 "",
157 false,
158 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
159 HttpAuthHandlerDigest::QOP_UNSPECIFIED,
160 },
161
[email protected]eb833112010-11-15 18:30:14162 { // At a minimum, a nonce must be provided.
163 "Digest realm=\"Thunder Bluff\"",
164 false,
165 "",
166 "",
167 "",
168 "",
169 false,
170 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
171 HttpAuthHandlerDigest::QOP_UNSPECIFIED
172 },
173
174 { // The nonce does not need to be quoted, even though RFC2617
175 // requires it.
176 "Digest nonce=xyz, realm=\"Thunder Bluff\"",
177 true,
178 "Thunder Bluff",
179 "xyz",
180 "",
181 "",
182 false,
183 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
184 HttpAuthHandlerDigest::QOP_UNSPECIFIED
185 },
186
187 { // Unknown authentication parameters are ignored.
188 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", foo=\"bar\"",
189 true,
190 "Thunder Bluff",
191 "xyz",
192 "",
193 "",
194 false,
195 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
196 HttpAuthHandlerDigest::QOP_UNSPECIFIED
197 },
198
199 { // Check that when algorithm has an unsupported value, parsing fails.
200 "Digest nonce=\"xyz\", algorithm=\"awezum\", realm=\"Thunder\"",
201 false,
202 // The remaining values don't matter (but some have been set already).
203 "",
204 "xyz",
205 "",
206 "",
207 false,
208 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
209 HttpAuthHandlerDigest::QOP_UNSPECIFIED
210 },
211
212 { // Check that algorithm's value is case insensitive, and that MD5 is
213 // a supported algorithm.
214 "Digest nonce=\"xyz\", algorithm=\"mD5\", realm=\"Oblivion\"",
215 true,
216 "Oblivion",
217 "xyz",
218 "",
219 "",
220 false,
221 HttpAuthHandlerDigest::ALGORITHM_MD5,
222 HttpAuthHandlerDigest::QOP_UNSPECIFIED
223 },
224
225 { // Check that md5-sess is a supported algorithm.
226 "Digest nonce=\"xyz\", algorithm=\"md5-sess\", realm=\"Oblivion\"",
227 true,
228 "Oblivion",
229 "xyz",
230 "",
231 "",
232 false,
233 HttpAuthHandlerDigest::ALGORITHM_MD5_SESS,
234 HttpAuthHandlerDigest::QOP_UNSPECIFIED,
235 },
236
237 { // Check that qop's value is case insensitive, and that auth is known.
238 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"aUth\"",
239 true,
240 "Oblivion",
241 "xyz",
242 "",
243 "",
244 false,
245 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
246 HttpAuthHandlerDigest::QOP_AUTH
247 },
248
249 { // auth-int is not handled, but will fall back to default qop.
250 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth-int\"",
251 true,
252 "Oblivion",
253 "xyz",
254 "",
255 "",
256 false,
257 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
258 HttpAuthHandlerDigest::QOP_UNSPECIFIED
259 },
260
261 { // Unknown qop values are ignored.
262 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,foo\"",
263 true,
264 "Oblivion",
265 "xyz",
266 "",
267 "",
268 false,
269 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
270 HttpAuthHandlerDigest::QOP_AUTH
271 },
272
273 { // If auth-int is included with auth, then use auth.
274 "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,auth-int\"",
275 true,
276 "Oblivion",
277 "xyz",
278 "",
279 "",
280 false,
281 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
282 HttpAuthHandlerDigest::QOP_AUTH
283 },
284
285 { // Opaque parameter parsing should work correctly.
286 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=\"foobar\"",
287 true,
288 "Thunder Bluff",
289 "xyz",
290 "",
291 "foobar",
292 false,
293 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
294 HttpAuthHandlerDigest::QOP_UNSPECIFIED
295 },
296
297 { // Opaque parameters do not need to be quoted, even though RFC2617
298 // seems to require it.
299 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=foobar",
300 true,
301 "Thunder Bluff",
302 "xyz",
303 "",
304 "foobar",
305 false,
306 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
307 HttpAuthHandlerDigest::QOP_UNSPECIFIED
308 },
309
310 { // Domain can be parsed.
311 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", "
312 "domain=\"http://intranet.example.com/protection\"",
313 true,
314 "Thunder Bluff",
315 "xyz",
316 "http://intranet.example.com/protection",
317 "",
318 false,
319 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
320 HttpAuthHandlerDigest::QOP_UNSPECIFIED
321 },
322
323 { // Multiple domains can be parsed.
324 "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", "
325 "domain=\"http://intranet.example.com/protection http://www.google.com\"",
326 true,
327 "Thunder Bluff",
328 "xyz",
329 "http://intranet.example.com/protection http://www.google.com",
330 "",
331 false,
332 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
333 HttpAuthHandlerDigest::QOP_UNSPECIFIED
334 },
335
336 { // If a non-Digest scheme is somehow passed in, it should be rejected.
337 "Basic realm=\"foo\"",
338 false,
339 "",
340 "",
341 "",
342 "",
343 false,
344 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
345 HttpAuthHandlerDigest::QOP_UNSPECIFIED
346 },
[email protected]c3b35c22008-09-27 03:19:42347 };
348
[email protected]36c8e5f72010-06-07 14:17:14349 GURL origin("http://www.example.com");
350 scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
351 new HttpAuthHandlerDigest::Factory());
[email protected]b85ee492008-09-27 19:27:14352 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]36c8e5f72010-06-07 14:17:14353 scoped_ptr<HttpAuthHandler> handler;
354 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge,
355 HttpAuth::AUTH_SERVER,
356 origin,
357 BoundNetLog(),
358 &handler);
359 if (tests[i].parsed_success) {
360 EXPECT_EQ(OK, rv);
361 } else {
362 EXPECT_NE(OK, rv);
[email protected]eb833112010-11-15 18:30:14363 EXPECT_TRUE(handler.get() == NULL);
[email protected]36c8e5f72010-06-07 14:17:14364 continue;
365 }
[email protected]eb833112010-11-15 18:30:14366 ASSERT_TRUE(handler.get() != NULL);
[email protected]36c8e5f72010-06-07 14:17:14367 HttpAuthHandlerDigest* digest =
368 static_cast<HttpAuthHandlerDigest*>(handler.get());
[email protected]f9ee6b52008-11-08 06:46:23369 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str());
370 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str());
371 EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str());
372 EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str());
373 EXPECT_EQ(tests[i].parsed_stale, digest->stale_);
374 EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_);
375 EXPECT_EQ(tests[i].parsed_qop, digest->qop_);
[email protected]5bd68b132010-11-19 18:17:16376 EXPECT_TRUE(handler->encrypts_identity());
377 EXPECT_FALSE(handler->is_connection_based());
378 EXPECT_TRUE(handler->NeedsIdentity());
379 EXPECT_FALSE(handler->AllowsDefaultCredentials());
[email protected]c3b35c22008-09-27 03:19:42380 }
381}
382
383TEST(HttpAuthHandlerDigestTest, AssembleCredentials) {
384 static const struct {
385 const char* req_method;
386 const char* req_path;
387 const char* challenge;
388 const char* username;
389 const char* password;
390 const char* cnonce;
391 int nonce_count;
392 const char* expected_creds;
393 } tests[] = {
394 { // MD5 with username/password
395 "GET",
396 "/test/drealm1",
397
398 // Challenge
399 "Digest realm=\"DRealm1\", "
400 "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\", "
401 "algorithm=MD5, qop=\"auth\"",
402
403 "foo", "bar", // username/password
404 "082c875dcb2ca740", // cnonce
405 1, // nc
406
407 // Authorization
408 "Digest username=\"foo\", realm=\"DRealm1\", "
409 "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\", "
410 "uri=\"/test/drealm1\", algorithm=MD5, "
411 "response=\"bcfaa62f1186a31ff1b474a19a17cf57\", "
412 "qop=auth, nc=00000001, cnonce=\"082c875dcb2ca740\""
413 },
414
415 { // MD5 with username but empty password. username has space in it.
416 "GET",
417 "/test/drealm1/",
418
419 // Challenge
420 "Digest realm=\"DRealm1\", "
421 "nonce=\"Ure30oRXBAA=7eca98bbf521ac6642820b11b86bd2d9ed7edc70\", "
422 "algorithm=MD5, qop=\"auth\"",
423
424 "foo bar", "", // Username/password
425 "082c875dcb2ca740", // cnonce
426 1, // nc
427
428 // Authorization
429 "Digest username=\"foo bar\", realm=\"DRealm1\", "
430 "nonce=\"Ure30oRXBAA=7eca98bbf521ac6642820b11b86bd2d9ed7edc70\", "
431 "uri=\"/test/drealm1/\", algorithm=MD5, "
432 "response=\"93c9c6d5930af3b0eb26c745e02b04a0\", "
433 "qop=auth, nc=00000001, cnonce=\"082c875dcb2ca740\""
434 },
435
[email protected]b85a4f12008-10-29 00:11:08436 { // MD5 with no username.
437 "GET",
438 "/test/drealm1/",
439
440 // Challenge
441 "Digest realm=\"DRealm1\", "
442 "nonce=\"7thGplhaBAA=41fb92453c49799cf353c8cd0aabee02d61a98a8\", "
443 "algorithm=MD5, qop=\"auth\"",
444
445 "", "pass", // Username/password
446 "6509bc74daed8263", // cnonce
447 1, // nc
448
449 // Authorization
450 "Digest username=\"\", realm=\"DRealm1\", "
451 "nonce=\"7thGplhaBAA=41fb92453c49799cf353c8cd0aabee02d61a98a8\", "
452 "uri=\"/test/drealm1/\", algorithm=MD5, "
453 "response=\"bc597110f41a62d07f8b70b6977fcb61\", "
454 "qop=auth, nc=00000001, cnonce=\"6509bc74daed8263\""
455 },
456
457 { // MD5 with no username and no password.
458 "GET",
459 "/test/drealm1/",
460
461 // Challenge
462 "Digest realm=\"DRealm1\", "
463 "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\", "
464 "algorithm=MD5, qop=\"auth\"",
465
466 "", "", // Username/password
467 "1522e61005789929", // cnonce
468 1, // nc
469
470 // Authorization
471 "Digest username=\"\", realm=\"DRealm1\", "
472 "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\", "
473 "uri=\"/test/drealm1/\", algorithm=MD5, "
474 "response=\"22cfa2b30cb500a9591c6d55ec5590a8\", "
475 "qop=auth, nc=00000001, cnonce=\"1522e61005789929\""
476 },
477
[email protected]c3b35c22008-09-27 03:19:42478 { // No algorithm, and no qop.
479 "GET",
480 "/",
481
482 // Challenge
483 "Digest realm=\"Oblivion\", nonce=\"nonce-value\"",
484
485 "FooBar", "pass", // Username/password
486 "", // cnonce
487 1, // nc
488
489 // Authorization
490 "Digest username=\"FooBar\", realm=\"Oblivion\", "
491 "nonce=\"nonce-value\", uri=\"/\", "
492 "response=\"f72ff54ebde2f928860f806ec04acd1b\""
493 },
494
495 { // MD5-sess
496 "GET",
497 "/",
498
499 // Challenge
500 "Digest realm=\"Baztastic\", nonce=\"AAAAAAAA\", "
501 "algorithm=\"md5-sess\", qop=auth",
502
503 "USER", "123", // Username/password
504 "15c07961ed8575c4", // cnonce
505 1, // nc
506
507 // Authorization
508 "Digest username=\"USER\", realm=\"Baztastic\", "
509 "nonce=\"AAAAAAAA\", uri=\"/\", algorithm=MD5-sess, "
510 "response=\"cbc1139821ee7192069580570c541a03\", "
511 "qop=auth, nc=00000001, cnonce=\"15c07961ed8575c4\""
512 }
513 };
[email protected]4de702f42009-09-18 17:46:10514 GURL origin("http://www.example.com");
[email protected]36c8e5f72010-06-07 14:17:14515 scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
516 new HttpAuthHandlerDigest::Factory());
[email protected]b85ee492008-09-27 19:27:14517 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]36c8e5f72010-06-07 14:17:14518 scoped_ptr<HttpAuthHandler> handler;
519 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge,
520 HttpAuth::AUTH_SERVER,
521 origin,
522 BoundNetLog(),
523 &handler);
524 EXPECT_EQ(OK, rv);
525 ASSERT_TRUE(handler != NULL);
[email protected]c3b35c22008-09-27 03:19:42526
[email protected]36c8e5f72010-06-07 14:17:14527 HttpAuthHandlerDigest* digest =
528 static_cast<HttpAuthHandlerDigest*>(handler.get());
[email protected]13c8a092010-07-29 06:15:44529 std::string creds =
530 digest->AssembleCredentials(tests[i].req_method,
531 tests[i].req_path,
[email protected]f3cf9802011-10-28 18:44:58532 AuthCredentials(
533 ASCIIToUTF16(tests[i].username),
534 ASCIIToUTF16(tests[i].password)),
[email protected]13c8a092010-07-29 06:15:44535 tests[i].cnonce,
536 tests[i].nonce_count);
[email protected]f0a51fb52009-03-05 12:46:38537
[email protected]c3b35c22008-09-27 03:19:42538 EXPECT_STREQ(tests[i].expected_creds, creds.c_str());
539 }
540}
541
[email protected]eb833112010-11-15 18:30:14542TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) {
[email protected]eca50e122010-09-11 14:03:30543 scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
544 new HttpAuthHandlerDigest::Factory());
545 scoped_ptr<HttpAuthHandler> handler;
546 std::string default_challenge =
547 "Digest realm=\"Oblivion\", nonce=\"nonce-value\"";
548 GURL origin("intranet.google.com");
549 int rv = factory->CreateAuthHandlerFromString(
550 default_challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(),
551 &handler);
552 EXPECT_EQ(OK, rv);
[email protected]54fea2562010-11-17 14:40:44553 ASSERT_TRUE(handler.get() != NULL);
[email protected]eca50e122010-09-11 14:03:30554 HttpAuth::ChallengeTokenizer tok_default(default_challenge.begin(),
555 default_challenge.end());
556 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
557 handler->HandleAnotherChallenge(&tok_default));
558
559 std::string stale_challenge = default_challenge + ", stale=true";
560 HttpAuth::ChallengeTokenizer tok_stale(stale_challenge.begin(),
561 stale_challenge.end());
562 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_STALE,
563 handler->HandleAnotherChallenge(&tok_stale));
564
565 std::string stale_false_challenge = default_challenge + ", stale=false";
566 HttpAuth::ChallengeTokenizer tok_stale_false(stale_false_challenge.begin(),
567 stale_false_challenge.end());
568 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
569 handler->HandleAnotherChallenge(&tok_stale_false));
[email protected]463f8352011-02-18 14:26:55570
571 std::string realm_change_challenge =
572 "Digest realm=\"SomethingElse\", nonce=\"nonce-value2\"";
573 HttpAuth::ChallengeTokenizer tok_realm_change(realm_change_challenge.begin(),
574 realm_change_challenge.end());
575 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM,
576 handler->HandleAnotherChallenge(&tok_realm_change));
[email protected]eca50e122010-09-11 14:03:30577}
578
[email protected]5bd68b132010-11-19 18:17:16579TEST(HttpAuthHandlerDigest, RespondToServerChallenge) {
580 std::string auth_token;
[email protected]e06306f2010-12-02 14:56:23581 EXPECT_TRUE(RespondToChallenge(
[email protected]5bd68b132010-11-19 18:17:16582 HttpAuth::AUTH_SERVER,
583 std::string(),
584 "http://www.example.com/path/to/resource",
585 kSimpleChallenge,
[email protected]e06306f2010-12-02 14:56:23586 &auth_token));
[email protected]5bd68b132010-11-19 18:17:16587 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
588 "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
589 "response=\"6779f90bd0d658f937c1af967614fe84\"",
590 auth_token);
591}
592
593TEST(HttpAuthHandlerDigest, RespondToHttpsServerChallenge) {
594 std::string auth_token;
[email protected]e06306f2010-12-02 14:56:23595 EXPECT_TRUE(RespondToChallenge(
[email protected]5bd68b132010-11-19 18:17:16596 HttpAuth::AUTH_SERVER,
597 std::string(),
598 "https://www.example.com/path/to/resource",
599 kSimpleChallenge,
[email protected]e06306f2010-12-02 14:56:23600 &auth_token));
[email protected]5bd68b132010-11-19 18:17:16601 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
602 "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
603 "response=\"6779f90bd0d658f937c1af967614fe84\"",
604 auth_token);
605}
606
607TEST(HttpAuthHandlerDigest, RespondToProxyChallenge) {
608 std::string auth_token;
[email protected]e06306f2010-12-02 14:56:23609 EXPECT_TRUE(RespondToChallenge(
[email protected]5bd68b132010-11-19 18:17:16610 HttpAuth::AUTH_PROXY,
611 "http://proxy.intranet.corp.com:3128",
612 "http://www.example.com/path/to/resource",
613 kSimpleChallenge,
[email protected]e06306f2010-12-02 14:56:23614 &auth_token));
[email protected]5bd68b132010-11-19 18:17:16615 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
616 "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
617 "response=\"6779f90bd0d658f937c1af967614fe84\"",
618 auth_token);
619}
620
621TEST(HttpAuthHandlerDigest, RespondToProxyChallengeHttps) {
622 std::string auth_token;
[email protected]e06306f2010-12-02 14:56:23623 EXPECT_TRUE(RespondToChallenge(
[email protected]5bd68b132010-11-19 18:17:16624 HttpAuth::AUTH_PROXY,
625 "http://proxy.intranet.corp.com:3128",
626 "https://www.example.com/path/to/resource",
627 kSimpleChallenge,
[email protected]e06306f2010-12-02 14:56:23628 &auth_token));
[email protected]5bd68b132010-11-19 18:17:16629 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
630 "nonce=\"nonce-value\", uri=\"www.example.com:443\", "
631 "response=\"3270da8467afbe9ddf2334a48d46e9b9\"",
632 auth_token);
633}
634
[email protected]d46ca7302012-09-08 17:37:24635TEST(HttpAuthHandlerDigest, RespondToProxyChallengeWs) {
636 std::string auth_token;
637 EXPECT_TRUE(RespondToChallenge(
638 HttpAuth::AUTH_PROXY,
639 "http://proxy.intranet.corp.com:3128",
640 "ws://www.example.com/echo",
641 kSimpleChallenge,
642 &auth_token));
643 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
644 "nonce=\"nonce-value\", uri=\"www.example.com:80\", "
645 "response=\"aa1df184f68d5b6ab9d9aa4f88e41b4c\"",
646 auth_token);
647}
648
649TEST(HttpAuthHandlerDigest, RespondToProxyChallengeWss) {
650 std::string auth_token;
651 EXPECT_TRUE(RespondToChallenge(
652 HttpAuth::AUTH_PROXY,
653 "http://proxy.intranet.corp.com:3128",
654 "wss://www.example.com/echo",
655 kSimpleChallenge,
656 &auth_token));
657 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
658 "nonce=\"nonce-value\", uri=\"www.example.com:443\", "
659 "response=\"3270da8467afbe9ddf2334a48d46e9b9\"",
660 auth_token);
661}
662
[email protected]5bd68b132010-11-19 18:17:16663TEST(HttpAuthHandlerDigest, RespondToChallengeAuthQop) {
664 std::string auth_token;
[email protected]e06306f2010-12-02 14:56:23665 EXPECT_TRUE(RespondToChallenge(
[email protected]5bd68b132010-11-19 18:17:16666 HttpAuth::AUTH_SERVER,
667 std::string(),
668 "http://www.example.com/path/to/resource",
669 "Digest realm=\"Oblivion\", nonce=\"nonce-value\", qop=\"auth\"",
[email protected]e06306f2010-12-02 14:56:23670 &auth_token));
[email protected]5bd68b132010-11-19 18:17:16671 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
672 "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
673 "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", "
674 "qop=auth, nc=00000001, cnonce=\"client_nonce\"",
675 auth_token);
676}
677
678TEST(HttpAuthHandlerDigest, RespondToChallengeOpaque) {
679 std::string auth_token;
[email protected]e06306f2010-12-02 14:56:23680 EXPECT_TRUE(RespondToChallenge(
[email protected]5bd68b132010-11-19 18:17:16681 HttpAuth::AUTH_SERVER,
682 std::string(),
683 "http://www.example.com/path/to/resource",
684 "Digest realm=\"Oblivion\", nonce=\"nonce-value\", "
685 "qop=\"auth\", opaque=\"opaque text\"",
[email protected]e06306f2010-12-02 14:56:23686 &auth_token));
[email protected]5bd68b132010-11-19 18:17:16687 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
688 "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
689 "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", "
690 "opaque=\"opaque text\", "
691 "qop=auth, nc=00000001, cnonce=\"client_nonce\"",
692 auth_token);
693}
694
695
[email protected]c3b35c22008-09-27 03:19:42696} // namespace net