Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_HTTP_HTTP_AUTH_CACHE_H_
      6 #define NET_HTTP_HTTP_AUTH_CACHE_H_
      7 #pragma once
      8 
      9 #include <list>
     10 #include <string>
     11 
     12 #include "base/gtest_prod_util.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/string16.h"
     15 #include "googleurl/src/gurl.h"
     16 #include "net/http/http_auth.h"
     17 
     18 namespace net {
     19 
     20 // HttpAuthCache stores HTTP authentication identities and challenge info.
     21 // For each (origin, realm, scheme) triple the cache stores a
     22 // HttpAuthCache::Entry, which holds:
     23 //   - the origin server {protocol scheme, host, port}
     24 //   - the last identity used (username/password)
     25 //   - the last auth handler used (contains realm and authentication scheme)
     26 //   - the list of paths which used this realm
     27 // Entries can be looked up by either (origin, realm, scheme) or (origin, path).
     28 class HttpAuthCache {
     29  public:
     30   class Entry;
     31 
     32   // Prevent unbounded memory growth. These are safeguards for abuse; it is
     33   // not expected that the limits will be reached in ordinary usage.
     34   // This also defines the worst-case lookup times (which grow linearly
     35   // with number of elements in the cache).
     36   enum { kMaxNumPathsPerRealmEntry = 10 };
     37   enum { kMaxNumRealmEntries = 10 };
     38 
     39   HttpAuthCache();
     40   ~HttpAuthCache();
     41 
     42   // Find the realm entry on server |origin| for realm |realm| and
     43   // scheme |scheme|.
     44   //   |origin| - the {scheme, host, port} of the server.
     45   //   |realm|  - case sensitive realm string.
     46   //   |scheme| - the authentication scheme (i.e. basic, negotiate).
     47   //   returns  - the matched entry or NULL.
     48   Entry* Lookup(const GURL& origin,
     49                 const std::string& realm,
     50                 HttpAuth::Scheme scheme);
     51 
     52   // Find the entry on server |origin| whose protection space includes
     53   // |path|. This uses the assumption in RFC 2617 section 2 that deeper
     54   // paths lie in the same protection space.
     55   //   |origin| - the {scheme, host, port} of the server.
     56   //   |path|   - absolute path of the resource, or empty string in case of
     57   //              proxy auth (which does not use the concept of paths).
     58   //   returns  - the matched entry or NULL.
     59   Entry* LookupByPath(const GURL& origin, const std::string& path);
     60 
     61   // Add an entry on server |origin| for realm |handler->realm()| and
     62   // scheme |handler->scheme()|.  If an entry for this (realm,scheme)
     63   // already exists, update it rather than replace it -- this  preserves the
     64   // paths list.
     65   //   |origin|   - the {scheme, host, port} of the server.
     66   //   |realm|    - the auth realm for the challenge.
     67   //   |scheme|   - the authentication scheme (i.e. basic, negotiate).
     68   //   |username| - login information for the realm.
     69   //   |password| - login information for the realm.
     70   //   |path|     - absolute path for a resource contained in the protection
     71   //                space; this will be added to the list of known paths.
     72   //   returns    - the entry that was just added/updated.
     73   Entry* Add(const GURL& origin,
     74              const std::string& realm,
     75              HttpAuth::Scheme scheme,
     76              const std::string& auth_challenge,
     77              const string16& username,
     78              const string16& password,
     79              const std::string& path);
     80 
     81   // Remove entry on server |origin| for realm |realm| and scheme |scheme|
     82   // if one exists AND if the cached identity matches (|username|, |password|).
     83   //   |origin|   - the {scheme, host, port} of the server.
     84   //   |realm|    - case sensitive realm string.
     85   //   |scheme|   - the authentication scheme (i.e. basic, negotiate).
     86   //   |username| - condition to match.
     87   //   |password| - condition to match.
     88   //   returns    - true if an entry was removed.
     89   bool Remove(const GURL& origin,
     90               const std::string& realm,
     91               HttpAuth::Scheme scheme,
     92               const string16& username,
     93               const string16& password);
     94 
     95   // Updates a stale digest entry on server |origin| for realm |realm| and
     96   // scheme |scheme|. The cached auth challenge is replaced with
     97   // |auth_challenge| and the nonce count is reset.
     98   // |UpdateStaleChallenge()| returns true if a matching entry exists in the
     99   // cache, false otherwise.
    100   bool UpdateStaleChallenge(const GURL& origin,
    101                             const std::string& realm,
    102                             HttpAuth::Scheme scheme,
    103                             const std::string& auth_challenge);
    104 
    105  private:
    106   typedef std::list<Entry> EntryList;
    107   EntryList entries_;
    108 };
    109 
    110 // An authentication realm entry.
    111 class HttpAuthCache::Entry {
    112  public:
    113   ~Entry();
    114 
    115   const GURL& origin() const {
    116     return origin_;
    117   }
    118 
    119   // The case-sensitive realm string of the challenge.
    120   const std::string realm() const {
    121     return realm_;
    122   }
    123 
    124   // The authentication scheme of the challenge.
    125   HttpAuth::Scheme scheme() const {
    126     return scheme_;
    127   }
    128 
    129   // The authentication challenge.
    130   const std::string auth_challenge() const {
    131     return auth_challenge_;
    132   }
    133 
    134   // The login username.
    135   const string16 username() const {
    136     return username_;
    137   }
    138 
    139   // The login password.
    140   const string16 password() const {
    141     return password_;
    142   }
    143 
    144   int IncrementNonceCount() {
    145     return ++nonce_count_;
    146   }
    147 
    148   void UpdateStaleChallenge(const std::string& auth_challenge);
    149 
    150  private:
    151   friend class HttpAuthCache;
    152   FRIEND_TEST_ALL_PREFIXES(HttpAuthCacheTest, AddPath);
    153   FRIEND_TEST_ALL_PREFIXES(HttpAuthCacheTest, AddToExistingEntry);
    154 
    155   typedef std::list<std::string> PathList;
    156 
    157   Entry();
    158 
    159   // Adds a path defining the realm's protection space. If the path is
    160   // already contained in the protection space, is a no-op.
    161   void AddPath(const std::string& path);
    162 
    163   // Returns true if |dir| is contained within the realm's protection
    164   // space.  |*path_len| is set to the length of the enclosing path if
    165   // such a path exists and |path_len| is non-NULL.  If no enclosing
    166   // path is found, |*path_len| is left unmodified.
    167   //
    168   // Note that proxy auth cache entries are associated with empty
    169   // paths.  Therefore it is possible for HasEnclosingPath() to return
    170   // true and set |*path_len| to 0.
    171   bool HasEnclosingPath(const std::string& dir, size_t* path_len);
    172 
    173   // |origin_| contains the {protocol, host, port} of the server.
    174   GURL origin_;
    175   std::string realm_;
    176   HttpAuth::Scheme scheme_;
    177 
    178   // Identity.
    179   std::string auth_challenge_;
    180   string16 username_;
    181   string16 password_;
    182 
    183   int nonce_count_;
    184 
    185   // List of paths that define the realm's protection space.
    186   PathList paths_;
    187 };
    188 
    189 }  // namespace net
    190 
    191 #endif  // NET_HTTP_HTTP_AUTH_CACHE_H_
    192