• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_H_
6 #define NET_HTTP_HTTP_AUTH_H_
7 #pragma once
8 
9 #include <set>
10 #include <string>
11 
12 #include "base/memory/scoped_ptr.h"
13 #include "base/string16.h"
14 #include "net/http/http_util.h"
15 
16 template <class T> class scoped_refptr;
17 
18 namespace net {
19 
20 class BoundNetLog;
21 class HttpAuthHandler;
22 class HttpAuthHandlerFactory;
23 class HttpResponseHeaders;
24 
25 // Utility class for http authentication.
26 class HttpAuth {
27  public:
28   // Http authentication can be done the the proxy server, origin server,
29   // or both. This enum tracks who the target is.
30   enum Target {
31     AUTH_NONE = -1,
32     // We depend on the valid targets (!= AUTH_NONE) being usable as indexes
33     // in an array, so start from 0.
34     AUTH_PROXY = 0,
35     AUTH_SERVER = 1,
36     AUTH_NUM_TARGETS = 2,
37   };
38 
39   // What the HTTP WWW-Authenticate/Proxy-Authenticate headers indicate about
40   // the previous authorization attempt.
41   enum AuthorizationResult {
42     AUTHORIZATION_RESULT_ACCEPT,   // The authorization attempt was accepted,
43                                    // although there still may be additional
44                                    // rounds of challenges.
45 
46     AUTHORIZATION_RESULT_REJECT,   // The authorization attempt was rejected.
47 
48     AUTHORIZATION_RESULT_STALE,    // (Digest) The nonce used in the
49                                    // authorization attempt is stale, but
50                                    // otherwise the attempt was valid.
51 
52     AUTHORIZATION_RESULT_INVALID,  // The authentication challenge headers are
53                                    // poorly formed (the authorization attempt
54                                    // itself may have been fine).
55 
56     AUTHORIZATION_RESULT_DIFFERENT_REALM,  // The authorization
57                                            // attempt was rejected,
58                                            // but the realm associated
59                                            // with the new challenge
60                                            // is different from the
61                                            // previous attempt.
62   };
63 
64   // Describes where the identity used for authentication came from.
65   enum IdentitySource {
66     // Came from nowhere -- the identity is not initialized.
67     IDENT_SRC_NONE,
68 
69     // The identity came from the auth cache, by doing a path-based
70     // lookup (premptive authorization).
71     IDENT_SRC_PATH_LOOKUP,
72 
73     // The identity was extracted from a URL of the form:
74     // http://<username>:<password>@host:port
75     IDENT_SRC_URL,
76 
77     // The identity was retrieved from the auth cache, by doing a
78     // realm lookup.
79     IDENT_SRC_REALM_LOOKUP,
80 
81     // The identity was provided by RestartWithAuth -- it likely
82     // came from a prompt (or maybe the password manager).
83     IDENT_SRC_EXTERNAL,
84 
85     // The identity used the default credentials for the computer,
86     // on schemes that support single sign-on.
87     IDENT_SRC_DEFAULT_CREDENTIALS,
88   };
89 
90   enum Scheme {
91     AUTH_SCHEME_BASIC = 0,
92     AUTH_SCHEME_DIGEST,
93     AUTH_SCHEME_NTLM,
94     AUTH_SCHEME_NEGOTIATE,
95     AUTH_SCHEME_MOCK,
96     AUTH_SCHEME_MAX,
97   };
98 
99   // Helper structure used by HttpNetworkTransaction to track
100   // the current identity being used for authorization.
101   struct Identity {
102     Identity();
103 
104     IdentitySource source;
105     bool invalid;
106     string16 username;
107     string16 password;
108   };
109 
110   // Get the name of the header containing the auth challenge
111   // (either WWW-Authenticate or Proxy-Authenticate).
112   static std::string GetChallengeHeaderName(Target target);
113 
114   // Get the name of the header where the credentials go
115   // (either Authorization or Proxy-Authorization).
116   static std::string GetAuthorizationHeaderName(Target target);
117 
118   // Returns a string representation of a Target value that can be used in log
119   // messages.
120   static std::string GetAuthTargetString(Target target);
121 
122   // Returns a string representation of an authentication Scheme.
123   static const char* SchemeToString(Scheme scheme);
124 
125   // Iterate through the challenge headers, and pick the best one that
126   // we support. Obtains the implementation class for handling the challenge,
127   // and passes it back in |*handler|. If no supported challenge was found,
128   // |*handler| is set to NULL.
129   //
130   // |disabled_schemes| is the set of schemes that we should not use.
131   //
132   // |origin| is used by the NTLM and Negotiation authentication scheme to
133   // construct the service principal name.  It is ignored by other schemes.
134   static void ChooseBestChallenge(
135       HttpAuthHandlerFactory* http_auth_handler_factory,
136       const HttpResponseHeaders* headers,
137       Target target,
138       const GURL& origin,
139       const std::set<Scheme>& disabled_schemes,
140       const BoundNetLog& net_log,
141       scoped_ptr<HttpAuthHandler>* handler);
142 
143   // Handle a 401/407 response from a server/proxy after a previous
144   // authentication attempt. For connection-based authentication schemes, the
145   // new response may be another round in a multi-round authentication sequence.
146   // For request-based schemes, a 401/407 response is typically treated like a
147   // rejection of the previous challenge, except in the Digest case when a
148   // "stale" attribute is present.
149   //
150   // |handler| must be non-NULL, and is the HttpAuthHandler from the previous
151   // authentication round.
152   //
153   // |headers| must be non-NULL and contain the new HTTP response.
154   //
155   // |target| specifies whether the authentication challenge response came
156   // from a server or a proxy.
157   //
158   // |disabled_schemes| are the authentication schemes to ignore.
159   //
160   // |challenge_used| is the text of the authentication challenge used in
161   // support of the returned AuthorizationResult. If no headers were used for
162   // the result (for example, all headers have unknown authentication schemes),
163   // the value is cleared.
164   static AuthorizationResult HandleChallengeResponse(
165       HttpAuthHandler* handler,
166       const HttpResponseHeaders* headers,
167       Target target,
168       const std::set<Scheme>& disabled_schemes,
169       std::string* challenge_used);
170 
171   // Breaks up a challenge string into the the auth scheme and parameter list,
172   // according to RFC 2617 Sec 1.2:
173   //    challenge = auth-scheme 1*SP 1#auth-param
174   //
175   // Depending on the challenge scheme, it may be appropriate to interpret the
176   // parameters as either a base-64 encoded string or a comma-delimited list
177   // of name-value pairs. param_pairs() and base64_param() methods are provided
178   // to support either usage.
179   class ChallengeTokenizer {
180    public:
ChallengeTokenizer(std::string::const_iterator begin,std::string::const_iterator end)181     ChallengeTokenizer(std::string::const_iterator begin,
182                        std::string::const_iterator end)
183         : begin_(begin),
184           end_(end),
185           scheme_begin_(begin),
186           scheme_end_(begin),
187           params_begin_(end),
188           params_end_(end) {
189       Init(begin, end);
190     }
191 
192     // Get the original text.
challenge_text()193     std::string challenge_text() const {
194       return std::string(begin_, end_);
195     }
196 
197     // Get the auth scheme of the challenge.
scheme_begin()198     std::string::const_iterator scheme_begin() const { return scheme_begin_; }
scheme_end()199     std::string::const_iterator scheme_end() const { return scheme_end_; }
scheme()200     std::string scheme() const {
201       return std::string(scheme_begin_, scheme_end_);
202     }
203 
204     HttpUtil::NameValuePairsIterator param_pairs() const;
205     std::string base64_param() const;
206 
207    private:
208     void Init(std::string::const_iterator begin,
209               std::string::const_iterator end);
210 
211     std::string::const_iterator begin_;
212     std::string::const_iterator end_;
213 
214     std::string::const_iterator scheme_begin_;
215     std::string::const_iterator scheme_end_;
216 
217     std::string::const_iterator params_begin_;
218     std::string::const_iterator params_end_;
219   };
220 };
221 
222 }  // namespace net
223 
224 #endif  // NET_HTTP_HTTP_AUTH_H_
225