1 // Copyright (c) 2010 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 #include "net/http/http_auth_handler_factory.h" 6 7 #include "base/stl_util.h" 8 #include "base/strings/string_util.h" 9 #include "net/base/net_errors.h" 10 #include "net/http/http_auth_challenge_tokenizer.h" 11 #include "net/http/http_auth_filter.h" 12 #include "net/http/http_auth_handler_basic.h" 13 #include "net/http/http_auth_handler_digest.h" 14 #include "net/http/http_auth_handler_ntlm.h" 15 16 #if defined(USE_KERBEROS) 17 #include "net/http/http_auth_handler_negotiate.h" 18 #endif 19 20 namespace net { 21 22 int HttpAuthHandlerFactory::CreateAuthHandlerFromString( 23 const std::string& challenge, 24 HttpAuth::Target target, 25 const GURL& origin, 26 const BoundNetLog& net_log, 27 scoped_ptr<HttpAuthHandler>* handler) { 28 HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end()); 29 return CreateAuthHandler(&props, target, origin, CREATE_CHALLENGE, 1, 30 net_log, handler); 31 } 32 33 int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString( 34 const std::string& challenge, 35 HttpAuth::Target target, 36 const GURL& origin, 37 int digest_nonce_count, 38 const BoundNetLog& net_log, 39 scoped_ptr<HttpAuthHandler>* handler) { 40 HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end()); 41 return CreateAuthHandler(&props, target, origin, CREATE_PREEMPTIVE, 42 digest_nonce_count, net_log, handler); 43 } 44 45 // static 46 HttpAuthHandlerRegistryFactory* HttpAuthHandlerFactory::CreateDefault( 47 HostResolver* host_resolver) { 48 DCHECK(host_resolver); 49 HttpAuthHandlerRegistryFactory* registry_factory = 50 new HttpAuthHandlerRegistryFactory(); 51 registry_factory->RegisterSchemeFactory( 52 "basic", new HttpAuthHandlerBasic::Factory()); 53 registry_factory->RegisterSchemeFactory( 54 "digest", new HttpAuthHandlerDigest::Factory()); 55 56 #if defined(USE_KERBEROS) 57 HttpAuthHandlerNegotiate::Factory* negotiate_factory = 58 new HttpAuthHandlerNegotiate::Factory(); 59 #if defined(OS_POSIX) 60 negotiate_factory->set_library(new GSSAPISharedLibrary(std::string())); 61 #elif defined(OS_WIN) 62 negotiate_factory->set_library(new SSPILibraryDefault()); 63 #endif 64 negotiate_factory->set_host_resolver(host_resolver); 65 registry_factory->RegisterSchemeFactory("negotiate", negotiate_factory); 66 #endif // defined(USE_KERBEROS) 67 68 HttpAuthHandlerNTLM::Factory* ntlm_factory = 69 new HttpAuthHandlerNTLM::Factory(); 70 #if defined(OS_WIN) 71 ntlm_factory->set_sspi_library(new SSPILibraryDefault()); 72 #endif 73 registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory); 74 return registry_factory; 75 } 76 77 namespace { 78 79 bool IsSupportedScheme(const std::vector<std::string>& supported_schemes, 80 const std::string& scheme) { 81 std::vector<std::string>::const_iterator it = std::find( 82 supported_schemes.begin(), supported_schemes.end(), scheme); 83 return it != supported_schemes.end(); 84 } 85 86 } // namespace 87 88 HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory() { 89 } 90 91 HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() { 92 STLDeleteContainerPairSecondPointers(factory_map_.begin(), 93 factory_map_.end()); 94 } 95 96 void HttpAuthHandlerRegistryFactory::SetURLSecurityManager( 97 const std::string& scheme, 98 URLSecurityManager* security_manager) { 99 HttpAuthHandlerFactory* factory = GetSchemeFactory(scheme); 100 if (factory) 101 factory->set_url_security_manager(security_manager); 102 } 103 104 void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory( 105 const std::string& scheme, 106 HttpAuthHandlerFactory* factory) { 107 std::string lower_scheme = StringToLowerASCII(scheme); 108 FactoryMap::iterator it = factory_map_.find(lower_scheme); 109 if (it != factory_map_.end()) { 110 delete it->second; 111 } 112 if (factory) 113 factory_map_[lower_scheme] = factory; 114 else 115 factory_map_.erase(it); 116 } 117 118 HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory( 119 const std::string& scheme) const { 120 std::string lower_scheme = StringToLowerASCII(scheme); 121 FactoryMap::const_iterator it = factory_map_.find(lower_scheme); 122 if (it == factory_map_.end()) { 123 return NULL; // |scheme| is not registered. 124 } 125 return it->second; 126 } 127 128 // static 129 HttpAuthHandlerRegistryFactory* HttpAuthHandlerRegistryFactory::Create( 130 const std::vector<std::string>& supported_schemes, 131 URLSecurityManager* security_manager, 132 HostResolver* host_resolver, 133 const std::string& gssapi_library_name, 134 bool negotiate_disable_cname_lookup, 135 bool negotiate_enable_port) { 136 HttpAuthHandlerRegistryFactory* registry_factory = 137 new HttpAuthHandlerRegistryFactory(); 138 if (IsSupportedScheme(supported_schemes, "basic")) 139 registry_factory->RegisterSchemeFactory( 140 "basic", new HttpAuthHandlerBasic::Factory()); 141 if (IsSupportedScheme(supported_schemes, "digest")) 142 registry_factory->RegisterSchemeFactory( 143 "digest", new HttpAuthHandlerDigest::Factory()); 144 if (IsSupportedScheme(supported_schemes, "ntlm")) { 145 HttpAuthHandlerNTLM::Factory* ntlm_factory = 146 new HttpAuthHandlerNTLM::Factory(); 147 ntlm_factory->set_url_security_manager(security_manager); 148 #if defined(OS_WIN) 149 ntlm_factory->set_sspi_library(new SSPILibraryDefault()); 150 #endif 151 registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory); 152 } 153 #if defined(USE_KERBEROS) 154 if (IsSupportedScheme(supported_schemes, "negotiate")) { 155 HttpAuthHandlerNegotiate::Factory* negotiate_factory = 156 new HttpAuthHandlerNegotiate::Factory(); 157 #if defined(OS_POSIX) 158 negotiate_factory->set_library( 159 new GSSAPISharedLibrary(gssapi_library_name)); 160 #elif defined(OS_WIN) 161 negotiate_factory->set_library(new SSPILibraryDefault()); 162 #endif 163 negotiate_factory->set_url_security_manager(security_manager); 164 DCHECK(host_resolver || negotiate_disable_cname_lookup); 165 negotiate_factory->set_host_resolver(host_resolver); 166 negotiate_factory->set_disable_cname_lookup(negotiate_disable_cname_lookup); 167 negotiate_factory->set_use_port(negotiate_enable_port); 168 registry_factory->RegisterSchemeFactory("negotiate", negotiate_factory); 169 } 170 #endif // defined(USE_KERBEROS) 171 172 return registry_factory; 173 } 174 175 int HttpAuthHandlerRegistryFactory::CreateAuthHandler( 176 HttpAuthChallengeTokenizer* challenge, 177 HttpAuth::Target target, 178 const GURL& origin, 179 CreateReason reason, 180 int digest_nonce_count, 181 const BoundNetLog& net_log, 182 scoped_ptr<HttpAuthHandler>* handler) { 183 std::string scheme = challenge->scheme(); 184 if (scheme.empty()) { 185 handler->reset(); 186 return ERR_INVALID_RESPONSE; 187 } 188 std::string lower_scheme = StringToLowerASCII(scheme); 189 FactoryMap::iterator it = factory_map_.find(lower_scheme); 190 if (it == factory_map_.end()) { 191 handler->reset(); 192 return ERR_UNSUPPORTED_AUTH_SCHEME; 193 } 194 DCHECK(it->second); 195 return it->second->CreateAuthHandler(challenge, target, origin, reason, 196 digest_nonce_count, net_log, handler); 197 } 198 199 } // namespace net 200