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