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_HANDLER_NEGOTIATE_H_ 6 #define NET_HTTP_HTTP_AUTH_HANDLER_NEGOTIATE_H_ 7 8 #include <string> 9 10 #include "build/build_config.h" 11 #include "net/base/address_list.h" 12 #include "net/base/net_export.h" 13 #include "net/http/http_auth_handler.h" 14 #include "net/http/http_auth_handler_factory.h" 15 16 #if defined(OS_WIN) 17 #include "net/http/http_auth_sspi_win.h" 18 #elif defined(OS_POSIX) 19 #include "net/http/http_auth_gssapi_posix.h" 20 #endif 21 22 namespace net { 23 24 class HostResolver; 25 class SingleRequestHostResolver; 26 class URLSecurityManager; 27 28 // Handler for WWW-Authenticate: Negotiate protocol. 29 // 30 // See http://tools.ietf.org/html/rfc4178 and http://tools.ietf.org/html/rfc4559 31 // for more information about the protocol. 32 33 class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler { 34 public: 35 #if defined(OS_WIN) 36 typedef SSPILibrary AuthLibrary; 37 typedef HttpAuthSSPI AuthSystem; 38 #elif defined(OS_POSIX) 39 typedef GSSAPILibrary AuthLibrary; 40 typedef HttpAuthGSSAPI AuthSystem; 41 #endif 42 43 class NET_EXPORT_PRIVATE Factory : public HttpAuthHandlerFactory { 44 public: 45 Factory(); 46 virtual ~Factory(); 47 48 // |disable_cname_lookup()| and |set_disable_cname_lookup()| get/set whether 49 // the auth handlers generated by this factory should skip looking up the 50 // canonical DNS name of the the host that they are authenticating to when 51 // generating the SPN. The default value is false. disable_cname_lookup()52 bool disable_cname_lookup() const { return disable_cname_lookup_; } set_disable_cname_lookup(bool disable_cname_lookup)53 void set_disable_cname_lookup(bool disable_cname_lookup) { 54 disable_cname_lookup_ = disable_cname_lookup; 55 } 56 57 // |use_port()| and |set_use_port()| get/set whether the auth handlers 58 // generated by this factory should include the port number of the server 59 // they are authenticating to when constructing a Kerberos SPN. The default 60 // value is false. use_port()61 bool use_port() const { return use_port_; } set_use_port(bool use_port)62 void set_use_port(bool use_port) { use_port_ = use_port; } 63 64 void set_host_resolver(HostResolver* host_resolver); 65 66 // Sets the system library to use, thereby assuming ownership of 67 // |auth_library|. set_library(AuthLibrary * auth_library)68 void set_library(AuthLibrary* auth_library) { 69 auth_library_.reset(auth_library); 70 } 71 72 virtual int CreateAuthHandler( 73 HttpAuthChallengeTokenizer* challenge, 74 HttpAuth::Target target, 75 const GURL& origin, 76 CreateReason reason, 77 int digest_nonce_count, 78 const BoundNetLog& net_log, 79 scoped_ptr<HttpAuthHandler>* handler) OVERRIDE; 80 81 private: 82 bool disable_cname_lookup_; 83 bool use_port_; 84 HostResolver* resolver_; 85 #if defined(OS_WIN) 86 ULONG max_token_length_; 87 bool first_creation_; 88 #endif 89 bool is_unsupported_; 90 scoped_ptr<AuthLibrary> auth_library_; 91 }; 92 93 HttpAuthHandlerNegotiate(AuthLibrary* sspi_library, 94 #if defined(OS_WIN) 95 ULONG max_token_length, 96 #endif 97 URLSecurityManager* url_security_manager, 98 HostResolver* host_resolver, 99 bool disable_cname_lookup, 100 bool use_port); 101 102 virtual ~HttpAuthHandlerNegotiate(); 103 104 // These are public for unit tests 105 std::string CreateSPN(const AddressList& address_list, const GURL& orign); spn()106 const std::string& spn() const { return spn_; } 107 108 // HttpAuthHandler: 109 virtual HttpAuth::AuthorizationResult HandleAnotherChallenge( 110 HttpAuthChallengeTokenizer* challenge) OVERRIDE; 111 virtual bool NeedsIdentity() OVERRIDE; 112 virtual bool AllowsDefaultCredentials() OVERRIDE; 113 virtual bool AllowsExplicitCredentials() OVERRIDE; 114 115 protected: 116 virtual bool Init(HttpAuthChallengeTokenizer* challenge) OVERRIDE; 117 118 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials, 119 const HttpRequestInfo* request, 120 const CompletionCallback& callback, 121 std::string* auth_token) OVERRIDE; 122 123 private: 124 enum State { 125 STATE_RESOLVE_CANONICAL_NAME, 126 STATE_RESOLVE_CANONICAL_NAME_COMPLETE, 127 STATE_GENERATE_AUTH_TOKEN, 128 STATE_GENERATE_AUTH_TOKEN_COMPLETE, 129 STATE_NONE, 130 }; 131 132 void OnIOComplete(int result); 133 void DoCallback(int result); 134 int DoLoop(int result); 135 136 int DoResolveCanonicalName(); 137 int DoResolveCanonicalNameComplete(int rv); 138 int DoGenerateAuthToken(); 139 int DoGenerateAuthTokenComplete(int rv); 140 bool CanDelegate() const; 141 142 AuthSystem auth_system_; 143 bool disable_cname_lookup_; 144 bool use_port_; 145 HostResolver* const resolver_; 146 147 // Members which are needed for DNS lookup + SPN. 148 AddressList address_list_; 149 scoped_ptr<SingleRequestHostResolver> single_resolve_; 150 151 // Things which should be consistent after first call to GenerateAuthToken. 152 bool already_called_; 153 bool has_credentials_; 154 AuthCredentials credentials_; 155 std::string spn_; 156 157 // Things which vary each round. 158 CompletionCallback callback_; 159 std::string* auth_token_; 160 161 State next_state_; 162 163 const URLSecurityManager* url_security_manager_; 164 }; 165 166 } // namespace net 167 168 #endif // NET_HTTP_HTTP_AUTH_HANDLER_NEGOTIATE_H_ 169