• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string>
6 
7 #include "base/strings/string_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/test/simple_test_clock.h"
11 #include "base/test/simple_test_tick_clock.h"
12 #include "base/time/time.h"
13 #include "net/base/net_errors.h"
14 #include "net/base/network_anonymization_key.h"
15 #include "net/base/schemeful_site.h"
16 #include "net/http/http_auth_cache.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "url/gurl.h"
19 #include "url/scheme_host_port.h"
20 
21 using base::ASCIIToUTF16;
22 
23 namespace net {
24 
25 namespace {
26 
27 const char kRealm1[] = "Realm1";
28 const char kRealm2[] = "Realm2";
29 const char kRealm3[] = "Realm3";
30 const char kRealm4[] = "Realm4";
31 const char kRealm5[] = "Realm5";
32 const std::u16string k123(u"123");
33 const std::u16string k1234(u"1234");
34 const std::u16string k12345(u"12345");
35 const std::u16string kAdmin(u"admin");
36 const std::u16string kAlice(u"alice");
37 const std::u16string kAlice2(u"alice2");
38 const std::u16string kAlice3(u"alice3");
39 const std::u16string kPassword(u"password");
40 const std::u16string kRoot(u"root");
41 const std::u16string kUsername(u"username");
42 const std::u16string kWileCoyote(u"wilecoyote");
43 
CreateASCIICredentials(const char * username,const char * password)44 AuthCredentials CreateASCIICredentials(const char* username,
45                                        const char* password) {
46   return AuthCredentials(ASCIIToUTF16(username), ASCIIToUTF16(password));
47 }
48 
49 }  // namespace
50 
51 // Test adding and looking-up cache entries (both by realm and by path).
TEST(HttpAuthCacheTest,Basic)52 TEST(HttpAuthCacheTest, Basic) {
53   url::SchemeHostPort scheme_host_port(GURL("http://www.google.com"));
54   url::SchemeHostPort scheme_host_port2(GURL("http://www.foobar.com"));
55   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
56   HttpAuthCache::Entry* entry;
57 
58   // Add cache entries for 4 realms: "Realm1", "Realm2", "Realm3" and
59   // "Realm4"
60 
61   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
62             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
63             "Basic realm=Realm1",
64             CreateASCIICredentials("realm1-user", "realm1-password"),
65             "/foo/bar/index.html");
66 
67   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
68             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
69             "Basic realm=Realm2",
70             CreateASCIICredentials("realm2-user", "realm2-password"),
71             "/foo2/index.html");
72 
73   cache.Add(
74       scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
75       HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
76       "Basic realm=Realm3",
77       CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"),
78       std::string());
79 
80   cache.Add(
81       scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
82       HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
83       "Digest realm=Realm3",
84       CreateASCIICredentials("realm3-digest-user", "realm3-digest-password"),
85       "/baz/index.html");
86 
87   cache.Add(
88       scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
89       HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
90       "Basic realm=Realm4",
91       CreateASCIICredentials("realm4-basic-user", "realm4-basic-password"),
92       "/");
93 
94   cache.Add(scheme_host_port2, HttpAuth::AUTH_SERVER, kRealm5,
95             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
96             "Basic realm=Realm5",
97             CreateASCIICredentials("realm5-user", "realm5-password"), "/");
98   cache.Add(
99       scheme_host_port2, HttpAuth::AUTH_SERVER, kRealm3,
100       HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
101       "Basic realm=Realm3",
102       CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"),
103       std::string());
104 
105   // There is no Realm5 in `scheme_host_port`.
106   entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm5,
107                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
108   EXPECT_FALSE(entry);
109 
110   // While Realm3 does exist, the scheme is wrong.
111   entry = cache.Lookup(url::SchemeHostPort(GURL("https://www.google.com")),
112                        HttpAuth::AUTH_SERVER, kRealm3,
113                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
114   EXPECT_FALSE(entry);
115 
116   // Realm, scheme ok, authentication scheme wrong
117   entry = cache.Lookup(url::SchemeHostPort(GURL("https://www.google.com")),
118                        HttpAuth::AUTH_SERVER, kRealm1,
119                        HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey());
120   EXPECT_FALSE(entry);
121 
122   // Valid lookup by SchemeHostPort, realm, scheme.
123   entry = cache.Lookup(url::SchemeHostPort(GURL("http://www.google.com:80")),
124                        HttpAuth::AUTH_SERVER, kRealm3,
125                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
126   ASSERT_TRUE(entry);
127   EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme());
128   EXPECT_EQ(kRealm3, entry->realm());
129   EXPECT_EQ("Basic realm=Realm3", entry->auth_challenge());
130   EXPECT_EQ(u"realm3-basic-user", entry->credentials().username());
131   EXPECT_EQ(u"realm3-basic-password", entry->credentials().password());
132 
133   // Same realm, scheme with different SchemeHostPorts.
134   HttpAuthCache::Entry* entry2 =
135       cache.Lookup(url::SchemeHostPort(GURL("http://www.foobar.com:80")),
136                    HttpAuth::AUTH_SERVER, kRealm3, HttpAuth::AUTH_SCHEME_BASIC,
137                    NetworkAnonymizationKey());
138   ASSERT_TRUE(entry2);
139   EXPECT_NE(entry, entry2);
140 
141   // Valid lookup by SchemeHostPort, realm, scheme when there's a duplicate
142   // SchemeHostPort, realm in the cache.
143   entry = cache.Lookup(url::SchemeHostPort(GURL("http://www.google.com:80")),
144                        HttpAuth::AUTH_SERVER, kRealm3,
145                        HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey());
146   ASSERT_TRUE(entry);
147   EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST, entry->scheme());
148   EXPECT_EQ(kRealm3, entry->realm());
149   EXPECT_EQ("Digest realm=Realm3", entry->auth_challenge());
150   EXPECT_EQ(u"realm3-digest-user", entry->credentials().username());
151   EXPECT_EQ(u"realm3-digest-password", entry->credentials().password());
152 
153   // Valid lookup by realm.
154   entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
155                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
156   ASSERT_TRUE(entry);
157   EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme());
158   EXPECT_EQ(kRealm2, entry->realm());
159   EXPECT_EQ("Basic realm=Realm2", entry->auth_challenge());
160   EXPECT_EQ(u"realm2-user", entry->credentials().username());
161   EXPECT_EQ(u"realm2-password", entry->credentials().password());
162 
163   // Check that subpaths are recognized.
164   HttpAuthCache::Entry* p_realm2_entry =
165       cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
166                    HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
167   HttpAuthCache::Entry* p_realm4_entry =
168       cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
169                    HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
170   EXPECT_TRUE(p_realm2_entry);
171   EXPECT_TRUE(p_realm4_entry);
172   HttpAuthCache::Entry realm2_entry = *p_realm2_entry;
173   HttpAuthCache::Entry realm4_entry = *p_realm4_entry;
174   // Realm4 applies to '/' and Realm2 applies to '/foo2/'.
175   // LookupByPath() should return the closest enclosing path.
176   // Positive tests:
177   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
178                              NetworkAnonymizationKey(), "/foo2/index.html");
179   EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
180   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
181                              NetworkAnonymizationKey(), "/foo2/foobar.html");
182   EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
183   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
184                              NetworkAnonymizationKey(), "/foo2/bar/index.html");
185   EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
186   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
187                              NetworkAnonymizationKey(), "/foo2/");
188   EXPECT_TRUE(realm2_entry.IsEqualForTesting(*entry));
189   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
190                              NetworkAnonymizationKey(), "/foo2");
191   EXPECT_TRUE(realm4_entry.IsEqualForTesting(*entry));
192   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
193                              NetworkAnonymizationKey(), "/");
194   EXPECT_TRUE(realm4_entry.IsEqualForTesting(*entry));
195 
196   // Negative tests:
197   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
198                              NetworkAnonymizationKey(), "/foo3/index.html");
199   EXPECT_FALSE(realm2_entry.IsEqualForTesting(*entry));
200   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
201                              NetworkAnonymizationKey(), std::string());
202   EXPECT_FALSE(realm2_entry.IsEqualForTesting(*entry));
203 
204   // Confirm we find the same realm, different auth scheme by path lookup
205   HttpAuthCache::Entry* p_realm3_digest_entry =
206       cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
207                    HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey());
208   EXPECT_TRUE(p_realm3_digest_entry);
209   HttpAuthCache::Entry realm3_digest_entry = *p_realm3_digest_entry;
210   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
211                              NetworkAnonymizationKey(), "/baz/index.html");
212   EXPECT_TRUE(realm3_digest_entry.IsEqualForTesting(*entry));
213   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
214                              NetworkAnonymizationKey(), "/baz/");
215   EXPECT_TRUE(realm3_digest_entry.IsEqualForTesting(*entry));
216   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
217                              NetworkAnonymizationKey(), "/baz");
218   EXPECT_FALSE(realm3_digest_entry.IsEqualForTesting(*entry));
219 
220   // Confirm we find the same realm, different auth scheme by path lookup
221   HttpAuthCache::Entry* p_realm3DigestEntry =
222       cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
223                    HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey());
224   EXPECT_TRUE(p_realm3DigestEntry);
225   HttpAuthCache::Entry realm3DigestEntry = *p_realm3DigestEntry;
226   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
227                              NetworkAnonymizationKey(), "/baz/index.html");
228   EXPECT_TRUE(realm3DigestEntry.IsEqualForTesting(*entry));
229   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
230                              NetworkAnonymizationKey(), "/baz/");
231   EXPECT_TRUE(realm3DigestEntry.IsEqualForTesting(*entry));
232   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
233                              NetworkAnonymizationKey(), "/baz");
234   EXPECT_FALSE(realm3DigestEntry.IsEqualForTesting(*entry));
235 
236   // Lookup using empty path (may be used for proxy).
237   entry = cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
238                              NetworkAnonymizationKey(), std::string());
239   EXPECT_TRUE(entry);
240   EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme());
241   EXPECT_EQ(kRealm3, entry->realm());
242 }
243 
244 // Make sure server and proxy credentials are treated separately.
TEST(HttpAuthCacheTest,SeparateByTarget)245 TEST(HttpAuthCacheTest, SeparateByTarget) {
246   const std::u16string kServerUser = u"server_user";
247   const std::u16string kServerPass = u"server_pass";
248   const std::u16string kProxyUser = u"proxy_user";
249   const std::u16string kProxyPass = u"proxy_pass";
250 
251   const char kServerPath[] = "/foo/bar/index.html";
252 
253   url::SchemeHostPort scheme_host_port(GURL("http://www.google.com"));
254   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
255   HttpAuthCache::Entry* entry;
256 
257   // Add AUTH_SERVER entry.
258   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
259             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
260             "Basic realm=Realm1", AuthCredentials(kServerUser, kServerPass),
261             kServerPath);
262 
263   // Make sure credentials are only accessible with AUTH_SERVER target.
264   entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
265                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
266   ASSERT_TRUE(entry);
267   EXPECT_EQ(entry->credentials().username(), kServerUser);
268   EXPECT_EQ(entry->credentials().password(), kServerPass);
269   EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
270                                       NetworkAnonymizationKey(), kServerPath));
271   EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
272                             HttpAuth::AUTH_SCHEME_BASIC,
273                             NetworkAnonymizationKey()));
274   EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
275                                   NetworkAnonymizationKey(), kServerPath));
276 
277   // Add AUTH_PROXY entry with same SchemeHostPort and realm but different
278   // credentials.
279   cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
280             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
281             "Basic realm=Realm1", AuthCredentials(kProxyUser, kProxyPass), "/");
282 
283   // Make sure credentials are only accessible with the corresponding target.
284   entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
285                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
286   ASSERT_TRUE(entry);
287   EXPECT_EQ(entry->credentials().username(), kServerUser);
288   EXPECT_EQ(entry->credentials().password(), kServerPass);
289   EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
290                                       NetworkAnonymizationKey(), kServerPath));
291   entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
292                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
293   ASSERT_TRUE(entry);
294   EXPECT_EQ(entry->credentials().username(), kProxyUser);
295   EXPECT_EQ(entry->credentials().password(), kProxyPass);
296   EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
297                                       NetworkAnonymizationKey(), "/"));
298 
299   // Remove the AUTH_SERVER entry.
300   EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
301                            HttpAuth::AUTH_SCHEME_BASIC,
302                            NetworkAnonymizationKey(),
303                            AuthCredentials(kServerUser, kServerPass)));
304 
305   // Verify that only the AUTH_SERVER entry was removed.
306   EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
307                             HttpAuth::AUTH_SCHEME_BASIC,
308                             NetworkAnonymizationKey()));
309   EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
310                                   NetworkAnonymizationKey(), kServerPath));
311   entry = cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
312                        HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
313   ASSERT_TRUE(entry);
314   EXPECT_EQ(entry->credentials().username(), kProxyUser);
315   EXPECT_EQ(entry->credentials().password(), kProxyPass);
316   EXPECT_EQ(entry, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
317                                       NetworkAnonymizationKey(), "/"));
318 
319   // Remove the AUTH_PROXY entry.
320   EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
321                            HttpAuth::AUTH_SCHEME_BASIC,
322                            NetworkAnonymizationKey(),
323                            AuthCredentials(kProxyUser, kProxyPass)));
324 
325   // Verify that neither entry remains.
326   EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
327                             HttpAuth::AUTH_SCHEME_BASIC,
328                             NetworkAnonymizationKey()));
329   EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
330                                   NetworkAnonymizationKey(), kServerPath));
331   EXPECT_FALSE(cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
332                             HttpAuth::AUTH_SCHEME_BASIC,
333                             NetworkAnonymizationKey()));
334   EXPECT_FALSE(cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
335                                   NetworkAnonymizationKey(), "/"));
336 }
337 
338 // Make sure server credentials with different NetworkAnonymizationKeys are
339 // treated separately if |key_entries_by_network_anonymization_key| is set to
340 // true.
TEST(HttpAuthCacheTest,SeparateServersByNetworkAnonymizationKey)341 TEST(HttpAuthCacheTest, SeparateServersByNetworkAnonymizationKey) {
342   const SchemefulSite kSite1(GURL("https://foo.test/"));
343   auto kNetworkAnonymizationKey1 =
344       net::NetworkAnonymizationKey::CreateSameSite(kSite1);
345   const SchemefulSite kSite2(GURL("https://bar.test/"));
346   auto kNetworkAnonymizationKey2 =
347       net::NetworkAnonymizationKey::CreateSameSite(kSite2);
348 
349   url::SchemeHostPort kSchemeHostPort(GURL("http://www.google.com"));
350   const char kPath[] = "/";
351 
352   const std::u16string kUser1 = u"user1";
353   const std::u16string kPass1 = u"pass1";
354   const std::u16string kUser2 = u"user2";
355   const std::u16string kPass2 = u"pass2";
356 
357   for (bool key_entries_by_network_anonymization_key : {false, true}) {
358     HttpAuthCache cache(key_entries_by_network_anonymization_key);
359     HttpAuthCache::Entry* entry;
360 
361     // Add entry for kNetworkAnonymizationKey1.
362     cache.Add(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
363               HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1,
364               "Basic realm=Realm1", AuthCredentials(kUser1, kPass1), kPath);
365 
366     entry =
367         cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
368                      HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
369     ASSERT_TRUE(entry);
370     EXPECT_EQ(entry->credentials().username(), kUser1);
371     EXPECT_EQ(entry->credentials().password(), kPass1);
372     EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
373                                         kNetworkAnonymizationKey1, kPath));
374     if (key_entries_by_network_anonymization_key) {
375       EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
376                                 HttpAuth::AUTH_SCHEME_BASIC,
377                                 kNetworkAnonymizationKey2));
378       EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
379                                       kNetworkAnonymizationKey2, kPath));
380     } else {
381       EXPECT_EQ(entry, cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER,
382                                     kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
383                                     kNetworkAnonymizationKey2));
384       EXPECT_EQ(entry,
385                 cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
386                                    kNetworkAnonymizationKey2, kPath));
387     }
388 
389     // Add entry for kNetworkAnonymizationKey2.
390     cache.Add(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
391               HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2,
392               "Basic realm=Realm1", AuthCredentials(kUser2, kPass2), kPath);
393 
394     entry =
395         cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
396                      HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2);
397     ASSERT_TRUE(entry);
398     EXPECT_EQ(entry->credentials().username(), kUser2);
399     EXPECT_EQ(entry->credentials().password(), kPass2);
400     EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
401                                         kNetworkAnonymizationKey2, kPath));
402     entry =
403         cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
404                      HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
405     ASSERT_TRUE(entry);
406     EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
407                                         kNetworkAnonymizationKey1, kPath));
408     if (key_entries_by_network_anonymization_key) {
409       EXPECT_EQ(entry->credentials().username(), kUser1);
410       EXPECT_EQ(entry->credentials().password(), kPass1);
411     } else {
412       EXPECT_EQ(entry->credentials().username(), kUser2);
413       EXPECT_EQ(entry->credentials().password(), kPass2);
414     }
415 
416     // Remove the entry that was just added.
417     EXPECT_TRUE(cache.Remove(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
418                              HttpAuth::AUTH_SCHEME_BASIC,
419                              kNetworkAnonymizationKey2,
420                              AuthCredentials(kUser2, kPass2)));
421 
422     EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
423                               HttpAuth::AUTH_SCHEME_BASIC,
424                               kNetworkAnonymizationKey2));
425     EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
426                                     kNetworkAnonymizationKey2, kPath));
427     if (key_entries_by_network_anonymization_key) {
428       entry =
429           cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
430                        HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
431       ASSERT_TRUE(entry);
432       EXPECT_EQ(entry->credentials().username(), kUser1);
433       EXPECT_EQ(entry->credentials().password(), kPass1);
434       EXPECT_EQ(entry,
435                 cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
436                                    kNetworkAnonymizationKey1, kPath));
437     } else {
438       EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
439                                 HttpAuth::AUTH_SCHEME_BASIC,
440                                 kNetworkAnonymizationKey1));
441       EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
442                                       kNetworkAnonymizationKey1, kPath));
443     }
444   }
445 }
446 
447 // Make sure added proxy credentials ignore NetworkAnonymizationKey, even if if
448 // |key_entries_by_network_anonymization_key| is set to true.
TEST(HttpAuthCacheTest,NeverSeparateProxiesByNetworkAnonymizationKey)449 TEST(HttpAuthCacheTest, NeverSeparateProxiesByNetworkAnonymizationKey) {
450   const SchemefulSite kSite1(GURL("https://foo.test/"));
451   auto kNetworkAnonymizationKey1 =
452       net::NetworkAnonymizationKey::CreateSameSite(kSite1);
453   const SchemefulSite kSite2(GURL("https://bar.test/"));
454   auto kNetworkAnonymizationKey2 =
455       net::NetworkAnonymizationKey::CreateSameSite(kSite2);
456 
457   url::SchemeHostPort kSchemeHostPort(GURL("http://www.google.com"));
458   const char kPath[] = "/";
459 
460   const std::u16string kUser1 = u"user1";
461   const std::u16string kPass1 = u"pass1";
462   const std::u16string kUser2 = u"user2";
463   const std::u16string kPass2 = u"pass2";
464 
465   for (bool key_entries_by_network_anonymization_key : {false, true}) {
466     HttpAuthCache cache(key_entries_by_network_anonymization_key);
467     HttpAuthCache::Entry* entry;
468 
469     // Add entry for kNetworkAnonymizationKey1.
470     cache.Add(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
471               HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1,
472               "Basic realm=Realm1", AuthCredentials(kUser1, kPass1), kPath);
473 
474     entry =
475         cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
476                      HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
477     ASSERT_TRUE(entry);
478     EXPECT_EQ(entry->credentials().username(), kUser1);
479     EXPECT_EQ(entry->credentials().password(), kPass1);
480     EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
481                                         kNetworkAnonymizationKey1, kPath));
482     EXPECT_EQ(entry, cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY,
483                                   kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
484                                   kNetworkAnonymizationKey2));
485     EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
486                                         kNetworkAnonymizationKey2, kPath));
487 
488     // Add entry for kNetworkAnonymizationKey2. It should overwrite the entry
489     // for kNetworkAnonymizationKey1.
490     cache.Add(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
491               HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2,
492               "Basic realm=Realm1", AuthCredentials(kUser2, kPass2), kPath);
493 
494     entry =
495         cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
496                      HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2);
497     ASSERT_TRUE(entry);
498     EXPECT_EQ(entry->credentials().username(), kUser2);
499     EXPECT_EQ(entry->credentials().password(), kPass2);
500     EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
501                                         kNetworkAnonymizationKey2, kPath));
502     EXPECT_EQ(entry, cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY,
503                                   kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
504                                   kNetworkAnonymizationKey1));
505     EXPECT_EQ(entry, cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
506                                         kNetworkAnonymizationKey1, kPath));
507 
508     // Remove the entry that was just added using an empty
509     // NetworkAnonymizationKey.
510     EXPECT_TRUE(cache.Remove(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
511                              HttpAuth::AUTH_SCHEME_BASIC,
512                              NetworkAnonymizationKey(),
513                              AuthCredentials(kUser2, kPass2)));
514 
515     EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
516                               HttpAuth::AUTH_SCHEME_BASIC,
517                               kNetworkAnonymizationKey2));
518     EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
519                                     kNetworkAnonymizationKey2, kPath));
520     EXPECT_FALSE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
521                               HttpAuth::AUTH_SCHEME_BASIC,
522                               kNetworkAnonymizationKey1));
523     EXPECT_FALSE(cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
524                                     kNetworkAnonymizationKey1, kPath));
525   }
526 }
527 
528 // Test that SetKeyServerEntriesByNetworkAnonymizationKey() deletes server
529 // credentials when it toggles the setting. This test uses an empty
530 // NetworkAnonymizationKey() for all entries, as the interesting part of this
531 // method is what type entries are deleted, which doesn't depend on the
532 // NetworkAnonymizationKey the entries use.
TEST(HttpAuthCacheTest,SetKeyServerEntriesByNetworkAnonymizationKey)533 TEST(HttpAuthCacheTest, SetKeyServerEntriesByNetworkAnonymizationKey) {
534   const url::SchemeHostPort kSchemeHostPort(GURL("http://www.google.com"));
535   const char kPath[] = "/";
536 
537   const std::u16string kUser1 = u"user1";
538   const std::u16string kPass1 = u"pass1";
539   const std::u16string kUser2 = u"user2";
540   const std::u16string kPass2 = u"pass2";
541 
542   for (bool initially_key_entries_by_network_anonymization_key :
543        {false, true}) {
544     for (bool to_key_entries_by_network_anonymization_key : {false, true}) {
545       HttpAuthCache cache(initially_key_entries_by_network_anonymization_key);
546       EXPECT_EQ(initially_key_entries_by_network_anonymization_key,
547                 cache.key_server_entries_by_network_anonymization_key());
548 
549       cache.Add(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
550                 HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
551                 "Basic realm=Realm1", AuthCredentials(kUser1, kPass1), kPath);
552       cache.Add(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
553                 HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
554                 "Basic realm=Realm1", AuthCredentials(kUser2, kPass2), kPath);
555 
556       EXPECT_TRUE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_PROXY, kRealm1,
557                                HttpAuth::AUTH_SCHEME_BASIC,
558                                NetworkAnonymizationKey()));
559       EXPECT_TRUE(cache.Lookup(kSchemeHostPort, HttpAuth::AUTH_SERVER, kRealm1,
560                                HttpAuth::AUTH_SCHEME_BASIC,
561                                NetworkAnonymizationKey()));
562 
563       cache.SetKeyServerEntriesByNetworkAnonymizationKey(
564           to_key_entries_by_network_anonymization_key);
565       EXPECT_EQ(to_key_entries_by_network_anonymization_key,
566                 cache.key_server_entries_by_network_anonymization_key());
567 
568       // AUTH_PROXY credentials should always remain in the cache.
569       HttpAuthCache::Entry* entry =
570           cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_PROXY,
571                              NetworkAnonymizationKey(), kPath);
572       ASSERT_TRUE(entry);
573       EXPECT_EQ(entry->credentials().username(), kUser1);
574       EXPECT_EQ(entry->credentials().password(), kPass1);
575 
576       entry = cache.LookupByPath(kSchemeHostPort, HttpAuth::AUTH_SERVER,
577                                  NetworkAnonymizationKey(), kPath);
578       // AUTH_SERVER credentials should only remain in the cache if the proxy
579       // configuration changes.
580       EXPECT_EQ(initially_key_entries_by_network_anonymization_key ==
581                     to_key_entries_by_network_anonymization_key,
582                 !!entry);
583       if (entry) {
584         EXPECT_EQ(entry->credentials().username(), kUser2);
585         EXPECT_EQ(entry->credentials().password(), kPass2);
586       }
587     }
588   }
589 }
590 
TEST(HttpAuthCacheTest,AddPath)591 TEST(HttpAuthCacheTest, AddPath) {
592   HttpAuthCache::Entry entry;
593 
594   // All of these paths have a common root /1/2/2/4/5/
595   entry.AddPath("/1/2/3/4/5/x.txt");
596   entry.AddPath("/1/2/3/4/5/y.txt");
597   entry.AddPath("/1/2/3/4/5/z.txt");
598 
599   EXPECT_EQ(1U, entry.paths_.size());
600   EXPECT_EQ("/1/2/3/4/5/", entry.paths_.front());
601 
602   // Add a new entry (not a subpath).
603   entry.AddPath("/1/XXX/q");
604   EXPECT_EQ(2U, entry.paths_.size());
605   EXPECT_EQ("/1/XXX/", entry.paths_.front());
606   EXPECT_EQ("/1/2/3/4/5/", entry.paths_.back());
607 
608   // Add containing paths of /1/2/3/4/5/ -- should swallow up the deeper paths.
609   entry.AddPath("/1/2/3/4/x.txt");
610   EXPECT_EQ(2U, entry.paths_.size());
611   EXPECT_EQ("/1/2/3/4/", entry.paths_.front());
612   EXPECT_EQ("/1/XXX/", entry.paths_.back());
613   entry.AddPath("/1/2/3/x");
614   EXPECT_EQ(2U, entry.paths_.size());
615   EXPECT_EQ("/1/2/3/", entry.paths_.front());
616   EXPECT_EQ("/1/XXX/", entry.paths_.back());
617 
618   entry.AddPath("/index.html");
619   EXPECT_EQ(1U, entry.paths_.size());
620   EXPECT_EQ("/", entry.paths_.front());
621 }
622 
623 // Calling Add when the realm entry already exists, should append that
624 // path.
TEST(HttpAuthCacheTest,AddToExistingEntry)625 TEST(HttpAuthCacheTest, AddToExistingEntry) {
626   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
627   url::SchemeHostPort scheme_host_port(GURL("http://www.foobar.com:70"));
628   const std::string kAuthChallenge = "Basic realm=MyRealm";
629   const std::string kRealm = "MyRealm";
630 
631   HttpAuthCache::Entry* orig_entry = cache.Add(
632       scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
633       HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(), kAuthChallenge,
634       CreateASCIICredentials("user1", "password1"), "/x/y/z/");
635   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
636             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
637             kAuthChallenge, CreateASCIICredentials("user2", "password2"),
638             "/z/y/x/");
639   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
640             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
641             kAuthChallenge, CreateASCIICredentials("user3", "password3"),
642             "/z/y");
643 
644   HttpAuthCache::Entry* entry =
645       cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm,
646                    HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
647 
648   EXPECT_TRUE(entry == orig_entry);
649   EXPECT_EQ(u"user3", entry->credentials().username());
650   EXPECT_EQ(u"password3", entry->credentials().password());
651 
652   EXPECT_EQ(2U, entry->paths_.size());
653   EXPECT_EQ("/z/", entry->paths_.front());
654   EXPECT_EQ("/x/y/z/", entry->paths_.back());
655 }
656 
TEST(HttpAuthCacheTest,Remove)657 TEST(HttpAuthCacheTest, Remove) {
658   url::SchemeHostPort scheme_host_port(GURL("http://foobar2.com"));
659 
660   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
661   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
662             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
663             "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
664   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
665             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
666             "basic realm=Realm2", CreateASCIICredentials("bob", "princess"),
667             "/");
668   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
669             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
670             "basic realm=Realm3", AuthCredentials(kAdmin, kPassword), "/");
671   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
672             HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
673             "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/");
674 
675   // Fails, because there is no realm "Realm5".
676   EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm5,
677                             HttpAuth::AUTH_SCHEME_BASIC,
678                             NetworkAnonymizationKey(),
679                             AuthCredentials(kAlice, k123)));
680 
681   // Fails because the origin is wrong.
682   EXPECT_FALSE(
683       cache.Remove(url::SchemeHostPort(GURL("http://foobar2.com:100")),
684                    HttpAuth::AUTH_SERVER, kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
685                    NetworkAnonymizationKey(), AuthCredentials(kAlice, k123)));
686 
687   // Fails because the username is wrong.
688   EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
689                             HttpAuth::AUTH_SCHEME_BASIC,
690                             NetworkAnonymizationKey(),
691                             AuthCredentials(kAlice2, k123)));
692 
693   // Fails because the password is wrong.
694   EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
695                             HttpAuth::AUTH_SCHEME_BASIC,
696                             NetworkAnonymizationKey(),
697                             AuthCredentials(kAlice, k1234)));
698 
699   // Fails because the authentication type is wrong.
700   EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
701                             HttpAuth::AUTH_SCHEME_DIGEST,
702                             NetworkAnonymizationKey(),
703                             AuthCredentials(kAlice, k123)));
704 
705   // Succeeds.
706   EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
707                            HttpAuth::AUTH_SCHEME_BASIC,
708                            NetworkAnonymizationKey(),
709                            AuthCredentials(kAlice, k123)));
710 
711   // Fails because we just deleted the entry!
712   EXPECT_FALSE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
713                             HttpAuth::AUTH_SCHEME_BASIC,
714                             NetworkAnonymizationKey(),
715                             AuthCredentials(kAlice, k123)));
716 
717   // Succeed when there are two authentication types for the same origin,realm.
718   EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
719                            HttpAuth::AUTH_SCHEME_DIGEST,
720                            NetworkAnonymizationKey(),
721                            AuthCredentials(kRoot, kWileCoyote)));
722 
723   // Succeed as above, but when entries were added in opposite order
724   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
725             HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
726             "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/");
727   EXPECT_TRUE(cache.Remove(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
728                            HttpAuth::AUTH_SCHEME_BASIC,
729                            NetworkAnonymizationKey(),
730                            AuthCredentials(kAdmin, kPassword)));
731 
732   // Make sure that removing one entry still leaves the other available for
733   // lookup.
734   HttpAuthCache::Entry* entry =
735       cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
736                    HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey());
737   EXPECT_FALSE(nullptr == entry);
738 }
739 
TEST(HttpAuthCacheTest,ClearEntriesAddedBetween)740 TEST(HttpAuthCacheTest, ClearEntriesAddedBetween) {
741   url::SchemeHostPort scheme_host_port(GURL("http://foobar.com"));
742 
743   base::Time start_time;
744   ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:00", &start_time));
745   base::SimpleTestClock test_clock;
746   test_clock.SetNow(start_time);
747 
748   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
749   cache.set_clock_for_testing(&test_clock);
750 
751   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
752             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
753             "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
754   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
755             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
756             "basic realm=Realm2", AuthCredentials(kRoot, kWileCoyote), "/");
757 
758   test_clock.Advance(base::Seconds(10));  // Time now 12:00:10
759   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
760             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
761             "basic realm=Realm3", AuthCredentials(kAlice2, k1234), "/");
762   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
763             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
764             "basic realm=Realm4", AuthCredentials(kUsername, kPassword), "/");
765   // Add path to existing entry.
766   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
767             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
768             "basic realm=Realm2", AuthCredentials(kAdmin, kPassword), "/baz/");
769 
770   test_clock.Advance(base::Seconds(10));  // Time now 12:00:20
771   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm5,
772             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
773             "basic realm=Realm5", AuthCredentials(kAlice3, k12345), "/");
774 
775   base::Time test_time1;
776   ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:05", &test_time1));
777   base::Time test_time2;
778   ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:15", &test_time2));
779   cache.ClearEntriesAddedBetween(test_time1, test_time2);
780 
781   // Realms 1 and 2 are older than 12:00:05 and should not be cleared
782   EXPECT_NE(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
783                                   kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
784                                   NetworkAnonymizationKey()));
785   EXPECT_NE(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
786                                   kRealm2, HttpAuth::AUTH_SCHEME_BASIC,
787                                   NetworkAnonymizationKey()));
788 
789   // Realms 5 is newer than 12:00:15 and should not be cleared
790   EXPECT_NE(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
791                                   kRealm5, HttpAuth::AUTH_SCHEME_BASIC,
792                                   NetworkAnonymizationKey()));
793 
794   // Creation time is set for a whole entry rather than for a particular path.
795   // Path added within the requested duration isn't be removed.
796   EXPECT_NE(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
797                                         NetworkAnonymizationKey(), "/baz/"));
798 
799   // Realms 3 and 4 are between 12:00:05 and 12:00:10 and should be cleared.
800   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
801                                   kRealm3, HttpAuth::AUTH_SCHEME_BASIC,
802                                   NetworkAnonymizationKey()));
803   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
804                                   kRealm4, HttpAuth::AUTH_SCHEME_BASIC,
805                                   NetworkAnonymizationKey()));
806 
807   cache.ClearEntriesAddedBetween(start_time - base::Seconds(1),
808                                  base::Time::Max());
809   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
810                                   kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
811                                   NetworkAnonymizationKey()));
812   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
813                                   kRealm2, HttpAuth::AUTH_SCHEME_BASIC,
814                                   NetworkAnonymizationKey()));
815   EXPECT_EQ(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
816                                         NetworkAnonymizationKey(), "/baz/"));
817 }
818 
TEST(HttpAuthCacheTest,ClearEntriesAddedBetweenWithAllTimeValues)819 TEST(HttpAuthCacheTest, ClearEntriesAddedBetweenWithAllTimeValues) {
820   url::SchemeHostPort scheme_host_port(GURL("http://foobar.com"));
821 
822   base::SimpleTestClock test_clock;
823   test_clock.SetNow(base::Time::Now());
824 
825   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
826   cache.set_clock_for_testing(&test_clock);
827 
828   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
829             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
830             "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
831   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
832             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
833             "basic realm=Realm2", AuthCredentials(kRoot, kWileCoyote), "/");
834 
835   test_clock.Advance(base::Seconds(10));
836   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
837             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
838             "basic realm=Realm3", AuthCredentials(kAlice2, k1234), "/");
839   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
840             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
841             "basic realm=Realm4", AuthCredentials(kUsername, kPassword), "/");
842   // Add path to existing entry.
843   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
844             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
845             "basic realm=Realm2", AuthCredentials(kAdmin, kPassword), "/baz/");
846 
847   cache.ClearEntriesAddedBetween(base::Time::Min(), base::Time::Max());
848 
849   // All entries should be cleared.
850   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
851                                   kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
852                                   NetworkAnonymizationKey()));
853   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
854                                   kRealm2, HttpAuth::AUTH_SCHEME_BASIC,
855                                   NetworkAnonymizationKey()));
856   EXPECT_EQ(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
857                                         NetworkAnonymizationKey(), "/baz/"));
858   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
859                                   kRealm3, HttpAuth::AUTH_SCHEME_BASIC,
860                                   NetworkAnonymizationKey()));
861   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
862                                   kRealm4, HttpAuth::AUTH_SCHEME_BASIC,
863                                   NetworkAnonymizationKey()));
864 }
865 
TEST(HttpAuthCacheTest,ClearAllEntries)866 TEST(HttpAuthCacheTest, ClearAllEntries) {
867   url::SchemeHostPort scheme_host_port(GURL("http://foobar.com"));
868 
869   base::SimpleTestClock test_clock;
870   test_clock.SetNow(base::Time::Now());
871 
872   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
873   cache.set_clock_for_testing(&test_clock);
874 
875   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
876             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
877             "basic realm=Realm1", AuthCredentials(kAlice, k123), "/");
878   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
879             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
880             "basic realm=Realm2", AuthCredentials(kRoot, kWileCoyote), "/");
881 
882   test_clock.Advance(base::Seconds(10));
883   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm3,
884             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
885             "basic realm=Realm3", AuthCredentials(kAlice2, k1234), "/");
886   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm4,
887             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
888             "basic realm=Realm4", AuthCredentials(kUsername, kPassword), "/");
889   // Add path to existing entry.
890   cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
891             HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
892             "basic realm=Realm2", AuthCredentials(kAdmin, kPassword), "/baz/");
893 
894   test_clock.Advance(base::Seconds(55));
895   cache.ClearAllEntries();
896 
897   // All entries should be cleared.
898   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
899                                   kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
900                                   NetworkAnonymizationKey()));
901   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
902                                   kRealm2, HttpAuth::AUTH_SCHEME_BASIC,
903                                   NetworkAnonymizationKey()));
904   EXPECT_EQ(nullptr, cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_SERVER,
905                                         NetworkAnonymizationKey(), "/baz/"));
906   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
907                                   kRealm3, HttpAuth::AUTH_SCHEME_BASIC,
908                                   NetworkAnonymizationKey()));
909   EXPECT_EQ(nullptr, cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
910                                   kRealm4, HttpAuth::AUTH_SCHEME_BASIC,
911                                   NetworkAnonymizationKey()));
912 }
913 
TEST(HttpAuthCacheTest,UpdateStaleChallenge)914 TEST(HttpAuthCacheTest, UpdateStaleChallenge) {
915   HttpAuthCache cache(false /* key_entries_by_network_anonymization_key */);
916   url::SchemeHostPort scheme_host_port(GURL("http://foobar2.com"));
917   HttpAuthCache::Entry* entry_pre = cache.Add(
918       scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
919       HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
920       "Digest realm=Realm1,"
921       "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\"",
922       CreateASCIICredentials("realm-digest-user", "realm-digest-password"),
923       "/baz/index.html");
924   ASSERT_TRUE(entry_pre != nullptr);
925 
926   EXPECT_EQ(2, entry_pre->IncrementNonceCount());
927   EXPECT_EQ(3, entry_pre->IncrementNonceCount());
928   EXPECT_EQ(4, entry_pre->IncrementNonceCount());
929 
930   bool update_success = cache.UpdateStaleChallenge(
931       scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
932       HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
933       "Digest realm=Realm1,"
934       "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\","
935       "stale=\"true\"");
936   EXPECT_TRUE(update_success);
937 
938   // After the stale update, the entry should still exist in the cache and
939   // the nonce count should be reset to 0.
940   HttpAuthCache::Entry* entry_post =
941       cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
942                    HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey());
943   ASSERT_TRUE(entry_post != nullptr);
944   EXPECT_EQ(2, entry_post->IncrementNonceCount());
945 
946   // UpdateStaleChallenge will fail if an entry doesn't exist in the cache.
947   bool update_failure = cache.UpdateStaleChallenge(
948       scheme_host_port, HttpAuth::AUTH_SERVER, kRealm2,
949       HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
950       "Digest realm=Realm2,"
951       "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\","
952       "stale=\"true\"");
953   EXPECT_FALSE(update_failure);
954 }
955 
TEST(HttpAuthCacheTest,CopyProxyEntriesFrom)956 TEST(HttpAuthCacheTest, CopyProxyEntriesFrom) {
957   url::SchemeHostPort scheme_host_port(GURL("http://example.com"));
958   std::string path("/some/path");
959   std::string another_path("/another/path");
960 
961   HttpAuthCache first_cache(
962       false /* key_entries_by_network_anonymization_key */);
963   HttpAuthCache::Entry* entry;
964 
965   first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
966                   HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
967                   "basic realm=Realm1", AuthCredentials(kAlice, k123), path);
968   first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm2,
969                   HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
970                   "basic realm=Realm2", AuthCredentials(kAlice2, k1234), path);
971   first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
972                   HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
973                   "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote),
974                   path);
975   entry = first_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
976                           HttpAuth::AUTH_SCHEME_DIGEST,
977                           NetworkAnonymizationKey(), "digest realm=Realm3",
978                           AuthCredentials(kRoot, kWileCoyote), another_path);
979 
980   EXPECT_EQ(2, entry->IncrementNonceCount());
981 
982   // Server entry, which should not be copied.
983   first_cache.Add(scheme_host_port, HttpAuth::AUTH_SERVER, kRealm1,
984                   HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
985                   "basic realm=Realm1", AuthCredentials(kAlice, k123), path);
986 
987   HttpAuthCache second_cache(
988       false /* key_entries_by_network_anonymization_key */);
989   // Will be overwritten by kRoot:kWileCoyote.
990   second_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
991                    HttpAuth::AUTH_SCHEME_DIGEST, NetworkAnonymizationKey(),
992                    "digest realm=Realm3", AuthCredentials(kAlice2, k1234),
993                    path);
994   // Should be left intact.
995   second_cache.Add(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm4,
996                    HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
997                    "basic realm=Realm4", AuthCredentials(kAdmin, kRoot), path);
998 
999   second_cache.CopyProxyEntriesFrom(first_cache);
1000 
1001   // Copied from first_cache.
1002   entry = second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm1,
1003                               HttpAuth::AUTH_SCHEME_BASIC,
1004                               NetworkAnonymizationKey());
1005   EXPECT_TRUE(nullptr != entry);
1006   EXPECT_EQ(kAlice, entry->credentials().username());
1007   EXPECT_EQ(k123, entry->credentials().password());
1008 
1009   // Copied from first_cache.
1010   entry = second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm2,
1011                               HttpAuth::AUTH_SCHEME_BASIC,
1012                               NetworkAnonymizationKey());
1013   EXPECT_TRUE(nullptr != entry);
1014   EXPECT_EQ(kAlice2, entry->credentials().username());
1015   EXPECT_EQ(k1234, entry->credentials().password());
1016 
1017   // Overwritten from first_cache.
1018   entry = second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm3,
1019                               HttpAuth::AUTH_SCHEME_DIGEST,
1020                               NetworkAnonymizationKey());
1021   EXPECT_TRUE(nullptr != entry);
1022   EXPECT_EQ(kRoot, entry->credentials().username());
1023   EXPECT_EQ(kWileCoyote, entry->credentials().password());
1024   // Nonce count should get copied.
1025   EXPECT_EQ(3, entry->IncrementNonceCount());
1026 
1027   // All paths should get copied.
1028   entry = second_cache.LookupByPath(scheme_host_port, HttpAuth::AUTH_PROXY,
1029                                     NetworkAnonymizationKey(), another_path);
1030   EXPECT_TRUE(nullptr != entry);
1031   EXPECT_EQ(kRoot, entry->credentials().username());
1032   EXPECT_EQ(kWileCoyote, entry->credentials().password());
1033 
1034   // Left intact in second_cache.
1035   entry = second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_PROXY, kRealm4,
1036                               HttpAuth::AUTH_SCHEME_BASIC,
1037                               NetworkAnonymizationKey());
1038   EXPECT_TRUE(nullptr != entry);
1039   EXPECT_EQ(kAdmin, entry->credentials().username());
1040   EXPECT_EQ(kRoot, entry->credentials().password());
1041 
1042   // AUTH_SERVER entry should not have been copied from first_cache.
1043   EXPECT_TRUE(first_cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
1044                                  kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
1045                                  NetworkAnonymizationKey()));
1046   EXPECT_FALSE(second_cache.Lookup(scheme_host_port, HttpAuth::AUTH_SERVER,
1047                                    kRealm1, HttpAuth::AUTH_SCHEME_BASIC,
1048                                    NetworkAnonymizationKey()));
1049 }
1050 
1051 // Test fixture class for eviction tests (contains helpers for bulk
1052 // insertion and existence testing).
1053 class HttpAuthCacheEvictionTest : public testing::Test {
1054  protected:
HttpAuthCacheEvictionTest()1055   HttpAuthCacheEvictionTest()
1056       : scheme_host_port_(GURL("http://www.google.com")),
1057         cache_(false /* key_entries_by_network_anonymization_key */) {}
1058 
GenerateRealm(int realm_i)1059   std::string GenerateRealm(int realm_i) {
1060     return base::StringPrintf("Realm %d", realm_i);
1061   }
1062 
GeneratePath(int realm_i,int path_i)1063   std::string GeneratePath(int realm_i, int path_i) {
1064     return base::StringPrintf("/%d/%d/x/y", realm_i, path_i);
1065   }
1066 
AddRealm(int realm_i)1067   void AddRealm(int realm_i) {
1068     AddPathToRealm(realm_i, 0);
1069   }
1070 
AddPathToRealm(int realm_i,int path_i)1071   void AddPathToRealm(int realm_i, int path_i) {
1072     cache_.Add(scheme_host_port_, HttpAuth::AUTH_SERVER, GenerateRealm(realm_i),
1073                HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
1074                std::string(), AuthCredentials(kUsername, kPassword),
1075                GeneratePath(realm_i, path_i));
1076   }
1077 
CheckRealmExistence(int realm_i,bool exists)1078   void CheckRealmExistence(int realm_i, bool exists) {
1079     const HttpAuthCache::Entry* entry = cache_.Lookup(
1080         scheme_host_port_, HttpAuth::AUTH_SERVER, GenerateRealm(realm_i),
1081         HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey());
1082     if (exists) {
1083       EXPECT_FALSE(entry == nullptr);
1084       EXPECT_EQ(GenerateRealm(realm_i), entry->realm());
1085     } else {
1086       EXPECT_TRUE(entry == nullptr);
1087     }
1088   }
1089 
CheckPathExistence(int realm_i,int path_i,bool exists)1090   void CheckPathExistence(int realm_i, int path_i, bool exists) {
1091     const HttpAuthCache::Entry* entry = cache_.LookupByPath(
1092         scheme_host_port_, HttpAuth::AUTH_SERVER, NetworkAnonymizationKey(),
1093         GeneratePath(realm_i, path_i));
1094     if (exists) {
1095       EXPECT_FALSE(entry == nullptr);
1096       EXPECT_EQ(GenerateRealm(realm_i), entry->realm());
1097     } else {
1098       EXPECT_TRUE(entry == nullptr);
1099     }
1100   }
1101 
1102   url::SchemeHostPort scheme_host_port_;
1103   HttpAuthCache cache_;
1104 
1105   static const int kMaxPaths = HttpAuthCache::kMaxNumPathsPerRealmEntry;
1106   static const int kMaxRealms = HttpAuthCache::kMaxNumRealmEntries;
1107 };
1108 
1109 // Add the maxinim number of realm entries to the cache. Each of these entries
1110 // must still be retrievable. Next add three more entries -- since the cache is
1111 // full this causes FIFO eviction of the first three entries by time of last
1112 // use.
TEST_F(HttpAuthCacheEvictionTest,RealmEntryEviction)1113 TEST_F(HttpAuthCacheEvictionTest, RealmEntryEviction) {
1114   base::SimpleTestTickClock test_clock;
1115   test_clock.SetNowTicks(base::TimeTicks::Now());
1116   cache_.set_tick_clock_for_testing(&test_clock);
1117 
1118   for (int i = 0; i < kMaxRealms; ++i) {
1119     AddRealm(i);
1120     test_clock.Advance(base::Seconds(1));
1121   }
1122 
1123   for (int i = 0; i < kMaxRealms; ++i) {
1124     CheckRealmExistence(i, true);
1125     test_clock.Advance(base::Seconds(1));
1126   }
1127 
1128   for (int i = 0; i < 3; ++i) {
1129     AddRealm(i + kMaxRealms);
1130     test_clock.Advance(base::Seconds(1));
1131   }
1132 
1133   for (int i = 0; i < 3; ++i) {
1134     CheckRealmExistence(i, false);
1135     test_clock.Advance(base::Seconds(1));
1136   }
1137 
1138   for (int i = 0; i < kMaxRealms; ++i) {
1139     CheckRealmExistence(i + 3, true);
1140     test_clock.Advance(base::Seconds(1));
1141   }
1142 
1143   cache_.set_tick_clock_for_testing(nullptr);
1144 }
1145 
1146 // Add the maximum number of paths to a single realm entry. Each of these
1147 // paths should be retrievable. Next add 3 more paths -- since the cache is
1148 // full this causes FIFO eviction of the first three paths.
TEST_F(HttpAuthCacheEvictionTest,RealmPathEviction)1149 TEST_F(HttpAuthCacheEvictionTest, RealmPathEviction) {
1150   for (int i = 0; i < kMaxPaths; ++i)
1151     AddPathToRealm(0, i);
1152 
1153   for (int i = 1; i < kMaxRealms; ++i)
1154     AddRealm(i);
1155 
1156   for (int i = 0; i < 3; ++i)
1157     AddPathToRealm(0, i + kMaxPaths);
1158 
1159   for (int i = 0; i < 3; ++i)
1160     CheckPathExistence(0, i, false);
1161 
1162   for (int i = 0; i < kMaxPaths; ++i)
1163     CheckPathExistence(0, i + 3, true);
1164 
1165   for (int i = 0; i < kMaxRealms; ++i)
1166     CheckRealmExistence(i, true);
1167 }
1168 
1169 }  // namespace net
1170