123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134 |
- // Copyright (c) 2011 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <string>
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/test/simple_test_clock.h"
- #include "base/test/simple_test_tick_clock.h"
- #include "base/time/time.h"
- #include "net/base/net_errors.h"
- #include "net/base/network_isolation_key.h"
- #include "net/base/schemeful_site.h"
- #include "net/http/http_auth_cache.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "url/gurl.h"
- #include "url/scheme_host_port.h"
- using base::ASCIIToUTF16;
- namespace net {
- namespace {
- const char kRealm1[] = "Realm1";
- const char kRealm2[] = "Realm2";
- const char kRealm3[] = "Realm3";
- const char kRealm4[] = "Realm4";
- const char kRealm5[] = "Realm5";
- const std::u16string k123(u"123");
- const std::u16string k1234(u"1234");
- const std::u16string k12345(u"12345");
- const std::u16string kAdmin(u"admin");
- const std::u16string kAlice(u"alice");
- const std::u16string kAlice2(u"alice2");
- const std::u16string kAlice3(u"alice3");
- const std::u16string kPassword(u"password");
- const std::u16string kRoot(u"root");
- const std::u16string kUsername(u"username");
- const std::u16string kWileCoyote(u"wilecoyote");
- AuthCredentials CreateASCIICredentials(const char* username,
- const char* password) {
- return AuthCredentials(ASCIIToUTF16(username), ASCIIToUTF16(password));
- }
- } // namespace
- // Test adding and looking-up cache entries (both by realm and by path).
- TEST(HttpAuthCacheTest, Basic) {
- url::SchemeHostPort scheme_host_port(GURL("http://www.google.com"));
- url::SchemeHostPort scheme_host_port2(GURL("http://www.foobar.com"));
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- HttpAuthCache::Entry* entry;
- // Add cache entries for 4 realms: "Realm1", "Realm2", "Realm3" and
- // "Realm4"
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "Basic realm=Realm1",
- CreateASCIICredentials("realm1-user", "realm1-password"),
- "/foo/bar/index.html");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "Basic realm=Realm2",
- CreateASCIICredentials("realm2-user", "realm2-password"),
- "/foo2/index.html");
- cache.Add(
- scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(), "Basic realm=Realm3",
- CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"),
- std::string());
- cache.Add(
- scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "Digest realm=Realm3",
- CreateASCIICredentials("realm3-digest-user", "realm3-digest-password"),
- "/baz/index.html");
- cache.Add(
- scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(), "Basic realm=Realm4",
- CreateASCIICredentials("realm4-basic-user", "realm4-basic-password"),
- "/");
- cache.Add(scheme_host_port2, HttpAuth::AUTH_SERVER, kRealm5,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "Basic realm=Realm5",
- CreateASCIICredentials("realm5-user", "realm5-password"), "/");
- cache.Add(
- scheme_host_port2, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(), "Basic realm=Realm3",
- CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"),
- std::string());
- // There is no Realm5 in `scheme_host_port`.
- entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm5,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- EXPECT_FALSE(entry);
- // While Realm3 does exist, the scheme is wrong.
- entry = cache.Lookup(url::SchemeHostPort(GURL("https://www.google.com")),
- HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- EXPECT_FALSE(entry);
- // Realm, scheme ok, authentication scheme wrong
- entry = cache.Lookup(url::SchemeHostPort(GURL("https://www.google.com")),
- HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey());
- EXPECT_FALSE(entry);
- // Valid lookup by SchemeHostPort, realm, scheme.
- entry = cache.Lookup(url::SchemeHostPort(GURL("http://www.google.com:80")),
- HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme());
- EXPECT_EQ(kRealm3, entry->realm());
- EXPECT_EQ("Basic realm=Realm3", entry->auth_challenge());
- EXPECT_EQ(u"realm3-basic-user", entry->credentials().username());
- EXPECT_EQ(u"realm3-basic-password", entry->credentials().password());
- // Same realm, scheme with different SchemeHostPorts.
- HttpAuthCache::Entry* entry2 =
- cache.Lookup(url::SchemeHostPort(GURL("http://www.foobar.com:80")),
- HttpAuth::AUTH_SERVER, kRealm3, HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey());
- ASSERT_TRUE(entry2);
- EXPECT_NE(entry, entry2);
- // Valid lookup by SchemeHostPort, realm, scheme when there's a duplicate
- // SchemeHostPort, realm in the cache.
- entry = cache.Lookup(url::SchemeHostPort(GURL("http://www.google.com:80")),
- HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST, entry->scheme());
- EXPECT_EQ(kRealm3, entry->realm());
- EXPECT_EQ("Digest realm=Realm3", entry->auth_challenge());
- EXPECT_EQ(u"realm3-digest-user", entry->credentials().username());
- EXPECT_EQ(u"realm3-digest-password", entry->credentials().password());
- // Valid lookup by realm.
- entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme());
- EXPECT_EQ(kRealm2, entry->realm());
- EXPECT_EQ("Basic realm=Realm2", entry->auth_challenge());
- EXPECT_EQ(u"realm2-user", entry->credentials().username());
- EXPECT_EQ(u"realm2-password", entry->credentials().password());
- // Check that subpaths are recognized.
- HttpAuthCache::Entry* p_realm2_entry =
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- HttpAuthCache::Entry* p_realm4_entry =
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- EXPECT_TRUE(p_realm2_entry);
- EXPECT_TRUE(p_realm4_entry);
- HttpAuthCache::Entry realm2_entry = *p_realm2_entry;
- HttpAuthCache::Entry realm4_entry = *p_realm4_entry;
- // Realm4 applies to '/' and Realm2 applies to '/foo2/'.
- // LookupByPath() should return the closest enclosing path.
- // Positive tests:
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/foo2/index.html");
- EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/foo2/foobar.html");
- EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/foo2/bar/index.html");
- EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/foo2/");
- EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/foo2");
- EXPECT_TRUE(realm4_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/");
- EXPECT_TRUE(realm4_entry.IsEqualForTesting(*entry));
- // Negative tests:
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/foo3/index.html");
- EXPECT_FALSE(realm2_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), std::string());
- EXPECT_FALSE(realm2_entry.IsEqualForTesting(*entry));
- // Confirm we find the same realm, different auth scheme by path lookup
- HttpAuthCache::Entry* p_realm3_digest_entry =
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey());
- EXPECT_TRUE(p_realm3_digest_entry);
- HttpAuthCache::Entry realm3_digest_entry = *p_realm3_digest_entry;
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/index.html");
- EXPECT_TRUE(realm3_digest_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/");
- EXPECT_TRUE(realm3_digest_entry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz");
- EXPECT_FALSE(realm3_digest_entry.IsEqualForTesting(*entry));
- // Confirm we find the same realm, different auth scheme by path lookup
- HttpAuthCache::Entry* p_realm3DigestEntry =
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey());
- EXPECT_TRUE(p_realm3DigestEntry);
- HttpAuthCache::Entry realm3DigestEntry = *p_realm3DigestEntry;
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/index.html");
- EXPECT_TRUE(realm3DigestEntry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/");
- EXPECT_TRUE(realm3DigestEntry.IsEqualForTesting(*entry));
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz");
- EXPECT_FALSE(realm3DigestEntry.IsEqualForTesting(*entry));
- // Lookup using empty path (may be used for proxy).
- entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), std::string());
- EXPECT_TRUE(entry);
- EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme());
- EXPECT_EQ(kRealm3, entry->realm());
- }
- // Make sure server and proxy credentials are treated separately.
- TEST(HttpAuthCacheTest, SeparateByTarget) {
- const std::u16string kServerUser = u"server_user";
- const std::u16string kServerPass = u"server_pass";
- const std::u16string kProxyUser = u"proxy_user";
- const std::u16string kProxyPass = u"proxy_pass";
- const char kServerPath[] = "/foo/bar/index.html";
- url::SchemeHostPort scheme_host_port(GURL("http://www.google.com"));
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- HttpAuthCache::Entry* entry;
- // Add AUTH_SERVER entry.
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "Basic realm=Realm1", AuthCredentials(kServerUser, kServerPass),
- kServerPath);
- // Make sure credentials are only accessible with AUTH_SERVER target.
- entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kServerUser);
- EXPECT_EQ(entry->credentials().password(), kServerPass);
- EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), kServerPath));
- EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
- NetworkIsolationKey(), kServerPath));
- // Add AUTH_PROXY entry with same SchemeHostPort and realm but different
- // credentials.
- cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "Basic realm=Realm1", AuthCredentials(kProxyUser, kProxyPass), "/");
- // Make sure credentials are only accessible with the corresponding target.
- entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kServerUser);
- EXPECT_EQ(entry->credentials().password(), kServerPass);
- EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), kServerPath));
- entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kProxyUser);
- EXPECT_EQ(entry->credentials().password(), kProxyPass);
- EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
- NetworkIsolationKey(), "/"));
- // Remove the AUTH_SERVER entry.
- EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kServerUser, kServerPass)));
- // Verify that only the AUTH_SERVER entry was removed.
- EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), kServerPath));
- entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kProxyUser);
- EXPECT_EQ(entry->credentials().password(), kProxyPass);
- EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
- NetworkIsolationKey(), "/"));
- // Remove the AUTH_PROXY entry.
- EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kProxyUser, kProxyPass)));
- // Verify that neither entry remains.
- EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), kServerPath));
- EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
- NetworkIsolationKey(), "/"));
- }
- // Make sure server credentials with different NetworkIsolationKeys are treated
- // separately if |key_entries_by_network_isolation_key| is set to true.
- TEST(HttpAuthCacheTest, SeparateServersByNetworkIsolationKey) {
- const SchemefulSite kSite1(GURL("https://foo.test/"));
- const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
- const SchemefulSite kSite2(GURL("https://bar.test/"));
- const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
- url::SchemeHostPort kSchemeHostPort(GURL("http://www.google.com"));
- const char kPath[] = "/";
- const std::u16string kUser1 = u"user1";
- const std::u16string kPass1 = u"pass1";
- const std::u16string kUser2 = u"user2";
- const std::u16string kPass2 = u"pass2";
- for (bool key_entries_by_network_isolation_key : {false, true}) {
- HttpAuthCache cache(key_entries_by_network_isolation_key);
- HttpAuthCache::Entry* entry;
- // Add entry for kNetworkIsolationKey1.
- cache.Add(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1,
- "Basic realm=Realm1", AuthCredentials(kUser1, kPass1), kPath);
- entry = cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kUser1);
- EXPECT_EQ(entry->credentials().password(), kPass1);
- EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey1, kPath));
- if (key_entries_by_network_isolation_key) {
- EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- kNetworkIsolationKey2));
- EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey2, kPath));
- } else {
- EXPECT_EQ(entry, cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
- kNetworkIsolationKey2));
- EXPECT_EQ(entry,
- cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey2, kPath));
- }
- // Add entry for kNetworkIsolationKey2.
- cache.Add(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2,
- "Basic realm=Realm1", AuthCredentials(kUser2, kPass2), kPath);
- entry = cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2);
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kUser2);
- EXPECT_EQ(entry->credentials().password(), kPass2);
- EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey2, kPath));
- entry = cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey1, kPath));
- if (key_entries_by_network_isolation_key) {
- EXPECT_EQ(entry->credentials().username(), kUser1);
- EXPECT_EQ(entry->credentials().password(), kPass1);
- } else {
- EXPECT_EQ(entry->credentials().username(), kUser2);
- EXPECT_EQ(entry->credentials().password(), kPass2);
- }
- // Remove the entry that was just added.
- EXPECT_TRUE(cache.Remove(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2,
- AuthCredentials(kUser2, kPass2)));
- EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- kNetworkIsolationKey2));
- EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey2, kPath));
- if (key_entries_by_network_isolation_key) {
- entry = cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kUser1);
- EXPECT_EQ(entry->credentials().password(), kPass1);
- EXPECT_EQ(entry,
- cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey1, kPath));
- } else {
- EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- kNetworkIsolationKey1));
- EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- kNetworkIsolationKey1, kPath));
- }
- }
- }
- // Make sure added proxy credentials ignore NetworkIsolationKey, even if if
- // |key_entries_by_network_isolation_key| is set to true.
- TEST(HttpAuthCacheTest, NeverSeparateProxiesByNetworkIsolationKey) {
- const SchemefulSite kSite1(GURL("https://foo.test/"));
- const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
- const SchemefulSite kSite2(GURL("https://bar.test/"));
- const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
- url::SchemeHostPort kSchemeHostPort(GURL("http://www.google.com"));
- const char kPath[] = "/";
- const std::u16string kUser1 = u"user1";
- const std::u16string kPass1 = u"pass1";
- const std::u16string kUser2 = u"user2";
- const std::u16string kPass2 = u"pass2";
- for (bool key_entries_by_network_isolation_key : {false, true}) {
- HttpAuthCache cache(key_entries_by_network_isolation_key);
- HttpAuthCache::Entry* entry;
- // Add entry for kNetworkIsolationKey1.
- cache.Add(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1,
- "Basic realm=Realm1", AuthCredentials(kUser1, kPass1), kPath);
- entry = cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kUser1);
- EXPECT_EQ(entry->credentials().password(), kPass1);
- EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
- kNetworkIsolationKey1, kPath));
- EXPECT_EQ(entry,
- cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2));
- EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
- kNetworkIsolationKey2, kPath));
- // Add entry for kNetworkIsolationKey2. It should overwrite the entry for
- // kNetworkIsolationKey1.
- cache.Add(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2,
- "Basic realm=Realm1", AuthCredentials(kUser2, kPass2), kPath);
- entry = cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2);
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kUser2);
- EXPECT_EQ(entry->credentials().password(), kPass2);
- EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
- kNetworkIsolationKey2, kPath));
- EXPECT_EQ(entry,
- cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1));
- EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
- kNetworkIsolationKey1, kPath));
- // Remove the entry that was just added using an empty NetworkIsolationKey.
- EXPECT_TRUE(cache.Remove(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kUser2, kPass2)));
- EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- kNetworkIsolationKey2));
- EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
- kNetworkIsolationKey2, kPath));
- EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- kNetworkIsolationKey1));
- EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
- kNetworkIsolationKey1, kPath));
- }
- }
- // Test that SetKeyServerEntriesByNetworkIsolationKey() deletes server
- // credentials when it toggles the setting. This test uses an empty
- // NetworkIsolationKey() for all entries, as the interesting part of this method
- // is what type entries are deleted, which doesn't depend on the
- // NetworkIsolationKey the entries use.
- TEST(HttpAuthCacheTest, SetKeyServerEntriesByNetworkIsolationKey) {
- const url::SchemeHostPort kSchemeHostPort(GURL("http://www.google.com"));
- const char kPath[] = "/";
- const std::u16string kUser1 = u"user1";
- const std::u16string kPass1 = u"pass1";
- const std::u16string kUser2 = u"user2";
- const std::u16string kPass2 = u"pass2";
- for (bool initially_key_entries_by_network_isolation_key : {false, true}) {
- for (bool to_key_entries_by_network_isolation_key : {false, true}) {
- HttpAuthCache cache(initially_key_entries_by_network_isolation_key);
- EXPECT_EQ(initially_key_entries_by_network_isolation_key,
- cache.key_server_entries_by_network_isolation_key());
- cache.Add(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "Basic realm=Realm1", AuthCredentials(kUser1, kPass1), kPath);
- cache.Add(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "Basic realm=Realm1", AuthCredentials(kUser2, kPass2), kPath);
- EXPECT_TRUE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- EXPECT_TRUE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- cache.SetKeyServerEntriesByNetworkIsolationKey(
- to_key_entries_by_network_isolation_key);
- EXPECT_EQ(to_key_entries_by_network_isolation_key,
- cache.key_server_entries_by_network_isolation_key());
- // AUTH_PROXY credentials should always remain in the cache.
- HttpAuthCache::Entry* entry = cache.LookupByPath(
- kSchemeHostPort, HttpAuth::AUTH_PROXY, NetworkIsolationKey(), kPath);
- ASSERT_TRUE(entry);
- EXPECT_EQ(entry->credentials().username(), kUser1);
- EXPECT_EQ(entry->credentials().password(), kPass1);
- entry = cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), kPath);
- // AUTH_SERVER credentials should only remain in the cache if the proxy
- // configuration changes.
- EXPECT_EQ(initially_key_entries_by_network_isolation_key ==
- to_key_entries_by_network_isolation_key,
- !!entry);
- if (entry) {
- EXPECT_EQ(entry->credentials().username(), kUser2);
- EXPECT_EQ(entry->credentials().password(), kPass2);
- }
- }
- }
- }
- TEST(HttpAuthCacheTest, AddPath) {
- HttpAuthCache::Entry entry;
- // All of these paths have a common root /1/2/2/4/5/
- entry.AddPath("/1/2/3/4/5/x.txt");
- entry.AddPath("/1/2/3/4/5/y.txt");
- entry.AddPath("/1/2/3/4/5/z.txt");
- EXPECT_EQ(1U, entry.paths_.size());
- EXPECT_EQ("/1/2/3/4/5/", entry.paths_.front());
- // Add a new entry (not a subpath).
- entry.AddPath("/1/XXX/q");
- EXPECT_EQ(2U, entry.paths_.size());
- EXPECT_EQ("/1/XXX/", entry.paths_.front());
- EXPECT_EQ("/1/2/3/4/5/", entry.paths_.back());
- // Add containing paths of /1/2/3/4/5/ -- should swallow up the deeper paths.
- entry.AddPath("/1/2/3/4/x.txt");
- EXPECT_EQ(2U, entry.paths_.size());
- EXPECT_EQ("/1/2/3/4/", entry.paths_.front());
- EXPECT_EQ("/1/XXX/", entry.paths_.back());
- entry.AddPath("/1/2/3/x");
- EXPECT_EQ(2U, entry.paths_.size());
- EXPECT_EQ("/1/2/3/", entry.paths_.front());
- EXPECT_EQ("/1/XXX/", entry.paths_.back());
- entry.AddPath("/index.html");
- EXPECT_EQ(1U, entry.paths_.size());
- EXPECT_EQ("/", entry.paths_.front());
- }
- // Calling Add when the realm entry already exists, should append that
- // path.
- TEST(HttpAuthCacheTest, AddToExistingEntry) {
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- url::SchemeHostPort scheme_host_port(GURL("http://www.foobar.com:70"));
- const std::string kAuthChallenge = "Basic realm=MyRealm";
- const std::string kRealm = "MyRealm";
- HttpAuthCache::Entry* orig_entry = cache.Add(
- scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(), kAuthChallenge,
- CreateASCIICredentials("user1", "password1"), "/x/y/z/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(), kAuthChallenge,
- CreateASCIICredentials("user2", "password2"), "/z/y/x/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(), kAuthChallenge,
- CreateASCIICredentials("user3", "password3"), "/z/y");
- HttpAuthCache::Entry* entry =
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- EXPECT_TRUE(entry == orig_entry);
- EXPECT_EQ(u"user3", entry->credentials().username());
- EXPECT_EQ(u"password3", entry->credentials().password());
- EXPECT_EQ(2U, entry->paths_.size());
- EXPECT_EQ("/z/", entry->paths_.front());
- EXPECT_EQ("/x/y/z/", entry->paths_.back());
- }
- TEST(HttpAuthCacheTest, Remove) {
- url::SchemeHostPort scheme_host_port(GURL("http://foobar2.com"));
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", CreateASCIICredentials("bob", "princess"),
- "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm3", AuthCredentials(kAdmin, kPassword), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/");
- // Fails, because there is no realm "Realm5".
- EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm5,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kAlice, k123)));
- // Fails because the origin is wrong.
- EXPECT_FALSE(cache.Remove(url::SchemeHostPort(GURL("http://foobar2.com:100")),
- HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kAlice, k123)));
- // Fails because the username is wrong.
- EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kAlice2, k123)));
- // Fails because the password is wrong.
- EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kAlice, k1234)));
- // Fails because the authentication type is wrong.
- EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- AuthCredentials(kAlice, k123)));
- // Succeeds.
- EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kAlice, k123)));
- // Fails because we just deleted the entry!
- EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kAlice, k123)));
- // Succeed when there are two authentication types for the same origin,realm.
- EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- AuthCredentials(kRoot, kWileCoyote)));
- // Succeed as above, but when entries were added in opposite order
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/");
- EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- AuthCredentials(kAdmin, kPassword)));
- // Make sure that removing one entry still leaves the other available for
- // lookup.
- HttpAuthCache::Entry* entry =
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey());
- EXPECT_FALSE(nullptr == entry);
- }
- TEST(HttpAuthCacheTest, ClearEntriesAddedBetween) {
- url::SchemeHostPort scheme_host_port(GURL("http://foobar.com"));
- base::Time start_time;
- ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:00", &start_time));
- base::SimpleTestClock test_clock;
- test_clock.SetNow(start_time);
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- cache.set_clock_for_testing(&test_clock);
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", AuthCredentials(kRoot, kWileCoyote), "/");
- test_clock.Advance(base::Seconds(10)); // Time now 12:00:10
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm3", AuthCredentials(kAlice2, k1234), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm4", AuthCredentials(kUsername, kPassword), "/");
- // Add path to existing entry.
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", AuthCredentials(kAdmin, kPassword), "/baz/");
- test_clock.Advance(base::Seconds(10)); // Time now 12:00:20
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm5,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm5", AuthCredentials(kAlice3, k12345), "/");
- base::Time test_time1;
- ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:05", &test_time1));
- base::Time test_time2;
- ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:15", &test_time2));
- cache.ClearEntriesAddedBetween(test_time1, test_time2);
- // Realms 1 and 2 are older than 12:00:05 and should not be cleared
- EXPECT_NE(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_NE(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- // Realms 5 is newer than 12:00:15 and should not be cleared
- EXPECT_NE(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm5,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- // Creation time is set for a whole entry rather than for a particular path.
- // Path added within the requested duration isn't be removed.
- EXPECT_NE(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/"));
- // Realms 3 and 4 are between 12:00:05 and 12:00:10 and should be cleared.
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- cache.ClearEntriesAddedBetween(start_time - base::Seconds(1),
- base::Time::Max());
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/"));
- }
- TEST(HttpAuthCacheTest, ClearEntriesAddedBetweenWithAllTimeValues) {
- url::SchemeHostPort scheme_host_port(GURL("http://foobar.com"));
- base::SimpleTestClock test_clock;
- test_clock.SetNow(base::Time::Now());
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- cache.set_clock_for_testing(&test_clock);
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", AuthCredentials(kRoot, kWileCoyote), "/");
- test_clock.Advance(base::Seconds(10));
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm3", AuthCredentials(kAlice2, k1234), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm4", AuthCredentials(kUsername, kPassword), "/");
- // Add path to existing entry.
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", AuthCredentials(kAdmin, kPassword), "/baz/");
- cache.ClearEntriesAddedBetween(base::Time::Min(), base::Time::Max());
- // All entries should be cleared.
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/"));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- }
- TEST(HttpAuthCacheTest, ClearAllEntries) {
- url::SchemeHostPort scheme_host_port(GURL("http://foobar.com"));
- base::SimpleTestClock test_clock;
- test_clock.SetNow(base::Time::Now());
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- cache.set_clock_for_testing(&test_clock);
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", AuthCredentials(kRoot, kWileCoyote), "/");
- test_clock.Advance(base::Seconds(10));
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm3", AuthCredentials(kAlice2, k1234), "/");
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm4", AuthCredentials(kUsername, kPassword), "/");
- // Add path to existing entry.
- cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", AuthCredentials(kAdmin, kPassword), "/baz/");
- test_clock.Advance(base::Seconds(55));
- cache.ClearAllEntries();
- // All entries should be cleared.
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
- NetworkIsolationKey(), "/baz/"));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- EXPECT_EQ(nullptr,
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey()));
- }
- TEST(HttpAuthCacheTest, UpdateStaleChallenge) {
- HttpAuthCache cache(false /* key_entries_by_network_isolation_key */);
- url::SchemeHostPort scheme_host_port(GURL("http://foobar2.com"));
- HttpAuthCache::Entry* entry_pre = cache.Add(
- scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "Digest realm=Realm1,"
- "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\"",
- CreateASCIICredentials("realm-digest-user", "realm-digest-password"),
- "/baz/index.html");
- ASSERT_TRUE(entry_pre != nullptr);
- EXPECT_EQ(2, entry_pre->IncrementNonceCount());
- EXPECT_EQ(3, entry_pre->IncrementNonceCount());
- EXPECT_EQ(4, entry_pre->IncrementNonceCount());
- bool update_success = cache.UpdateStaleChallenge(
- scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "Digest realm=Realm1,"
- "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\","
- "stale=\"true\"");
- EXPECT_TRUE(update_success);
- // After the stale update, the entry should still exist in the cache and
- // the nonce count should be reset to 0.
- HttpAuthCache::Entry* entry_post =
- cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey());
- ASSERT_TRUE(entry_post != nullptr);
- EXPECT_EQ(2, entry_post->IncrementNonceCount());
- // UpdateStaleChallenge will fail if an entry doesn't exist in the cache.
- bool update_failure = cache.UpdateStaleChallenge(
- scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "Digest realm=Realm2,"
- "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\","
- "stale=\"true\"");
- EXPECT_FALSE(update_failure);
- }
- TEST(HttpAuthCacheTest, CopyProxyEntriesFrom) {
- url::SchemeHostPort scheme_host_port(GURL("http://example.com"));
- std::string path("/some/path");
- std::string another_path("/another/path");
- HttpAuthCache first_cache(false /* key_entries_by_network_isolation_key */);
- HttpAuthCache::Entry* entry;
- first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm1", AuthCredentials(kAlice, k123), path);
- first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm2", AuthCredentials(kAlice2, k1234), path);
- first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote),
- path);
- entry = first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "digest realm=Realm3",
- AuthCredentials(kRoot, kWileCoyote), another_path);
- EXPECT_EQ(2, entry->IncrementNonceCount());
- // Server entry, which should not be copied.
- first_cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm1", AuthCredentials(kAlice, k123), path);
- HttpAuthCache second_cache(false /* key_entries_by_network_isolation_key */);
- // Will be overwritten by kRoot:kWileCoyote.
- second_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey(),
- "digest realm=Realm3", AuthCredentials(kAlice2, k1234),
- path);
- // Should be left intact.
- second_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- "basic realm=Realm4", AuthCredentials(kAdmin, kRoot), path);
- second_cache.CopyProxyEntriesFrom(first_cache);
- // Copied from first_cache.
- entry =
- second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- EXPECT_TRUE(nullptr != entry);
- EXPECT_EQ(kAlice, entry->credentials().username());
- EXPECT_EQ(k123, entry->credentials().password());
- // Copied from first_cache.
- entry =
- second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm2,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- EXPECT_TRUE(nullptr != entry);
- EXPECT_EQ(kAlice2, entry->credentials().username());
- EXPECT_EQ(k1234, entry->credentials().password());
- // Overwritten from first_cache.
- entry =
- second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
- HttpAuth::AUTH_SCHEME_DIGEST, NetworkIsolationKey());
- EXPECT_TRUE(nullptr != entry);
- EXPECT_EQ(kRoot, entry->credentials().username());
- EXPECT_EQ(kWileCoyote, entry->credentials().password());
- // Nonce count should get copied.
- EXPECT_EQ(3, entry->IncrementNonceCount());
- // All paths should get copied.
- entry = second_cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
- NetworkIsolationKey(), another_path);
- EXPECT_TRUE(nullptr != entry);
- EXPECT_EQ(kRoot, entry->credentials().username());
- EXPECT_EQ(kWileCoyote, entry->credentials().password());
- // Left intact in second_cache.
- entry =
- second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm4,
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- EXPECT_TRUE(nullptr != entry);
- EXPECT_EQ(kAdmin, entry->credentials().username());
- EXPECT_EQ(kRoot, entry->credentials().password());
- // AUTH_SERVER entry should not have been copied from first_cache.
- EXPECT_TRUE(first_cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
- kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- EXPECT_FALSE(second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
- kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
- NetworkIsolationKey()));
- }
- // Test fixture class for eviction tests (contains helpers for bulk
- // insertion and existence testing).
- class HttpAuthCacheEvictionTest : public testing::Test {
- protected:
- HttpAuthCacheEvictionTest()
- : scheme_host_port_(GURL("http://www.google.com")),
- cache_(false /* key_entries_by_network_isolation_key */) {}
- std::string GenerateRealm(int realm_i) {
- return base::StringPrintf("Realm %d", realm_i);
- }
- std::string GeneratePath(int realm_i, int path_i) {
- return base::StringPrintf("/%d/%d/x/y", realm_i, path_i);
- }
- void AddRealm(int realm_i) {
- AddPathToRealm(realm_i, 0);
- }
- void AddPathToRealm(int realm_i, int path_i) {
- cache_.Add(scheme_host_port_, HttpAuth::AUTH_SERVER, GenerateRealm(realm_i),
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
- std::string(), AuthCredentials(kUsername, kPassword),
- GeneratePath(realm_i, path_i));
- }
- void CheckRealmExistence(int realm_i, bool exists) {
- const HttpAuthCache::Entry* entry = cache_.Lookup(
- scheme_host_port_, HttpAuth::AUTH_SERVER, GenerateRealm(realm_i),
- HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
- if (exists) {
- EXPECT_FALSE(entry == nullptr);
- EXPECT_EQ(GenerateRealm(realm_i), entry->realm());
- } else {
- EXPECT_TRUE(entry == nullptr);
- }
- }
- void CheckPathExistence(int realm_i, int path_i, bool exists) {
- const HttpAuthCache::Entry* entry = cache_.LookupByPath(
- scheme_host_port_, HttpAuth::AUTH_SERVER, NetworkIsolationKey(),
- GeneratePath(realm_i, path_i));
- if (exists) {
- EXPECT_FALSE(entry == nullptr);
- EXPECT_EQ(GenerateRealm(realm_i), entry->realm());
- } else {
- EXPECT_TRUE(entry == nullptr);
- }
- }
- url::SchemeHostPort scheme_host_port_;
- HttpAuthCache cache_;
- static const int kMaxPaths = HttpAuthCache::kMaxNumPathsPerRealmEntry;
- static const int kMaxRealms = HttpAuthCache::kMaxNumRealmEntries;
- };
- // Add the maxinim number of realm entries to the cache. Each of these entries
- // must still be retrievable. Next add three more entries -- since the cache is
- // full this causes FIFO eviction of the first three entries by time of last
- // use.
- TEST_F(HttpAuthCacheEvictionTest, RealmEntryEviction) {
- base::SimpleTestTickClock test_clock;
- test_clock.SetNowTicks(base::TimeTicks::Now());
- cache_.set_tick_clock_for_testing(&test_clock);
- for (int i = 0; i < kMaxRealms; ++i) {
- AddRealm(i);
- test_clock.Advance(base::Seconds(1));
- }
- for (int i = 0; i < kMaxRealms; ++i) {
- CheckRealmExistence(i, true);
- test_clock.Advance(base::Seconds(1));
- }
- for (int i = 0; i < 3; ++i) {
- AddRealm(i + kMaxRealms);
- test_clock.Advance(base::Seconds(1));
- }
- for (int i = 0; i < 3; ++i) {
- CheckRealmExistence(i, false);
- test_clock.Advance(base::Seconds(1));
- }
- for (int i = 0; i < kMaxRealms; ++i) {
- CheckRealmExistence(i + 3, true);
- test_clock.Advance(base::Seconds(1));
- }
- }
- // Add the maximum number of paths to a single realm entry. Each of these
- // paths should be retrievable. Next add 3 more paths -- since the cache is
- // full this causes FIFO eviction of the first three paths.
- TEST_F(HttpAuthCacheEvictionTest, RealmPathEviction) {
- for (int i = 0; i < kMaxPaths; ++i)
- AddPathToRealm(0, i);
- for (int i = 1; i < kMaxRealms; ++i)
- AddRealm(i);
- for (int i = 0; i < 3; ++i)
- AddPathToRealm(0, i + kMaxPaths);
- for (int i = 0; i < 3; ++i)
- CheckPathExistence(0, i, false);
- for (int i = 0; i < kMaxPaths; ++i)
- CheckPathExistence(0, i + 3, true);
- for (int i = 0; i < kMaxRealms; ++i)
- CheckRealmExistence(i, true);
- }
- } // namespace net
|