| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/http/http_auth_handler_factory.h" |
| |
| #include "base/stl_util.h" |
| #include "base/string_util.h" |
| #include "net/base/net_errors.h" |
| #include "net/http/http_auth_filter.h" |
| #include "net/http/http_auth_handler_basic.h" |
| #include "net/http/http_auth_handler_digest.h" |
| #include "net/http/http_auth_handler_ntlm.h" |
| |
| #if defined(USE_KERBEROS) |
| #include "net/http/http_auth_handler_negotiate.h" |
| #endif |
| |
| namespace net { |
| |
| int HttpAuthHandlerFactory::CreateAuthHandlerFromString( |
| const std::string& challenge, |
| HttpAuth::Target target, |
| const GURL& origin, |
| const BoundNetLog& net_log, |
| scoped_ptr<HttpAuthHandler>* handler) { |
| HttpAuth::ChallengeTokenizer props(challenge.begin(), challenge.end()); |
| return CreateAuthHandler(&props, target, origin, CREATE_CHALLENGE, 1, |
| net_log, handler); |
| } |
| |
| int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString( |
| const std::string& challenge, |
| HttpAuth::Target target, |
| const GURL& origin, |
| int digest_nonce_count, |
| const BoundNetLog& net_log, |
| scoped_ptr<HttpAuthHandler>* handler) { |
| HttpAuth::ChallengeTokenizer props(challenge.begin(), challenge.end()); |
| return CreateAuthHandler(&props, target, origin, CREATE_PREEMPTIVE, |
| digest_nonce_count, net_log, handler); |
| } |
| |
| // static |
| HttpAuthHandlerRegistryFactory* HttpAuthHandlerFactory::CreateDefault( |
| HostResolver* host_resolver) { |
| DCHECK(host_resolver); |
| HttpAuthHandlerRegistryFactory* registry_factory = |
| new HttpAuthHandlerRegistryFactory(); |
| registry_factory->RegisterSchemeFactory( |
| "basic", new HttpAuthHandlerBasic::Factory()); |
| registry_factory->RegisterSchemeFactory( |
| "digest", new HttpAuthHandlerDigest::Factory()); |
| |
| #if defined(USE_KERBEROS) |
| HttpAuthHandlerNegotiate::Factory* negotiate_factory = |
| new HttpAuthHandlerNegotiate::Factory(); |
| #if defined(OS_POSIX) |
| negotiate_factory->set_library(new GSSAPISharedLibrary(std::string())); |
| #elif defined(OS_WIN) |
| negotiate_factory->set_library(new SSPILibraryDefault()); |
| #endif |
| negotiate_factory->set_host_resolver(host_resolver); |
| registry_factory->RegisterSchemeFactory("negotiate", negotiate_factory); |
| #endif // defined(USE_KERBEROS) |
| |
| HttpAuthHandlerNTLM::Factory* ntlm_factory = |
| new HttpAuthHandlerNTLM::Factory(); |
| #if defined(OS_WIN) |
| ntlm_factory->set_sspi_library(new SSPILibraryDefault()); |
| #endif |
| registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory); |
| return registry_factory; |
| } |
| |
| namespace { |
| |
| bool IsSupportedScheme(const std::vector<std::string>& supported_schemes, |
| const std::string& scheme) { |
| std::vector<std::string>::const_iterator it = std::find( |
| supported_schemes.begin(), supported_schemes.end(), scheme); |
| return it != supported_schemes.end(); |
| } |
| |
| } // namespace |
| |
| HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory() { |
| } |
| |
| HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() { |
| STLDeleteContainerPairSecondPointers(factory_map_.begin(), |
| factory_map_.end()); |
| } |
| |
| void HttpAuthHandlerRegistryFactory::SetURLSecurityManager( |
| const std::string& scheme, |
| URLSecurityManager* security_manager) { |
| HttpAuthHandlerFactory* factory = GetSchemeFactory(scheme); |
| if (factory) |
| factory->set_url_security_manager(security_manager); |
| } |
| |
| void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory( |
| const std::string& scheme, |
| HttpAuthHandlerFactory* factory) { |
| std::string lower_scheme = StringToLowerASCII(scheme); |
| FactoryMap::iterator it = factory_map_.find(lower_scheme); |
| if (it != factory_map_.end()) { |
| delete it->second; |
| } |
| if (factory) |
| factory_map_[lower_scheme] = factory; |
| else |
| factory_map_.erase(it); |
| } |
| |
| HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory( |
| const std::string& scheme) const { |
| std::string lower_scheme = StringToLowerASCII(scheme); |
| FactoryMap::const_iterator it = factory_map_.find(lower_scheme); |
| if (it == factory_map_.end()) { |
| return NULL; // |scheme| is not registered. |
| } |
| return it->second; |
| } |
| |
| // static |
| HttpAuthHandlerRegistryFactory* HttpAuthHandlerRegistryFactory::Create( |
| const std::vector<std::string>& supported_schemes, |
| URLSecurityManager* security_manager, |
| HostResolver* host_resolver, |
| const std::string& gssapi_library_name, |
| bool negotiate_disable_cname_lookup, |
| bool negotiate_enable_port) { |
| HttpAuthHandlerRegistryFactory* registry_factory = |
| new HttpAuthHandlerRegistryFactory(); |
| if (IsSupportedScheme(supported_schemes, "basic")) |
| registry_factory->RegisterSchemeFactory( |
| "basic", new HttpAuthHandlerBasic::Factory()); |
| if (IsSupportedScheme(supported_schemes, "digest")) |
| registry_factory->RegisterSchemeFactory( |
| "digest", new HttpAuthHandlerDigest::Factory()); |
| if (IsSupportedScheme(supported_schemes, "ntlm")) { |
| HttpAuthHandlerNTLM::Factory* ntlm_factory = |
| new HttpAuthHandlerNTLM::Factory(); |
| ntlm_factory->set_url_security_manager(security_manager); |
| #if defined(OS_WIN) |
| ntlm_factory->set_sspi_library(new SSPILibraryDefault()); |
| #endif |
| registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory); |
| } |
| #if defined(USE_KERBEROS) |
| if (IsSupportedScheme(supported_schemes, "negotiate")) { |
| HttpAuthHandlerNegotiate::Factory* negotiate_factory = |
| new HttpAuthHandlerNegotiate::Factory(); |
| #if defined(OS_POSIX) |
| negotiate_factory->set_library( |
| new GSSAPISharedLibrary(gssapi_library_name)); |
| #elif defined(OS_WIN) |
| negotiate_factory->set_library(new SSPILibraryDefault()); |
| #endif |
| negotiate_factory->set_url_security_manager(security_manager); |
| DCHECK(host_resolver || negotiate_disable_cname_lookup); |
| negotiate_factory->set_host_resolver(host_resolver); |
| negotiate_factory->set_disable_cname_lookup(negotiate_disable_cname_lookup); |
| negotiate_factory->set_use_port(negotiate_enable_port); |
| registry_factory->RegisterSchemeFactory("negotiate", negotiate_factory); |
| } |
| #endif // defined(USE_KERBEROS) |
| |
| return registry_factory; |
| } |
| |
| int HttpAuthHandlerRegistryFactory::CreateAuthHandler( |
| HttpAuth::ChallengeTokenizer* challenge, |
| HttpAuth::Target target, |
| const GURL& origin, |
| CreateReason reason, |
| int digest_nonce_count, |
| const BoundNetLog& net_log, |
| scoped_ptr<HttpAuthHandler>* handler) { |
| std::string scheme = challenge->scheme(); |
| if (scheme.empty()) { |
| handler->reset(); |
| return ERR_INVALID_RESPONSE; |
| } |
| std::string lower_scheme = StringToLowerASCII(scheme); |
| FactoryMap::iterator it = factory_map_.find(lower_scheme); |
| if (it == factory_map_.end()) { |
| handler->reset(); |
| return ERR_UNSUPPORTED_AUTH_SCHEME; |
| } |
| DCHECK(it->second); |
| return it->second->CreateAuthHandler(challenge, target, origin, reason, |
| digest_nonce_count, net_log, handler); |
| } |
| |
| } // namespace net |