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.
5 #include "net/http/http_auth_handler_factory.h"
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"
15 #if defined(USE_KERBEROS)
16 #include "net/http/http_auth_handler_negotiate.h"
21 int HttpAuthHandlerFactory::CreateAuthHandlerFromString(
22 const std::string
& challenge
,
23 HttpAuth::Target target
,
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,
32 int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString(
33 const std::string
& challenge
,
34 HttpAuth::Target target
,
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
);
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());
55 #if defined(USE_KERBEROS)
56 HttpAuthHandlerNegotiate::Factory
* negotiate_factory
=
57 new HttpAuthHandlerNegotiate::Factory();
59 negotiate_factory
->set_library(new GSSAPISharedLibrary(std::string()));
61 negotiate_factory
->set_library(new SSPILibraryDefault());
63 negotiate_factory
->set_host_resolver(host_resolver
);
64 registry_factory
->RegisterSchemeFactory("negotiate", negotiate_factory
);
65 #endif // defined(USE_KERBEROS)
67 HttpAuthHandlerNTLM::Factory
* ntlm_factory
=
68 new HttpAuthHandlerNTLM::Factory();
70 ntlm_factory
->set_sspi_library(new SSPILibraryDefault());
72 registry_factory
->RegisterSchemeFactory("ntlm", ntlm_factory
);
73 return registry_factory
;
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();
87 HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory() {
90 HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() {
91 STLDeleteContainerPairSecondPointers(factory_map_
.begin(),
95 void HttpAuthHandlerRegistryFactory::SetURLSecurityManager(
96 const std::string
& scheme
,
97 URLSecurityManager
* security_manager
) {
98 HttpAuthHandlerFactory
* factory
= GetSchemeFactory(scheme
);
100 factory
->set_url_security_manager(security_manager
);
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()) {
112 factory_map_
[lower_scheme
] = factory
;
114 factory_map_
.erase(it
);
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.
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
);
148 ntlm_factory
->set_sspi_library(new SSPILibraryDefault());
150 registry_factory
->RegisterSchemeFactory("ntlm", ntlm_factory
);
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());
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
);
169 #endif // defined(USE_KERBEROS)
171 return registry_factory
;
174 int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
175 HttpAuth::ChallengeTokenizer
* challenge
,
176 HttpAuth::Target target
,
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()) {
185 return ERR_INVALID_RESPONSE
;
187 std::string lower_scheme
= StringToLowerASCII(scheme
);
188 FactoryMap::iterator it
= factory_map_
.find(lower_scheme
);
189 if (it
== factory_map_
.end()) {
191 return ERR_UNSUPPORTED_AUTH_SCHEME
;
194 return it
->second
->CreateAuthHandler(challenge
, target
, origin
, reason
,
195 digest_nonce_count
, net_log
, handler
);