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