xref: /aosp_15_r20/external/cronet/net/http/http_auth_handler.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_HTTP_HTTP_AUTH_HANDLER_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_HTTP_HTTP_AUTH_HANDLER_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <string>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_once_callback.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/http/http_auth.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
14*6777b538SAndroid Build Coastguard Worker #include "url/scheme_host_port.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace net {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker class NetworkAnonymizationKey;
19*6777b538SAndroid Build Coastguard Worker class HttpAuthChallengeTokenizer;
20*6777b538SAndroid Build Coastguard Worker struct HttpRequestInfo;
21*6777b538SAndroid Build Coastguard Worker class SSLInfo;
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker // HttpAuthHandler is the interface for the authentication schemes
24*6777b538SAndroid Build Coastguard Worker // (basic, digest, NTLM, Negotiate).
25*6777b538SAndroid Build Coastguard Worker // HttpAuthHandler objects are typically created by an HttpAuthHandlerFactory.
26*6777b538SAndroid Build Coastguard Worker //
27*6777b538SAndroid Build Coastguard Worker // HttpAuthHandlers and generally created and managed by an HttpAuthController,
28*6777b538SAndroid Build Coastguard Worker // which is the interaction point between the rest of net and the HTTP auth
29*6777b538SAndroid Build Coastguard Worker // code.
30*6777b538SAndroid Build Coastguard Worker //
31*6777b538SAndroid Build Coastguard Worker // For connection-based authentication, an HttpAuthHandler handles all rounds
32*6777b538SAndroid Build Coastguard Worker // related to using a single identity. If the identity is rejected, a new
33*6777b538SAndroid Build Coastguard Worker // HttpAuthHandler must be created.
34*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE HttpAuthHandler {
35*6777b538SAndroid Build Coastguard Worker  public:
36*6777b538SAndroid Build Coastguard Worker   HttpAuthHandler();
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker   HttpAuthHandler(const HttpAuthHandler&) = delete;
39*6777b538SAndroid Build Coastguard Worker   HttpAuthHandler& operator=(const HttpAuthHandler&) = delete;
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker   virtual ~HttpAuthHandler();
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker   // Initializes the handler using a challenge issued by a server.
44*6777b538SAndroid Build Coastguard Worker   //
45*6777b538SAndroid Build Coastguard Worker   // |challenge| must be non-nullptr and have already tokenized the
46*6777b538SAndroid Build Coastguard Worker   //      authentication scheme, but none of the tokens occurring after the
47*6777b538SAndroid Build Coastguard Worker   //      authentication scheme.
48*6777b538SAndroid Build Coastguard Worker   // |target| and |scheme_host_port| are both stored for later use, and are not
49*6777b538SAndroid Build Coastguard Worker   //      part of the initial challenge.
50*6777b538SAndroid Build Coastguard Worker   // |ssl_info| must be valid if the underlying connection used a certificate.
51*6777b538SAndroid Build Coastguard Worker   // |network_anonymization_key| the NetworkAnonymizationKey associated with the
52*6777b538SAndroid Build Coastguard Worker   //      challenge. Used for host resolutions, if any are needed.
53*6777b538SAndroid Build Coastguard Worker   // |net_log| to be used for logging.
54*6777b538SAndroid Build Coastguard Worker   bool InitFromChallenge(
55*6777b538SAndroid Build Coastguard Worker       HttpAuthChallengeTokenizer* challenge,
56*6777b538SAndroid Build Coastguard Worker       HttpAuth::Target target,
57*6777b538SAndroid Build Coastguard Worker       const SSLInfo& ssl_info,
58*6777b538SAndroid Build Coastguard Worker       const NetworkAnonymizationKey& network_anonymization_key,
59*6777b538SAndroid Build Coastguard Worker       const url::SchemeHostPort& scheme_host_port,
60*6777b538SAndroid Build Coastguard Worker       const NetLogWithSource& net_log);
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker   // Determines how the previous authorization attempt was received.
63*6777b538SAndroid Build Coastguard Worker   //
64*6777b538SAndroid Build Coastguard Worker   // This is called when the server/proxy responds with a 401/407 after an
65*6777b538SAndroid Build Coastguard Worker   // earlier authorization attempt. Although this normally means that the
66*6777b538SAndroid Build Coastguard Worker   // previous attempt was rejected, in multi-round schemes such as
67*6777b538SAndroid Build Coastguard Worker   // NTLM+Negotiate it may indicate that another round of challenge+response
68*6777b538SAndroid Build Coastguard Worker   // is required. For Digest authentication it may also mean that the previous
69*6777b538SAndroid Build Coastguard Worker   // attempt used a stale nonce (and nonce-count) and that a new attempt should
70*6777b538SAndroid Build Coastguard Worker   // be made with a different nonce provided in the challenge.
71*6777b538SAndroid Build Coastguard Worker   //
72*6777b538SAndroid Build Coastguard Worker   // |challenge| must be non-nullptr and have already tokenized the
73*6777b538SAndroid Build Coastguard Worker   // authentication scheme, but none of the tokens occurring after the
74*6777b538SAndroid Build Coastguard Worker   // authentication scheme.
75*6777b538SAndroid Build Coastguard Worker   HttpAuth::AuthorizationResult HandleAnotherChallenge(
76*6777b538SAndroid Build Coastguard Worker       HttpAuthChallengeTokenizer* challenge);
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   // Generates an authentication token, potentially asynchronously.
79*6777b538SAndroid Build Coastguard Worker   //
80*6777b538SAndroid Build Coastguard Worker   // When |credentials| is nullptr, the default credentials for the currently
81*6777b538SAndroid Build Coastguard Worker   // logged in user are used. |AllowsDefaultCredentials()| MUST be true in this
82*6777b538SAndroid Build Coastguard Worker   // case.
83*6777b538SAndroid Build Coastguard Worker   //
84*6777b538SAndroid Build Coastguard Worker   // |request|, |callback|, and |auth_token| must be non-nullptr.
85*6777b538SAndroid Build Coastguard Worker   //
86*6777b538SAndroid Build Coastguard Worker   // The return value is a net error code.
87*6777b538SAndroid Build Coastguard Worker   //
88*6777b538SAndroid Build Coastguard Worker   // If |OK| is returned, |*auth_token| is filled in with an authentication
89*6777b538SAndroid Build Coastguard Worker   // token which can be inserted in the HTTP request.
90*6777b538SAndroid Build Coastguard Worker   //
91*6777b538SAndroid Build Coastguard Worker   // If |ERR_IO_PENDING| is returned, |*auth_token| will be filled in
92*6777b538SAndroid Build Coastguard Worker   // asynchronously and |callback| will be invoked. The lifetime of
93*6777b538SAndroid Build Coastguard Worker   // |request|, |callback|, and |auth_token| must last until |callback| is
94*6777b538SAndroid Build Coastguard Worker   // invoked, but |credentials| is only used during the initial call.
95*6777b538SAndroid Build Coastguard Worker   //
96*6777b538SAndroid Build Coastguard Worker   // All other return codes indicate that there was a problem generating a
97*6777b538SAndroid Build Coastguard Worker   // token, and the value of |*auth_token| is unspecified.
98*6777b538SAndroid Build Coastguard Worker   int GenerateAuthToken(const AuthCredentials* credentials,
99*6777b538SAndroid Build Coastguard Worker                         const HttpRequestInfo* request,
100*6777b538SAndroid Build Coastguard Worker                         CompletionOnceCallback callback,
101*6777b538SAndroid Build Coastguard Worker                         std::string* auth_token);
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker   // The authentication scheme as an enumerated value.
auth_scheme()104*6777b538SAndroid Build Coastguard Worker   HttpAuth::Scheme auth_scheme() const {
105*6777b538SAndroid Build Coastguard Worker     return auth_scheme_;
106*6777b538SAndroid Build Coastguard Worker   }
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker   // The realm, encoded as UTF-8. This may be empty.
realm()109*6777b538SAndroid Build Coastguard Worker   const std::string& realm() const {
110*6777b538SAndroid Build Coastguard Worker     return realm_;
111*6777b538SAndroid Build Coastguard Worker   }
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker   // The challenge which was issued when creating the handler.
challenge()114*6777b538SAndroid Build Coastguard Worker   const std::string& challenge() const { return auth_challenge_; }
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker   // Numeric rank based on the challenge's security level. Higher
117*6777b538SAndroid Build Coastguard Worker   // numbers are better. Used by HttpAuth::ChooseBestChallenge().
score()118*6777b538SAndroid Build Coastguard Worker   int score() const {
119*6777b538SAndroid Build Coastguard Worker     return score_;
120*6777b538SAndroid Build Coastguard Worker   }
121*6777b538SAndroid Build Coastguard Worker 
target()122*6777b538SAndroid Build Coastguard Worker   HttpAuth::Target target() const {
123*6777b538SAndroid Build Coastguard Worker     return target_;
124*6777b538SAndroid Build Coastguard Worker   }
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker   // Returns the proxy or server which issued the authentication challenge
127*6777b538SAndroid Build Coastguard Worker   // that this HttpAuthHandler is handling.
scheme_host_port()128*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort& scheme_host_port() const {
129*6777b538SAndroid Build Coastguard Worker     return scheme_host_port_;
130*6777b538SAndroid Build Coastguard Worker   }
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker   // Returns true if the authentication scheme does not send the username and
133*6777b538SAndroid Build Coastguard Worker   // password in the clear.
encrypts_identity()134*6777b538SAndroid Build Coastguard Worker   bool encrypts_identity() const {
135*6777b538SAndroid Build Coastguard Worker     return (properties_ & ENCRYPTS_IDENTITY) != 0;
136*6777b538SAndroid Build Coastguard Worker   }
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   // Returns true if the authentication scheme is connection-based, for
139*6777b538SAndroid Build Coastguard Worker   // example, NTLM.  A connection-based authentication scheme does not support
140*6777b538SAndroid Build Coastguard Worker   // preemptive authentication, and must use the same handler object
141*6777b538SAndroid Build Coastguard Worker   // throughout the life of an HTTP transaction.
is_connection_based()142*6777b538SAndroid Build Coastguard Worker   bool is_connection_based() const {
143*6777b538SAndroid Build Coastguard Worker     return (properties_ & IS_CONNECTION_BASED) != 0;
144*6777b538SAndroid Build Coastguard Worker   }
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker   // This HttpAuthHandler's bound NetLog.
net_log()147*6777b538SAndroid Build Coastguard Worker   const NetLogWithSource& net_log() const { return net_log_; }
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker   // If NeedsIdentity() returns true, then a subsequent call to
150*6777b538SAndroid Build Coastguard Worker   // GenerateAuthToken() must indicate which identity to use. This can be done
151*6777b538SAndroid Build Coastguard Worker   // either by passing in a non-empty set of credentials, or an empty set to
152*6777b538SAndroid Build Coastguard Worker   // force the handler to use the default credentials. The latter is only an
153*6777b538SAndroid Build Coastguard Worker   // option if AllowsDefaultCredentials() returns true.
154*6777b538SAndroid Build Coastguard Worker   //
155*6777b538SAndroid Build Coastguard Worker   // If NeedsIdentity() returns false, then the handler is already bound to an
156*6777b538SAndroid Build Coastguard Worker   // identity and GenerateAuthToken() will ignore any credentials that are
157*6777b538SAndroid Build Coastguard Worker   // passed in.
158*6777b538SAndroid Build Coastguard Worker   //
159*6777b538SAndroid Build Coastguard Worker   // TODO(wtc): Find a better way to handle a multi-round challenge-response
160*6777b538SAndroid Build Coastguard Worker   // sequence used by a connection-based authentication scheme.
161*6777b538SAndroid Build Coastguard Worker   virtual bool NeedsIdentity();
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   // Returns whether the default credentials may be used for the |origin| passed
164*6777b538SAndroid Build Coastguard Worker   // into |InitFromChallenge|. If true, the user does not need to be prompted
165*6777b538SAndroid Build Coastguard Worker   // for username and password to establish credentials.
166*6777b538SAndroid Build Coastguard Worker   // NOTE: SSO is a potential security risk.
167*6777b538SAndroid Build Coastguard Worker   // TODO(cbentzel): Add a pointer to Firefox documentation about risk.
168*6777b538SAndroid Build Coastguard Worker   virtual bool AllowsDefaultCredentials();
169*6777b538SAndroid Build Coastguard Worker 
170*6777b538SAndroid Build Coastguard Worker   // Returns whether explicit credentials can be used with this handler.  If
171*6777b538SAndroid Build Coastguard Worker   // true the user may be prompted for credentials if an implicit identity
172*6777b538SAndroid Build Coastguard Worker   // cannot be determined.
173*6777b538SAndroid Build Coastguard Worker   virtual bool AllowsExplicitCredentials();
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker  protected:
176*6777b538SAndroid Build Coastguard Worker   enum Property {
177*6777b538SAndroid Build Coastguard Worker     ENCRYPTS_IDENTITY = 1 << 0,
178*6777b538SAndroid Build Coastguard Worker     IS_CONNECTION_BASED = 1 << 1,
179*6777b538SAndroid Build Coastguard Worker   };
180*6777b538SAndroid Build Coastguard Worker 
181*6777b538SAndroid Build Coastguard Worker   // Initializes the handler using a challenge issued by a server.
182*6777b538SAndroid Build Coastguard Worker   // |challenge| must be non-nullptr and have already tokenized the
183*6777b538SAndroid Build Coastguard Worker   // authentication scheme, but none of the tokens occurring after the
184*6777b538SAndroid Build Coastguard Worker   // authentication scheme.
185*6777b538SAndroid Build Coastguard Worker   //
186*6777b538SAndroid Build Coastguard Worker   // If the request was sent over an encrypted connection, |ssl_info| is valid
187*6777b538SAndroid Build Coastguard Worker   // and describes the connection.
188*6777b538SAndroid Build Coastguard Worker   //
189*6777b538SAndroid Build Coastguard Worker   // NetworkAnonymizationKey is the NetworkAnonymizationKey associated with the
190*6777b538SAndroid Build Coastguard Worker   // request.
191*6777b538SAndroid Build Coastguard Worker   //
192*6777b538SAndroid Build Coastguard Worker   // Implementations are expected to initialize the following members:
193*6777b538SAndroid Build Coastguard Worker   // scheme_, realm_, score_, properties_
194*6777b538SAndroid Build Coastguard Worker   virtual bool Init(
195*6777b538SAndroid Build Coastguard Worker       HttpAuthChallengeTokenizer* challenge,
196*6777b538SAndroid Build Coastguard Worker       const SSLInfo& ssl_info,
197*6777b538SAndroid Build Coastguard Worker       const NetworkAnonymizationKey& network_anonymization_key) = 0;
198*6777b538SAndroid Build Coastguard Worker 
199*6777b538SAndroid Build Coastguard Worker   // |GenerateAuthTokenImpl()} is the auth-scheme specific implementation
200*6777b538SAndroid Build Coastguard Worker   // of generating the next auth token. Callers should use |GenerateAuthToken()|
201*6777b538SAndroid Build Coastguard Worker   // which will in turn call |GenerateAuthTokenImpl()|
202*6777b538SAndroid Build Coastguard Worker   virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
203*6777b538SAndroid Build Coastguard Worker                                     const HttpRequestInfo* request,
204*6777b538SAndroid Build Coastguard Worker                                     CompletionOnceCallback callback,
205*6777b538SAndroid Build Coastguard Worker                                     std::string* auth_token) = 0;
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker   // See HandleAnotherChallenge() above. HandleAuthChallengeImpl is the
208*6777b538SAndroid Build Coastguard Worker   // scheme-specific implementation. Callers should use HandleAnotherChallenge()
209*6777b538SAndroid Build Coastguard Worker   // instead.
210*6777b538SAndroid Build Coastguard Worker   virtual HttpAuth::AuthorizationResult HandleAnotherChallengeImpl(
211*6777b538SAndroid Build Coastguard Worker       HttpAuthChallengeTokenizer* challenge) = 0;
212*6777b538SAndroid Build Coastguard Worker 
213*6777b538SAndroid Build Coastguard Worker   // The auth-scheme as an enumerated value.
214*6777b538SAndroid Build Coastguard Worker   HttpAuth::Scheme auth_scheme_ = HttpAuth::AUTH_SCHEME_MAX;
215*6777b538SAndroid Build Coastguard Worker 
216*6777b538SAndroid Build Coastguard Worker   // The realm, encoded as UTF-8. Used by "basic" and "digest".
217*6777b538SAndroid Build Coastguard Worker   std::string realm_;
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker   // The auth challenge.
220*6777b538SAndroid Build Coastguard Worker   std::string auth_challenge_;
221*6777b538SAndroid Build Coastguard Worker 
222*6777b538SAndroid Build Coastguard Worker   // The {scheme, host, port} for the authentication target.  Used by "ntlm"
223*6777b538SAndroid Build Coastguard Worker   // and "negotiate" to construct the service principal name.
224*6777b538SAndroid Build Coastguard Worker   url::SchemeHostPort scheme_host_port_;
225*6777b538SAndroid Build Coastguard Worker 
226*6777b538SAndroid Build Coastguard Worker   // The score for this challenge. Higher numbers are better.
227*6777b538SAndroid Build Coastguard Worker   int score_ = -1;
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   // Whether this authentication request is for a proxy server, or an
230*6777b538SAndroid Build Coastguard Worker   // origin server.
231*6777b538SAndroid Build Coastguard Worker   HttpAuth::Target target_ = HttpAuth::AUTH_NONE;
232*6777b538SAndroid Build Coastguard Worker 
233*6777b538SAndroid Build Coastguard Worker   // A bitmask of the properties of the authentication scheme.
234*6777b538SAndroid Build Coastguard Worker   int properties_ = -1;
235*6777b538SAndroid Build Coastguard Worker 
236*6777b538SAndroid Build Coastguard Worker  private:
237*6777b538SAndroid Build Coastguard Worker   void OnGenerateAuthTokenComplete(int rv);
238*6777b538SAndroid Build Coastguard Worker   void FinishGenerateAuthToken(int rv);
239*6777b538SAndroid Build Coastguard Worker 
240*6777b538SAndroid Build Coastguard Worker   // NetLog that should be used for logging events generated by this
241*6777b538SAndroid Build Coastguard Worker   // HttpAuthHandler.
242*6777b538SAndroid Build Coastguard Worker   NetLogWithSource net_log_;
243*6777b538SAndroid Build Coastguard Worker 
244*6777b538SAndroid Build Coastguard Worker   CompletionOnceCallback callback_;
245*6777b538SAndroid Build Coastguard Worker };
246*6777b538SAndroid Build Coastguard Worker 
247*6777b538SAndroid Build Coastguard Worker }  // namespace net
248*6777b538SAndroid Build Coastguard Worker 
249*6777b538SAndroid Build Coastguard Worker #endif  // NET_HTTP_HTTP_AUTH_HANDLER_H_
250