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