• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
IdentityIdentity56      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:
ChallengeTokenizer(std::string::const_iterator begin,std::string::const_iterator end)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.
scheme_begin()115     std::string::const_iterator scheme_begin() const { return scheme_begin_; }
scheme_end()116     std::string::const_iterator scheme_end() const { return scheme_end_; }
scheme()117     std::string scheme() const {
118       return std::string(scheme_begin_, scheme_end_);
119     }
120 
121     // Returns false if there was a parse error.
valid()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.
name_begin()131     std::string::const_iterator name_begin() const { return name_begin_; }
name_end()132     std::string::const_iterator name_end() const { return name_end_; }
name()133     std::string name() const {
134       return std::string(name_begin_, name_end_);
135     }
136 
137     // The value of the current name-value pair.
value_begin()138     std::string::const_iterator value_begin() const { return value_begin_; }
value_end()139     std::string::const_iterator value_end() const { return value_end_; }
value()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.
value_is_quoted()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