// 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* 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* 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& supported_schemes, const std::string& scheme) { std::vector::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& 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* 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