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