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