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 20namespace net { 21 22int 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 33int 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 46HttpAuthHandlerRegistryFactory* 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 77namespace { 78 79bool 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 88HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory() { 89} 90 91HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() { 92 STLDeleteContainerPairSecondPointers(factory_map_.begin(), 93 factory_map_.end()); 94} 95 96void 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 104void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory( 105 const std::string& scheme, 106 HttpAuthHandlerFactory* factory) { 107 std::string lower_scheme = base::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 118HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory( 119 const std::string& scheme) const { 120 std::string lower_scheme = base::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 129HttpAuthHandlerRegistryFactory* 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 175int 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 = base::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