|  | // 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 |