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