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