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