| 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" |
| 11 #include "net/base/test_completion_callback.h" | 11 #include "net/base/test_completion_callback.h" |
| 12 #include "net/http/http_auth_challenge_tokenizer.h" | 12 #include "net/http/http_auth_challenge_tokenizer.h" |
| 13 #include "net/http/http_auth_handler_digest.h" | 13 #include "net/http/http_auth_handler_digest.h" |
| 14 #include "net/http/http_request_info.h" | 14 #include "net/http/http_request_info.h" |
| 15 #include "net/http/http_response_info.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 17 |
| 17 namespace net { | 18 namespace net { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 const char* const kSimpleChallenge = | 22 const char* const kSimpleChallenge = |
| 22 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; | 23 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; |
| 23 | 24 |
| 24 // RespondToChallenge creates an HttpAuthHandlerDigest for the specified | 25 // RespondToChallenge creates an HttpAuthHandlerDigest for the specified |
| (...skipping 24 matching lines...) Expand all Loading... |
| 49 new HttpAuthHandlerDigest::Factory()); | 50 new HttpAuthHandlerDigest::Factory()); |
| 50 HttpAuthHandlerDigest::NonceGenerator* nonce_generator = | 51 HttpAuthHandlerDigest::NonceGenerator* nonce_generator = |
| 51 new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce"); | 52 new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce"); |
| 52 factory->set_nonce_generator(nonce_generator); | 53 factory->set_nonce_generator(nonce_generator); |
| 53 | 54 |
| 54 // Create a handler for a particular challenge. | 55 // Create a handler for a particular challenge. |
| 55 GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name); | 56 GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name); |
| 56 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); | 57 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 57 scoped_ptr<HttpAuthHandler> handler = | 58 scoped_ptr<HttpAuthHandler> handler = |
| 58 factory->CreateAuthHandlerForScheme(tokenizer.NormalizedScheme()); | 59 factory->CreateAuthHandlerForScheme(tokenizer.NormalizedScheme()); |
| 59 int rv = handler->HandleInitialChallenge( | 60 HttpResponseInfo response_info; |
| 60 tokenizer, target, url_origin.GetOrigin(), BoundNetLog()); | 61 TestCompletionCallback callback; |
| 62 int rv = handler->HandleInitialChallenge(tokenizer, response_info, target, |
| 63 url_origin.GetOrigin(), |
| 64 BoundNetLog(), callback.callback()); |
| 65 rv = callback.GetResult(rv); |
| 61 if (rv != OK || handler.get() == NULL) { | 66 if (rv != OK || handler.get() == NULL) { |
| 62 ADD_FAILURE() << "Unable to create auth handler."; | 67 ADD_FAILURE() << "Unable to create auth handler."; |
| 63 return false; | 68 return false; |
| 64 } | 69 } |
| 65 | 70 |
| 66 // Create a token in response to the challenge. | 71 // Create a token in response to the challenge. |
| 67 // NOTE: HttpAuthHandlerDigest's implementation of GenerateAuthToken always | 72 // NOTE: HttpAuthHandlerDigest's implementation of GenerateAuthToken always |
| 68 // completes synchronously. That's why this test can get away with a | 73 // completes synchronously. That's why this test can get away with a |
| 69 // TestCompletionCallback without an IO thread. | 74 // TestCompletionCallback without an IO thread. |
| 70 TestCompletionCallback callback; | |
| 71 scoped_ptr<HttpRequestInfo> request(new HttpRequestInfo()); | 75 scoped_ptr<HttpRequestInfo> request(new HttpRequestInfo()); |
| 72 request->url = GURL(request_url); | 76 request->url = GURL(request_url); |
| 73 AuthCredentials credentials(base::ASCIIToUTF16("foo"), | 77 AuthCredentials credentials(base::ASCIIToUTF16("foo"), |
| 74 base::ASCIIToUTF16("bar")); | 78 base::ASCIIToUTF16("bar")); |
| 75 rv = handler->GenerateAuthToken(&credentials, *request, callback.callback(), | 79 rv = handler->GenerateAuthToken(&credentials, *request, callback.callback(), |
| 76 token); | 80 token); |
| 77 if (rv != OK) { | 81 if (rv != OK) { |
| 78 ADD_FAILURE() << "Problems generating auth token"; | 82 ADD_FAILURE() << "Problems generating auth token"; |
| 79 return false; | 83 return false; |
| 80 } | 84 } |
| 81 | 85 |
| 82 return true; | 86 return true; |
| 83 } | 87 } |
| 84 | 88 |
| 85 } // namespace | 89 } // namespace |
| 86 | 90 |
| 87 TEST(HttpAuthHandlerDigestTest, CreateAuthHandlerForScheme) { | 91 TEST(HttpAuthHandlerDigestTest, CreateAuthHandlerForScheme) { |
| 88 HttpAuthHandlerDigest::Factory digest_factory; | 92 HttpAuthHandlerDigest::Factory digest_factory; |
| 89 | 93 |
| 90 EXPECT_TRUE(digest_factory.CreateAuthHandlerForScheme("digest")); | 94 EXPECT_TRUE(digest_factory.CreateAuthHandlerForScheme("digest")); |
| 91 EXPECT_FALSE(digest_factory.CreateAuthHandlerForScheme("bogus")); | 95 EXPECT_FALSE(digest_factory.CreateAuthHandlerForScheme("bogus")); |
| 92 } | 96 } |
| 93 | 97 |
| 94 TEST(HttpAuthHandlerDigestTest, CreateAndInitPreemptiveAuthHandler_Valid) { | 98 TEST(HttpAuthHandlerDigestTest, CreateAndInitPreemptiveAuthHandler_Valid) { |
| 95 HttpAuthHandlerDigest::Factory digest_factory; | 99 HttpAuthHandlerDigest::Factory digest_factory; |
| 96 HttpAuthCache auth_cache; | 100 HttpAuthCache auth_cache; |
| 97 std::string challenge(kSimpleChallenge); | 101 std::string challenge(kSimpleChallenge); |
| 98 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); | |
| 99 | 102 |
| 100 HttpAuthCache::Entry* entry = | 103 HttpAuthCache::Entry* entry = |
| 101 auth_cache.Add(GURL("http://example.com/foo").GetOrigin(), "foo", | 104 auth_cache.Add(GURL("http://example.com/foo").GetOrigin(), "foo", |
| 102 "digest", challenge, AuthCredentials(), "/foo"); | 105 "digest", challenge, AuthCredentials(), "/foo"); |
| 103 EXPECT_TRUE(digest_factory.CreateAndInitPreemptiveAuthHandler( | 106 EXPECT_TRUE(digest_factory.CreateAndInitPreemptiveAuthHandler( |
| 104 entry, tokenizer, HttpAuth::AUTH_SERVER, BoundNetLog())); | 107 entry, HttpAuth::AUTH_SERVER, BoundNetLog())); |
| 105 } | 108 } |
| 106 | 109 |
| 107 TEST(HttpAuthHandlerDigestTest, CreateAndInitPreemptiveAuthHandler_Invalid) { | 110 TEST(HttpAuthHandlerDigestTest, CreateAndInitPreemptiveAuthHandler_Invalid) { |
| 108 HttpAuthHandlerDigest::Factory digest_factory; | 111 HttpAuthHandlerDigest::Factory digest_factory; |
| 109 HttpAuthCache auth_cache; | 112 HttpAuthCache auth_cache; |
| 110 std::string challenge("Basic realm=\"bar\""); | 113 std::string challenge("Basic realm=\"bar\""); |
| 111 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); | |
| 112 | 114 |
| 113 HttpAuthCache::Entry* entry = | 115 HttpAuthCache::Entry* entry = |
| 114 auth_cache.Add(GURL("http://example.com").GetOrigin(), "bar", "basic", | 116 auth_cache.Add(GURL("http://example.com").GetOrigin(), "bar", "basic", |
| 115 challenge, AuthCredentials(), "/bar"); | 117 challenge, AuthCredentials(), "/bar"); |
| 116 EXPECT_FALSE(digest_factory.CreateAndInitPreemptiveAuthHandler( | 118 EXPECT_FALSE(digest_factory.CreateAndInitPreemptiveAuthHandler( |
| 117 entry, tokenizer, HttpAuth::AUTH_SERVER, BoundNetLog())); | 119 entry, HttpAuth::AUTH_SERVER, BoundNetLog())); |
| 118 } | 120 } |
| 119 | 121 |
| 120 TEST(HttpAuthHandlerDigestTest, ParseChallenge) { | 122 TEST(HttpAuthHandlerDigestTest, ParseChallenge) { |
| 121 static const struct { | 123 static const struct { |
| 122 // The challenge string. | 124 // The challenge string. |
| 123 const char* challenge; | 125 const char* challenge; |
| 124 // Expected return value of ParseChallenge. | 126 // Expected return value of ParseChallenge. |
| 125 bool parsed_success; | 127 bool parsed_success; |
| 126 // The expected values that were parsed. | 128 // The expected values that were parsed. |
| 127 const char* parsed_realm; | 129 const char* parsed_realm; |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 | 374 |
| 373 GURL origin("http://www.example.com"); | 375 GURL origin("http://www.example.com"); |
| 374 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 376 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 375 new HttpAuthHandlerDigest::Factory()); | 377 new HttpAuthHandlerDigest::Factory()); |
| 376 for (size_t i = 0; i < arraysize(tests); ++i) { | 378 for (size_t i = 0; i < arraysize(tests); ++i) { |
| 377 std::string challenge = tests[i].challenge; | 379 std::string challenge = tests[i].challenge; |
| 378 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); | 380 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 379 scoped_ptr<HttpAuthHandler> handler = | 381 scoped_ptr<HttpAuthHandler> handler = |
| 380 factory->CreateAuthHandlerForScheme(tokenizer.NormalizedScheme()); | 382 factory->CreateAuthHandlerForScheme(tokenizer.NormalizedScheme()); |
| 381 ASSERT_TRUE(handler); | 383 ASSERT_TRUE(handler); |
| 382 int rv = handler->HandleInitialChallenge(tokenizer, HttpAuth::AUTH_SERVER, | 384 HttpResponseInfo response_info; |
| 383 origin, BoundNetLog()); | 385 TestCompletionCallback callback; |
| 386 int rv = handler->HandleInitialChallenge( |
| 387 tokenizer, response_info, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), |
| 388 callback.callback()); |
| 389 rv = callback.GetResult(rv); |
| 384 if (tests[i].parsed_success) { | 390 if (tests[i].parsed_success) { |
| 385 EXPECT_EQ(OK, rv); | 391 EXPECT_EQ(OK, rv); |
| 386 } else { | 392 } else { |
| 387 EXPECT_NE(OK, rv); | 393 EXPECT_NE(OK, rv); |
| 388 continue; | 394 continue; |
| 389 } | 395 } |
| 390 HttpAuthHandlerDigest* digest = | 396 HttpAuthHandlerDigest* digest = |
| 391 static_cast<HttpAuthHandlerDigest*>(handler.get()); | 397 static_cast<HttpAuthHandlerDigest*>(handler.get()); |
| 392 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); | 398 EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); |
| 393 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); | 399 EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 } | 539 } |
| 534 }; | 540 }; |
| 535 GURL origin("http://www.example.com"); | 541 GURL origin("http://www.example.com"); |
| 536 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 542 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 537 new HttpAuthHandlerDigest::Factory()); | 543 new HttpAuthHandlerDigest::Factory()); |
| 538 for (size_t i = 0; i < arraysize(tests); ++i) { | 544 for (size_t i = 0; i < arraysize(tests); ++i) { |
| 539 scoped_ptr<HttpAuthHandler> handler = | 545 scoped_ptr<HttpAuthHandler> handler = |
| 540 factory->CreateAuthHandlerForScheme("digest"); | 546 factory->CreateAuthHandlerForScheme("digest"); |
| 541 std::string challenge = tests[i].challenge; | 547 std::string challenge = tests[i].challenge; |
| 542 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); | 548 HttpAuthChallengeTokenizer tokenizer(challenge.begin(), challenge.end()); |
| 543 int rv = handler->HandleInitialChallenge(tokenizer, HttpAuth::AUTH_SERVER, | 549 HttpResponseInfo response_info; |
| 544 origin, BoundNetLog()); | 550 TestCompletionCallback callback; |
| 545 EXPECT_EQ(OK, rv); | 551 int rv = handler->HandleInitialChallenge( |
| 552 tokenizer, response_info, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), |
| 553 callback.callback()); |
| 554 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 546 | 555 |
| 547 HttpAuthHandlerDigest* digest = | 556 HttpAuthHandlerDigest* digest = |
| 548 static_cast<HttpAuthHandlerDigest*>(handler.get()); | 557 static_cast<HttpAuthHandlerDigest*>(handler.get()); |
| 549 std::string creds = | 558 std::string creds = |
| 550 digest->AssembleCredentials(tests[i].req_method, | 559 digest->AssembleCredentials(tests[i].req_method, |
| 551 tests[i].req_path, | 560 tests[i].req_path, |
| 552 AuthCredentials( | 561 AuthCredentials( |
| 553 base::ASCIIToUTF16(tests[i].username), | 562 base::ASCIIToUTF16(tests[i].username), |
| 554 base::ASCIIToUTF16(tests[i].password)), | 563 base::ASCIIToUTF16(tests[i].password)), |
| 555 tests[i].cnonce, | 564 tests[i].cnonce, |
| 556 tests[i].nonce_count); | 565 tests[i].nonce_count); |
| 557 | 566 |
| 558 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); | 567 EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); |
| 559 } | 568 } |
| 560 } | 569 } |
| 561 | 570 |
| 562 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { | 571 TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { |
| 563 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( | 572 scoped_ptr<HttpAuthHandlerDigest::Factory> factory( |
| 564 new HttpAuthHandlerDigest::Factory()); | 573 new HttpAuthHandlerDigest::Factory()); |
| 565 std::string default_challenge = | 574 std::string default_challenge = |
| 566 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; | 575 "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; |
| 567 HttpAuthChallengeTokenizer tok_default(default_challenge.begin(), | 576 HttpAuthChallengeTokenizer tok_default(default_challenge.begin(), |
| 568 default_challenge.end()); | 577 default_challenge.end()); |
| 569 GURL origin("intranet.google.com"); | 578 GURL origin("intranet.google.com"); |
| 570 scoped_ptr<HttpAuthHandler> handler = | 579 scoped_ptr<HttpAuthHandler> handler = |
| 571 factory->CreateAuthHandlerForScheme(tok_default.NormalizedScheme()); | 580 factory->CreateAuthHandlerForScheme(tok_default.NormalizedScheme()); |
| 572 EXPECT_EQ(OK, handler->HandleInitialChallenge( | 581 HttpResponseInfo response_info; |
| 573 tok_default, HttpAuth::AUTH_SERVER, origin, BoundNetLog())); | 582 TestCompletionCallback callback; |
| 583 int rv = handler->HandleInitialChallenge(tok_default, response_info, |
| 584 HttpAuth::AUTH_SERVER, origin, |
| 585 BoundNetLog(), callback.callback()); |
| 586 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 574 ASSERT_TRUE(handler.get() != NULL); | 587 ASSERT_TRUE(handler.get() != NULL); |
| 575 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, | 588 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, |
| 576 handler->HandleAnotherChallenge(tok_default)); | 589 handler->HandleAnotherChallenge(tok_default)); |
| 577 | 590 |
| 578 std::string stale_challenge = default_challenge + ", stale=true"; | 591 std::string stale_challenge = default_challenge + ", stale=true"; |
| 579 HttpAuthChallengeTokenizer tok_stale(stale_challenge.begin(), | 592 HttpAuthChallengeTokenizer tok_stale(stale_challenge.begin(), |
| 580 stale_challenge.end()); | 593 stale_challenge.end()); |
| 581 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_STALE, | 594 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_STALE, |
| 582 handler->HandleAnotherChallenge(tok_stale)); | 595 handler->HandleAnotherChallenge(tok_stale)); |
| 583 | 596 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", " | 719 EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", " |
| 707 "nonce=\"nonce-value\", uri=\"/path/to/resource\", " | 720 "nonce=\"nonce-value\", uri=\"/path/to/resource\", " |
| 708 "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", " | 721 "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", " |
| 709 "opaque=\"opaque text\", " | 722 "opaque=\"opaque text\", " |
| 710 "qop=auth, nc=00000001, cnonce=\"client_nonce\"", | 723 "qop=auth, nc=00000001, cnonce=\"client_nonce\"", |
| 711 auth_token); | 724 auth_token); |
| 712 } | 725 } |
| 713 | 726 |
| 714 | 727 |
| 715 } // namespace net | 728 } // namespace net |
| OLD | NEW |