1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
|
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_HTTP_HTTP_AUTH_HANDLER_FACTORY_H_
#define NET_HTTP_HTTP_AUTH_HANDLER_FACTORY_H_
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_mechanism.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/url_security_manager.h"
#include "net/net_buildflags.h"
namespace url {
class SchemeHostPort;
}
namespace net {
class HostResolver;
class HttpAuthChallengeTokenizer;
class HttpAuthHandler;
class HttpAuthHandlerRegistryFactory;
class HttpAuthPreferences;
class NetLogWithSource;
class NetworkAnonymizationKey;
// An HttpAuthHandlerFactory is used to create HttpAuthHandler objects.
// The HttpAuthHandlerFactory object _must_ outlive any of the HttpAuthHandler
// objects that it creates.
class NET_EXPORT HttpAuthHandlerFactory {
public:
enum CreateReason {
CREATE_CHALLENGE, // Create a handler in response to a challenge.
CREATE_PREEMPTIVE, // Create a handler preemptively.
};
HttpAuthHandlerFactory() = default;
HttpAuthHandlerFactory(const HttpAuthHandlerFactory&) = delete;
HttpAuthHandlerFactory& operator=(const HttpAuthHandlerFactory&) = delete;
virtual ~HttpAuthHandlerFactory() = default;
// Sets the source of the HTTP authentication preferences.
// HttpAuthHandlerFactory doesn't own the preferences, and the
// HttpAuthPreferences object should outlive the factory and any handlers it
// creates.
void set_http_auth_preferences(
const HttpAuthPreferences* http_auth_preferences) {
http_auth_preferences_ = http_auth_preferences;
}
// Retrieves the associated URL security manager.
const HttpAuthPreferences* http_auth_preferences() const {
return http_auth_preferences_;
}
// Creates an HttpAuthHandler object based on the authentication challenge
// specified by |*challenge|. |challenge| must point to a valid tokenizer.
//
// If an HttpAuthHandler object is successfully created it is passed back to
// the caller through |*handler| and OK is returned.
//
// If |*challenge| specifies an unsupported authentication scheme, |*handler|
// is set to nullptr and ERR_UNSUPPORTED_AUTH_SCHEME is returned.
//
// If |*challenge| is improperly formed, |*handler| is set to nullptr and
// ERR_INVALID_RESPONSE is returned.
//
// |create_reason| indicates why the handler is being created. This is used
// since NTLM and Negotiate schemes do not support preemptive creation.
//
// |digest_nonce_count| is specifically intended for the Digest authentication
// scheme, and indicates the number of handlers generated for a particular
// server nonce challenge.
//
// |ssl_info| is valid if the authentication session is being established over
// a secure connection.
//
// For the NTLM and Negotiate handlers:
// If |origin| does not match the authentication method's filters for
// the specified |target|, ERR_INVALID_AUTH_CREDENTIALS is returned.
// NOTE: This will apply to ALL |origin| values if the filters are empty.
//
// |*challenge| should not be reused after a call to |CreateAuthHandler()|,
//
// |host_resolver| is used by the Negotiate authentication handler to perform
// CNAME lookups to generate a Kerberos SPN for the server. If the "negotiate"
// scheme is used and the factory was created with
// |negotiate_disable_cname_lookup| false, |host_resolver| must not be null,
// and it must remain valid for the lifetime of the created |handler|.
virtual int CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
const NetworkAnonymizationKey& network_anonymization_key,
const url::SchemeHostPort& scheme_host_port,
CreateReason create_reason,
int digest_nonce_count,
const NetLogWithSource& net_log,
HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler) = 0;
// Creates an HTTP authentication handler based on the authentication
// challenge string |challenge|.
// This is a convenience function which creates a ChallengeTokenizer for
// |challenge| and calls |CreateAuthHandler|. See |CreateAuthHandler| for
// more details on return values.
int CreateAuthHandlerFromString(
std::string_view challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
const NetworkAnonymizationKey& network_anonymization_key,
const url::SchemeHostPort& scheme_host_port,
const NetLogWithSource& net_log,
HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler);
// Creates an HTTP authentication handler based on the authentication
// challenge string |challenge|.
// This is a convenience function which creates a ChallengeTokenizer for
// |challenge| and calls |CreateAuthHandler|. See |CreateAuthHandler| for
// more details on return values.
int CreatePreemptiveAuthHandlerFromString(
const std::string& challenge,
HttpAuth::Target target,
const NetworkAnonymizationKey& network_anonymization_key,
const url::SchemeHostPort& scheme_host_port,
int digest_nonce_count,
const NetLogWithSource& net_log,
HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler);
// Creates a standard HttpAuthHandlerRegistryFactory. The caller is
// responsible for deleting the factory.
// The default factory supports Basic, Digest, NTLM, and Negotiate schemes.
//
// |negotiate_auth_system_factory| is used to override the default auth system
// used by the Negotiate authentication handler.
static std::unique_ptr<HttpAuthHandlerRegistryFactory> CreateDefault(
const HttpAuthPreferences* prefs = nullptr
#if BUILDFLAG(USE_EXTERNAL_GSSAPI)
,
const std::string& gssapi_library_name = ""
#endif
#if BUILDFLAG(USE_KERBEROS)
,
HttpAuthMechanismFactory negotiate_auth_system_factory =
HttpAuthMechanismFactory()
#endif
);
private:
// The preferences for HTTP authentication.
raw_ptr<const HttpAuthPreferences> http_auth_preferences_ = nullptr;
};
// The HttpAuthHandlerRegistryFactory dispatches create requests out
// to other factories based on the auth scheme.
class NET_EXPORT HttpAuthHandlerRegistryFactory
: public HttpAuthHandlerFactory {
public:
explicit HttpAuthHandlerRegistryFactory(
const HttpAuthPreferences* http_auth_preferences);
HttpAuthHandlerRegistryFactory(const HttpAuthHandlerRegistryFactory&) =
delete;
HttpAuthHandlerRegistryFactory& operator=(
const HttpAuthHandlerRegistryFactory&) = delete;
~HttpAuthHandlerRegistryFactory() override;
// Sets the preferences into the factory associated with |scheme|.
void SetHttpAuthPreferences(const std::string& scheme,
const HttpAuthPreferences* prefs);
// Registers a |factory| that will be used for a particular HTTP
// authentication scheme such as Basic, Digest, or Negotiate.
// The |*factory| object is assumed to be new-allocated, and its lifetime
// will be managed by this HttpAuthHandlerRegistryFactory object (including
// deleting it when it is no longer used.
// A nullptr |factory| value means that HttpAuthHandlers's will not be created
// for |scheme|. If a factory object used to exist for |scheme|, it will be
// deleted.
void RegisterSchemeFactory(const std::string& scheme,
std::unique_ptr<HttpAuthHandlerFactory> factory);
// Creates an HttpAuthHandlerRegistryFactory.
//
// |prefs| is a pointer to the (single) authentication preferences object.
// That object tracks preference, and hence policy, updates relevant to HTTP
// authentication, and provides the current values of the preferences.
//
// |negotiate_auth_system_factory| is used to override the default auth system
// used by the Negotiate authentication handler.
static std::unique_ptr<HttpAuthHandlerRegistryFactory> Create(
const HttpAuthPreferences* prefs
#if BUILDFLAG(USE_EXTERNAL_GSSAPI)
,
const std::string& gssapi_library_name = ""
#endif
#if BUILDFLAG(USE_KERBEROS)
,
HttpAuthMechanismFactory negotiate_auth_system_factory =
HttpAuthMechanismFactory()
#endif
);
// Creates an auth handler by dispatching out to the registered factories
// based on the first token in |challenge|.
//
// |host_resolver| is used by the Negotiate authentication handler to perform
// CNAME lookups to generate a Kerberos SPN for the server. If the "negotiate"
// scheme is used and the factory was created with
// |negotiate_disable_cname_lookup| false, |host_resolver| must not be null,
// and it must remain valid for the lifetime of the created |handler|.
int CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
const NetworkAnonymizationKey& network_anonymization_key,
const url::SchemeHostPort& scheme_host_port,
CreateReason reason,
int digest_nonce_count,
const NetLogWithSource& net_log,
HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler) override;
#if BUILDFLAG(USE_KERBEROS) && !BUILDFLAG(IS_ANDROID) && BUILDFLAG(IS_POSIX)
std::optional<std::string> GetNegotiateLibraryNameForTesting() const;
#endif
// Returns true if the scheme is allowed to be used for all origins. An auth
// handler may still be created for an origin if that origin is allowed by
// policy to use all supported auth handlers.
bool IsSchemeAllowedForTesting(const std::string& scheme) const;
private:
bool IsSchemeAllowed(const std::string& scheme) const;
// Retrieve the factory for the specified |scheme|. If no factory exists
// for the |scheme|, nullptr is returned. The returned factory must not be
// deleted by the caller, and it is guaranteed to be valid until either
// a new factory is registered for the same scheme, or until this
// registry factory is destroyed.
HttpAuthHandlerFactory* GetSchemeFactory(const std::string& scheme) const;
using FactoryMap =
std::map<std::string, std::unique_ptr<HttpAuthHandlerFactory>>;
FactoryMap factory_map_;
};
} // namespace net
#endif // NET_HTTP_HTTP_AUTH_HANDLER_FACTORY_H_
|