| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 EXPECT_TRUE(target != HttpAuth::AUTH_PROXY || !proxy_name.empty()); | 43 EXPECT_TRUE(target != HttpAuth::AUTH_PROXY || !proxy_name.empty()); |
| 44 EXPECT_FALSE(request_url.empty()); | 44 EXPECT_FALSE(request_url.empty()); |
| 45 EXPECT_FALSE(challenge.empty()); | 45 EXPECT_FALSE(challenge.empty()); |
| 46 | 46 |
| 47 token->clear(); | 47 token->clear(); |
| 48 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 48 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 49 new HttpAuthHandlerDigest::Factory()); | 49 new HttpAuthHandlerDigest::Factory()); |
| 50 HttpAuthHandlerDigest::NonceGenerator* nonce_generator = | 50 HttpAuthHandlerDigest::NonceGenerator* nonce_generator = |
| 51 new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce"); | 51 new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce"); |
| 52 factory->set_nonce_generator(nonce_generator); | 52 factory->set_nonce_generator(nonce_generator); |
| 53 scoped_ptr<HttpAuthHandler> handler; | |
| 54 | 53 |
| 55 // Create a handler for a particular challenge. | 54 // Create a handler for a particular challenge. |
| 56 GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name); | 55 GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name); |
| 57 int rv_create = factory->CreateAuthHandlerFromString( | 56 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 58 challenge, target, url_origin.GetOrigin(), BoundNetLog(), &handler); | 57 scoped_ptr<HttpAuthHandler> handler = |
| 59 if (rv_create != OK || handler.get() == NULL) { | 58 factory->CreateAuthHandlerForScheme(tokenizer.NormalizedScheme()); |
| 59 int rv = handler->HandleInitialChallenge( |
| 60 tokenizer, target, url_origin.GetOrigin(), BoundNetLog()); |
| 61 if (rv != OK || handler.get() == NULL) { |
| 60 ADD_FAILURE() << "Unable to create auth handler."; | 62 ADD_FAILURE() << "Unable to create auth handler."; |
| 61 return false; | 63 return false; |
| 62 } | 64 } |
| 63 | 65 |
| 64 // Create a token in response to the challenge. | 66 // Create a token in response to the challenge. |
| 65 // NOTE: HttpAuthHandlerDigest's implementation of GenerateAuthToken always | 67 // NOTE: HttpAuthHandlerDigest's implementation of GenerateAuthToken always |
| 66 // completes synchronously. That's why this test can get away with a | 68 // completes synchronously. That's why this test can get away with a |
| 67 // TestCompletionCallback without an IO thread. | 69 // TestCompletionCallback without an IO thread. |
| 68 TestCompletionCallback callback; | 70 TestCompletionCallback callback; |
| 69 scoped_ptr<HttpRequestInfo> request(new HttpRequestInfo()); | 71 scoped_ptr<HttpRequestInfo> request(new HttpRequestInfo()); |
| 70 request->url = GURL(request_url); | 72 request->url = GURL(request_url); |
| 71 AuthCredentials credentials(base::ASCIIToUTF16("foo"), | 73 AuthCredentials credentials(base::ASCIIToUTF16("foo"), |
| 72 base::ASCIIToUTF16("bar")); | 74 base::ASCIIToUTF16("bar")); |
| 73 int rv_generate = handler->GenerateAuthToken(&credentials, *request, | 75 rv = handler->GenerateAuthToken(&credentials, *request, callback.callback(), |
| 74 callback.callback(), token); | 76 token); |
| 75 if (rv_generate != OK) { | 77 if (rv != OK) { |
| 76 ADD_FAILURE() << "Problems generating auth token"; | 78 ADD_FAILURE() << "Problems generating auth token"; |
| 77 return false; | 79 return false; |
| 78 } | 80 } |
| 79 | 81 |
| 80 return true; | 82 return true; |
| 81 } | 83 } |
| 82 | 84 |
| 83 } // namespace | 85 } // namespace |
| 84 | 86 |
| 87 TEST(HttpAuthHandlerDigestTest, CreateAuthHandlerForScheme) { |
| 88 HttpAuthHandlerDigest::Factory digest_factory; |
| 89 |
| 90 EXPECT_TRUE(digest_factory.CreateAuthHandlerForScheme("digest")); |
| 91 EXPECT_FALSE(digest_factory.CreateAuthHandlerForScheme("bogus")); |
| 92 } |
| 93 |
| 94 TEST(HttpAuthHandlerDigestTest, CreateAndInitPreemptiveAuthHandler_Valid) { |
| 95 HttpAuthHandlerDigest::Factory digest_factory; |
| 96 HttpAuthCache auth_cache; |
| 97 std::string challenge(kSimpleChallenge); |
| 98 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 99 |
| 100 HttpAuthCache::Entry* entry = |
| 101 auth_cache.Add(GURL("http://example.com/foo").GetOrigin(), "foo", |
| 102 "digest", challenge, AuthCredentials(), "/foo"); |
| 103 EXPECT_TRUE(digest_factory.CreateAndInitPreemptiveAuthHandler( |
| 104 entry, tokenizer, HttpAuth::AUTH_SERVER, BoundNetLog())); |
| 105 } |
| 106 |
| 107 TEST(HttpAuthHandlerDigestTest, CreateAndInitPreemptiveAuthHandler_Invalid) { |
| 108 HttpAuthHandlerDigest::Factory digest_factory; |
| 109 HttpAuthCache auth_cache; |
| 110 std::string challenge("Basic realm=\"bar\""); |
| 111 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 112 |
| 113 HttpAuthCache::Entry* entry = |
| 114 auth_cache.Add(GURL("http://example.com").GetOrigin(), "bar", "basic", |
| 115 challenge, AuthCredentials(), "/bar"); |
| 116 EXPECT_FALSE(digest_factory.CreateAndInitPreemptiveAuthHandler( |
| 117 entry, tokenizer, HttpAuth::AUTH_SERVER, BoundNetLog())); |
| 118 } |
| 85 | 119 |
| 86 TEST(HttpAuthHandlerDigestTest, ParseChallenge) { | 120 TEST(HttpAuthHandlerDigestTest, ParseChallenge) { |
| 87 static const struct { | 121 static const struct { |
| 88 // The challenge string. | 122 // The challenge string. |
| 89 const char* challenge; | 123 const char* challenge; |
| 90 // Expected return value of ParseChallenge. | 124 // Expected return value of ParseChallenge. |
| 91 bool parsed_success; | 125 bool parsed_success; |
| 92 // The expected values that were parsed. | 126 // The expected values that were parsed. |
| 93 const char* parsed_realm; | 127 const char* parsed_realm; |
| 94 const char* parsed_nonce; | 128 const char* parsed_nonce; |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 "domain=\"http://intranet.example.com/protection http://www.google.com\"", | 361 "domain=\"http://intranet.example.com/protection http://www.google.com\"", |
| 328 true, | 362 true, |
| 329 "Thunder Bluff", | 363 "Thunder Bluff", |
| 330 "xyz", | 364 "xyz", |
| 331 "http://intranet.example.com/protection http://www.google.com", | 365 "http://intranet.example.com/protection http://www.google.com", |
| 332 "", | 366 "", |
| 333 false, | 367 false, |
| 334 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | 368 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, |
| 335 HttpAuthHandlerDigest::QOP_UNSPECIFIED | 369 HttpAuthHandlerDigest::QOP_UNSPECIFIED |
| 336 }, | 370 }, |
| 337 | |
| 338 { // If a non-Digest scheme is somehow passed in, it should be rejected. | |
| 339 "Basic realm=\"foo\"", | |
| 340 false, | |
| 341 "", | |
| 342 "", | |
| 343 "", | |
| 344 "", | |
| 345 false, | |
| 346 HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED, | |
| 347 HttpAuthHandlerDigest::QOP_UNSPECIFIED | |
| 348 }, | |
| 349 }; | 371 }; |
| 350 | 372 |
| 351 GURL origin("http://www.example.com"); | 373 GURL origin("http://www.example.com"); |
| 352 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 374 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 353 new HttpAuthHandlerDigest::Factory()); | 375 new HttpAuthHandlerDigest::Factory()); |
| 354 for (size_t i = 0; i < arraysize(tests); ++i) { | 376 for (size_t i = 0; i < arraysize(tests); ++i) { |
| 355 scoped_ptr<HttpAuthHandler> handler; | 377 std::string challenge = tests[i].challenge; |
| 356 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge, | 378 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 357 HttpAuth::AUTH_SERVER, | 379 scoped_ptr<HttpAuthHandler> handler = |
| 358 origin, | 380 factory->CreateAuthHandlerForScheme(tokenizer.NormalizedScheme()); |
| 359 BoundNetLog(), | 381 ASSERT_TRUE(handler); |
| 360 &handler); | 382 int rv = handler->HandleInitialChallenge(tokenizer, HttpAuth::AUTH_SERVER, |
| 383 origin, BoundNetLog()); |
| 361 if (tests[i].parsed_success) { | 384 if (tests[i].parsed_success) { |
| 362 EXPECT_EQ(OK, rv); | 385 EXPECT_EQ(OK, rv); |
| 363 } else { | 386 } else { |
| 364 EXPECT_NE(OK, rv); | 387 EXPECT_NE(OK, rv); |
| 365 EXPECT_TRUE(handler.get() == NULL); | |
| 366 continue; | 388 continue; |
| 367 } | 389 } |
| 368 ASSERT_TRUE(handler.get() != NULL); | |
| 369 HttpAuthHandlerDigest* digest = | 390 HttpAuthHandlerDigest* digest = |
| 370 static_cast<HttpAuthHandlerDigest*>(handler.get()); | 391 static_cast<HttpAuthHandlerDigest*>(handler.get()); |
| 371 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); | 392 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); |
| 372 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); | 393 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); |
| 373 EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str()); | 394 EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str()); |
| 374 EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str()); | 395 EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str()); |
| 375 EXPECT_EQ(tests[i].parsed_stale, digest->stale_); | 396 EXPECT_EQ(tests[i].parsed_stale, digest->stale_); |
| 376 EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_); | 397 EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_); |
| 377 EXPECT_EQ(tests[i].parsed_qop, digest->qop_); | 398 EXPECT_EQ(tests[i].parsed_qop, digest->qop_); |
| 378 EXPECT_TRUE(handler->NeedsIdentity()); | 399 EXPECT_TRUE(handler->NeedsIdentity()); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 "Digest username=\"USER\", realm=\"Baztastic\", " | 529 "Digest username=\"USER\", realm=\"Baztastic\", " |
| 509 "nonce=\"AAAAAAAA\", uri=\"/\", algorithm=MD5-sess, " | 530 "nonce=\"AAAAAAAA\", uri=\"/\", algorithm=MD5-sess, " |
| 510 "response=\"cbc1139821ee7192069580570c541a03\", " | 531 "response=\"cbc1139821ee7192069580570c541a03\", " |
| 511 "qop=auth, nc=00000001, cnonce=\"15c07961ed8575c4\"" | 532 "qop=auth, nc=00000001, cnonce=\"15c07961ed8575c4\"" |
| 512 } | 533 } |
| 513 }; | 534 }; |
| 514 GURL origin("http://www.example.com"); | 535 GURL origin("http://www.example.com"); |
| 515 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 536 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 516 new HttpAuthHandlerDigest::Factory()); | 537 new HttpAuthHandlerDigest::Factory()); |
| 517 for (size_t i = 0; i < arraysize(tests); ++i) { | 538 for (size_t i = 0; i < arraysize(tests); ++i) { |
| 518 scoped_ptr<HttpAuthHandler> handler; | 539 scoped_ptr<HttpAuthHandler> handler = |
| 519 int rv = factory->CreateAuthHandlerFromString(tests[i].challenge, | 540 factory->CreateAuthHandlerForScheme("digest"); |
| 520 HttpAuth::AUTH_SERVER, | 541 std::string challenge = tests[i].challenge; |
| 521 origin, | 542 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 522 BoundNetLog(), | 543 int rv = handler->HandleInitialChallenge(tokenizer, HttpAuth::AUTH_SERVER, |
| 523 &handler); | 544 origin, BoundNetLog()); |
| 524 EXPECT_EQ(OK, rv); | 545 EXPECT_EQ(OK, rv); |
| 525 ASSERT_TRUE(handler != NULL); | |
| 526 | 546 |
| 527 HttpAuthHandlerDigest* digest = | 547 HttpAuthHandlerDigest* digest = |
| 528 static_cast<HttpAuthHandlerDigest*>(handler.get()); | 548 static_cast<HttpAuthHandlerDigest*>(handler.get()); |
| 529 std::string creds = | 549 std::string creds = |
| 530 digest->AssembleCredentials(tests[i].req_method, | 550 digest->AssembleCredentials(tests[i].req_method, |
| 531 tests[i].req_path, | 551 tests[i].req_path, |
| 532 AuthCredentials( | 552 AuthCredentials( |
| 533 base::ASCIIToUTF16(tests[i].username), | 553 base::ASCIIToUTF16(tests[i].username), |
| 534 base::ASCIIToUTF16(tests[i].password)), | 554 base::ASCIIToUTF16(tests[i].password)), |
| 535 tests[i].cnonce, | 555 tests[i].cnonce, |
| 536 tests[i].nonce_count); | 556 tests[i].nonce_count); |
| 537 | 557 |
| 538 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); | 558 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); |
| 539 } | 559 } |
| 540 } | 560 } |
| 541 | 561 |
| 542 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { | 562 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { |
| 543 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 563 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 544 new HttpAuthHandlerDigest::Factory()); | 564 new HttpAuthHandlerDigest::Factory()); |
| 545 scoped_ptr<HttpAuthHandler> handler; | |
| 546 std::string default_challenge = | 565 std::string default_challenge = |
| 547 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; | 566 "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); | |
| 553 ASSERT_TRUE(handler.get() != NULL); | |
| 554 HttpAuthChallengeTokenizer tok_default(default_challenge.begin(), | 567 HttpAuthChallengeTokenizer tok_default(default_challenge.begin(), |
| 555 default_challenge.end()); | 568 default_challenge.end()); |
| 569 GURL origin("intranet.google.com"); |
| 570 scoped_ptr<HttpAuthHandler> handler = |
| 571 factory->CreateAuthHandlerForScheme(tok_default.NormalizedScheme()); |
| 572 EXPECT_EQ(OK, handler->HandleInitialChallenge( |
| 573 tok_default, HttpAuth::AUTH_SERVER, origin, BoundNetLog())); |
| 574 ASSERT_TRUE(handler.get() != NULL); |
| 556 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, | 575 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, |
| 557 handler->HandleAnotherChallenge(tok_default)); | 576 handler->HandleAnotherChallenge(tok_default)); |
| 558 | 577 |
| 559 std::string stale_challenge = default_challenge + ", stale=true"; | 578 std::string stale_challenge = default_challenge + ", stale=true"; |
| 560 HttpAuthChallengeTokenizer tok_stale(stale_challenge.begin(), | 579 HttpAuthChallengeTokenizer tok_stale(stale_challenge.begin(), |
| 561 stale_challenge.end()); | 580 stale_challenge.end()); |
| 562 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_STALE, | 581 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_STALE, |
| 563 handler->HandleAnotherChallenge(tok_stale)); | 582 handler->HandleAnotherChallenge(tok_stale)); |
| 564 | 583 |
| 565 std::string stale_false_challenge = default_challenge + ", stale=false"; | 584 std::string stale_false_challenge = default_challenge + ", stale=false"; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", " | 706 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", " |
| 688 "nonce=\"nonce-value\", uri=\"/path/to/resource\", " | 707 "nonce=\"nonce-value\", uri=\"/path/to/resource\", " |
| 689 "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", " | 708 "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", " |
| 690 "opaque=\"opaque text\", " | 709 "opaque=\"opaque text\", " |
| 691 "qop=auth, nc=00000001, cnonce=\"client_nonce\"", | 710 "qop=auth, nc=00000001, cnonce=\"client_nonce\"", |
| 692 auth_token); | 711 auth_token); |
| 693 } | 712 } |
| 694 | 713 |
| 695 | 714 |
| 696 } // namespace net | 715 } // namespace net |
| OLD | NEW |