Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2006-2008 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_H_
      6 #define NET_HTTP_HTTP_AUTH_H_
      7 
      8 #include "net/http/http_util.h"
      9 
     10 template <class T> class scoped_refptr;
     11 
     12 namespace net {
     13 
     14 class HttpAuthHandler;
     15 class HttpResponseHeaders;
     16 
     17 // Utility class for http authentication.
     18 class HttpAuth {
     19  public:
     20 
     21    // Http authentication can be done the the proxy server, origin server,
     22    // or both. This enum tracks who the target is.
     23    enum Target {
     24      AUTH_NONE = -1,
     25      // We depend on the valid targets (!= AUTH_NONE) being usable as indexes
     26      // in an array, so start from 0.
     27      AUTH_PROXY = 0,
     28      AUTH_SERVER = 1,
     29    };
     30 
     31    // Describes where the identity used for authentication came from.
     32    enum IdentitySource {
     33      // Came from nowhere -- the identity is not initialized.
     34      IDENT_SRC_NONE,
     35 
     36      // The identity came from the auth cache, by doing a path-based
     37      // lookup (premptive authorization).
     38      IDENT_SRC_PATH_LOOKUP,
     39 
     40      // The identity was extracted from a URL of the form:
     41      // http://<username>:<password>@host:port
     42      IDENT_SRC_URL,
     43 
     44      // The identity was retrieved from the auth cache, by doing a
     45      // realm lookup.
     46      IDENT_SRC_REALM_LOOKUP,
     47 
     48      // The identity was provided by RestartWithAuth -- it likely
     49      // came from a prompt (or maybe the password manager).
     50      IDENT_SRC_EXTERNAL,
     51    };
     52 
     53    // Helper structure used by HttpNetworkTransaction to track
     54    // the current identity being used for authorization.
     55    struct Identity {
     56      Identity() : source(IDENT_SRC_NONE), invalid(true) { }
     57 
     58      IdentitySource source;
     59      bool invalid;
     60      // TODO(wtc): |username| and |password| should be string16.
     61      std::wstring username;
     62      std::wstring password;
     63    };
     64 
     65   // Get the name of the header containing the auth challenge
     66   // (either WWW-Authenticate or Proxy-Authenticate).
     67   static std::string GetChallengeHeaderName(Target target);
     68 
     69   // Get the name of the header where the credentials go
     70   // (either Authorization or Proxy-Authorization).
     71   static std::string GetAuthorizationHeaderName(Target target);
     72 
     73   // Create a handler to generate credentials for the challenge, and pass
     74   // it back in |*handler|. If the challenge is unsupported or invalid
     75   // |*handler| is set to NULL.
     76   static void CreateAuthHandler(const std::string& challenge,
     77                                 Target target,
     78                                 const GURL& origin,
     79                                 scoped_refptr<HttpAuthHandler>* handler);
     80 
     81   // Iterate through the challenge headers, and pick the best one that
     82   // we support. Obtains the implementation class for handling the challenge,
     83   // and passes it back in |*handler|. If the existing handler in |*handler|
     84   // should continue to be used (such as for the NTLM authentication scheme),
     85   // |*handler| is unchanged. If no supported challenge was found, |*handler|
     86   // is set to NULL.
     87   //
     88   // |origin| is used by the NTLM authentication scheme to construct the
     89   // service principal name.  It is ignored by other schemes.
     90   //
     91   // TODO(wtc): Continuing to use the existing handler in |*handler| (for
     92   // NTLM) is new behavior.  Rename ChooseBestChallenge to fully encompass
     93   // what it does now.
     94   static void ChooseBestChallenge(const HttpResponseHeaders* headers,
     95                                   Target target,
     96                                   const GURL& origin,
     97                                   scoped_refptr<HttpAuthHandler>* handler);
     98 
     99   // ChallengeTokenizer breaks up a challenge string into the the auth scheme
    100   // and parameter list, according to RFC 2617 Sec 1.2:
    101   //    challenge = auth-scheme 1*SP 1#auth-param
    102   //
    103   // Check valid() after each iteration step in case it was malformed.
    104   // Also note that value() will give whatever is to the right of the equals
    105   // sign, quotemarks and all. Use unquoted_value() to get the logical value.
    106   class ChallengeTokenizer {
    107    public:
    108     ChallengeTokenizer(std::string::const_iterator begin,
    109                        std::string::const_iterator end)
    110         : props_(begin, end, ','), valid_(true) {
    111       Init(begin, end);
    112     }
    113 
    114     // Get the auth scheme of the challenge.
    115     std::string::const_iterator scheme_begin() const { return scheme_begin_; }
    116     std::string::const_iterator scheme_end() const { return scheme_end_; }
    117     std::string scheme() const {
    118       return std::string(scheme_begin_, scheme_end_);
    119     }
    120 
    121     // Returns false if there was a parse error.
    122     bool valid() const {
    123       return valid_;
    124     }
    125 
    126     // Advances the iterator to the next name-value pair, if any.
    127     // Returns true if there is none to consume.
    128     bool GetNext();
    129 
    130     // The name of the current name-value pair.
    131     std::string::const_iterator name_begin() const { return name_begin_; }
    132     std::string::const_iterator name_end() const { return name_end_; }
    133     std::string name() const {
    134       return std::string(name_begin_, name_end_);
    135     }
    136 
    137     // The value of the current name-value pair.
    138     std::string::const_iterator value_begin() const { return value_begin_; }
    139     std::string::const_iterator value_end() const { return value_end_; }
    140     std::string value() const {
    141       return std::string(value_begin_, value_end_);
    142     }
    143 
    144     // If value() has quotemarks, unquote it.
    145     std::string unquoted_value() const;
    146 
    147     // True if the name-value pair's value has quote marks.
    148     bool value_is_quoted() const { return value_is_quoted_; }
    149 
    150    private:
    151     void Init(std::string::const_iterator begin,
    152               std::string::const_iterator end);
    153 
    154     HttpUtil::ValuesIterator props_;
    155     bool valid_;
    156 
    157     std::string::const_iterator scheme_begin_;
    158     std::string::const_iterator scheme_end_;
    159 
    160     std::string::const_iterator name_begin_;
    161     std::string::const_iterator name_end_;
    162 
    163     std::string::const_iterator value_begin_;
    164     std::string::const_iterator value_end_;
    165 
    166     bool value_is_quoted_;
    167   };
    168 };
    169 
    170 }  // namespace net
    171 
    172 #endif  // NET_HTTP_HTTP_AUTH_H_
    173