1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_HTTP_HTTP_AUTH_CACHE_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_HTTP_HTTP_AUTH_CACHE_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <list> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/gtest_prod_util.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "googleurl/src/gurl.h" 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/http/http_auth.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// HttpAuthCache stores HTTP authentication identities and challenge info. 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For each (origin, realm, scheme) triple the cache stores a 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HttpAuthCache::Entry, which holds: 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - the origin server {protocol scheme, host, port} 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - the last identity used (username/password) 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - the last auth handler used (contains realm and authentication scheme) 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - the list of paths which used this realm 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Entries can be looked up by either (origin, realm, scheme) or (origin, path). 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HttpAuthCache { 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class Entry; 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Prevent unbounded memory growth. These are safeguards for abuse; it is 333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // not expected that the limits will be reached in ordinary usage. 343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // This also defines the worst-case lookup times (which grow linearly 353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // with number of elements in the cache). 363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen enum { kMaxNumPathsPerRealmEntry = 10 }; 373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen enum { kMaxNumRealmEntries = 10 }; 383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HttpAuthCache(); 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ~HttpAuthCache(); 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Find the realm entry on server |origin| for realm |realm| and 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // scheme |scheme|. 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |origin| - the {scheme, host, port} of the server. 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |realm| - case sensitive realm string. 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // |scheme| - the authentication scheme (i.e. basic, negotiate). 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns - the matched entry or NULL. 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Entry* Lookup(const GURL& origin, 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& realm, 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme scheme); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Find the entry on server |origin| whose protection space includes 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |path|. This uses the assumption in RFC 2617 section 2 that deeper 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // paths lie in the same protection space. 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |origin| - the {scheme, host, port} of the server. 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |path| - absolute path of the resource, or empty string in case of 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // proxy auth (which does not use the concept of paths). 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns - the matched entry or NULL. 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Entry* LookupByPath(const GURL& origin, const std::string& path); 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add an entry on server |origin| for realm |handler->realm()| and 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // scheme |handler->scheme()|. If an entry for this (realm,scheme) 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // already exists, update it rather than replace it -- this preserves the 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // paths list. 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |origin| - the {scheme, host, port} of the server. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |realm| - the auth realm for the challenge. 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // |scheme| - the authentication scheme (i.e. basic, negotiate). 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |username| - login information for the realm. 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |password| - login information for the realm. 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |path| - absolute path for a resource contained in the protection 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // space; this will be added to the list of known paths. 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns - the entry that was just added/updated. 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Entry* Add(const GURL& origin, 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& realm, 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme scheme, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& auth_challenge, 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& username, 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& password, 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& path); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove entry on server |origin| for realm |realm| and scheme |scheme| 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // if one exists AND if the cached identity matches (|username|, |password|). 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |origin| - the {scheme, host, port} of the server. 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |realm| - case sensitive realm string. 8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // |scheme| - the authentication scheme (i.e. basic, negotiate). 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |username| - condition to match. 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |password| - condition to match. 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns - true if an entry was removed. 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool Remove(const GURL& origin, 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& realm, 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme scheme, 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& username, 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& password); 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Updates a stale digest entry on server |origin| for realm |realm| and 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // scheme |scheme|. The cached auth challenge is replaced with 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |auth_challenge| and the nonce count is reset. 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |UpdateStaleChallenge()| returns true if a matching entry exists in the 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // cache, false otherwise. 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool UpdateStaleChallenge(const GURL& origin, 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& realm, 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme scheme, 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& auth_challenge); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::list<Entry> EntryList; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryList entries_; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// An authentication realm entry. 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HttpAuthCache::Entry { 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 1133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ~Entry(); 1143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const GURL& origin() const { 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return origin_; 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The case-sensitive realm string of the challenge. 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string realm() const { 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return realm_; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The authentication scheme of the challenge. 12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme scheme() const { 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return scheme_; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The authentication challenge. 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string auth_challenge() const { 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return auth_challenge_; 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The login username. 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 username() const { 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return username_; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The login password. 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 password() const { 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return password_; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int IncrementNonceCount() { 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ++nonce_count_; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void UpdateStaleChallenge(const std::string& auth_challenge); 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class HttpAuthCache; 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FRIEND_TEST_ALL_PREFIXES(HttpAuthCacheTest, AddPath); 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FRIEND_TEST_ALL_PREFIXES(HttpAuthCacheTest, AddToExistingEntry); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen typedef std::list<std::string> PathList; 1563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Entry(); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds a path defining the realm's protection space. If the path is 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // already contained in the protection space, is a no-op. 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddPath(const std::string& path); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Returns true if |dir| is contained within the realm's protection 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // space. |*path_len| is set to the length of the enclosing path if 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // such a path exists and |path_len| is non-NULL. If no enclosing 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // path is found, |*path_len| is left unmodified. 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Note that proxy auth cache entries are associated with empty 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // paths. Therefore it is possible for HasEnclosingPath() to return 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // true and set |*path_len| to 0. 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool HasEnclosingPath(const std::string& dir, size_t* path_len); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // |origin_| contains the {protocol, host, port} of the server. 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL origin_; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string realm_; 17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme scheme_; 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Identity. 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string auth_challenge_; 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 username_; 1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 password_; 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int nonce_count_; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // List of paths that define the realm's protection space. 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PathList paths_; 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} // namespace net 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_HTTP_HTTP_AUTH_CACHE_H_ 192