1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_HTTP_HTTP_AUTH_HANDLER_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_HTTP_HTTP_AUTH_HANDLER_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/completion_callback.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_auth.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct HttpRequestInfo; 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// HttpAuthHandler is the interface for the authentication schemes 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (basic, digest, NTLM, Negotiate). 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HttpAuthHandler objects are typically created by an HttpAuthHandlerFactory. 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HttpAuthHandler { 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuthHandler(); 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~HttpAuthHandler(); 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initializes the handler using a challenge issued by a server. 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |challenge| must be non-NULL and have already tokenized the 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // authentication scheme, but none of the tokens occuring after the 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // authentication scheme. |target| and |origin| are both stored 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for later use, and are not part of the initial challenge. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool InitFromChallenge(HttpAuth::ChallengeTokenizer* challenge, 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpAuth::Target target, 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& origin, 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Determines how the previous authorization attempt was received. 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This is called when the server/proxy responds with a 401/407 after an 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // earlier authorization attempt. Although this normally means that the 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // previous attempt was rejected, in multi-round schemes such as 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // NTLM+Negotiate it may indicate that another round of challenge+response 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // is required. For Digest authentication it may also mean that the previous 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // attempt used a stale nonce (and nonce-count) and that a new attempt should 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // be made with a different nonce provided in the challenge. 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |challenge| must be non-NULL and have already tokenized the 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // authentication scheme, but none of the tokens occuring after the 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // authentication scheme. 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual HttpAuth::AuthorizationResult HandleAnotherChallenge( 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuth::ChallengeTokenizer* challenge) = 0; 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Generates an authentication token, potentially asynchronously. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When |username| and |password| are NULL, the default credentials for 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the currently logged in user are used. |AllowsDefaultCredentials()| MUST be 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // true in this case. 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |request|, |callback|, and |auth_token| must be non-NULL. 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The return value is a net error code. 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If |OK| is returned, |*auth_token| is filled in with an authentication 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // token which can be inserted in the HTTP request. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If |ERR_IO_PENDING| is returned, |*auth_token| will be filled in 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // asynchronously and |callback| will be invoked. The lifetime of 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |request|, |callback|, and |auth_token| must last until |callback| is 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // invoked, but |username| and |password| are only used during the initial 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // call. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Otherwise, there was a problem generating a token synchronously, and the 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // value of |*auth_token| is unspecified. 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int GenerateAuthToken(const string16* username, 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16* password, 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpRequestInfo* request, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* auth_token); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // The authentication scheme as an enumerated value. 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme auth_scheme() const { 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return auth_scheme_; 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The realm value that was parsed during Init(). 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& realm() const { 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return realm_; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The challenge which was issued when creating the handler. 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string challenge() const { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return auth_challenge_; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Numeric rank based on the challenge's security level. Higher 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // numbers are better. Used by HttpAuth::ChooseBestChallenge(). 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int score() const { 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return score_; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpAuth::Target target() const { 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return target_; 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Returns the proxy or server which issued the authentication challenge 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // that this HttpAuthHandler is handling. The URL includes scheme, host, and 10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // port, but does not include path. 10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const GURL& origin() const { 10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return origin_; 10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the authentication scheme does not send the username and 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // password in the clear. 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool encrypts_identity() const { 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (properties_ & ENCRYPTS_IDENTITY) != 0; 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the authentication scheme is connection-based, for 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // example, NTLM. A connection-based authentication scheme does not support 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // preemptive authentication, and must use the same handler object 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // throughout the life of an HTTP transaction. 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool is_connection_based() const { 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (properties_ & IS_CONNECTION_BASED) != 0; 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the response to the current authentication challenge 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // requires an identity. 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(wtc): Find a better way to handle a multi-round challenge-response 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // sequence used by a connection-based authentication scheme. 12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual bool NeedsIdentity(); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns whether the default credentials may be used for the |origin| passed 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // into |InitFromChallenge|. If true, the user does not need to be prompted 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for username and password to establish credentials. 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: SSO is a potential security risk. 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(cbentzel): Add a pointer to Firefox documentation about risk. 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual bool AllowsDefaultCredentials(); 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum Property { 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ENCRYPTS_IDENTITY = 1 << 0, 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IS_CONNECTION_BASED = 1 << 1, 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initializes the handler using a challenge issued by a server. 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |challenge| must be non-NULL and have already tokenized the 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // authentication scheme, but none of the tokens occuring after the 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // authentication scheme. 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Implementations are expcted to initialize the following members: 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // scheme_, realm_, score_, properties_ 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Init(HttpAuth::ChallengeTokenizer* challenge) = 0; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |GenerateAuthTokenImpl()} is the auth-scheme specific implementation 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of generating the next auth token. Callers sohuld use |GenerateAuthToken()| 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // which will in turn call |GenerateAuthTokenImpl()| 1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual int GenerateAuthTokenImpl(const string16* username, 1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16* password, 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpRequestInfo* request, 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback, 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* auth_token) = 0; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // The auth-scheme as an enumerated value. 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuth::Scheme auth_scheme_; 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The realm. Used by "basic" and "digest". 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string realm_; 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The auth challenge. 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string auth_challenge_; 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The {scheme, host, port} for the authentication target. Used by "ntlm" 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and "negotiate" to construct the service principal name. 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL origin_; 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The score for this challenge. Higher numbers are better. 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int score_; 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Whether this authentication request is for a proxy server, or an 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // origin server. 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpAuth::Target target_; 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A bitmask of the properties of the authentication scheme. 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int properties_; 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog net_log_; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnGenerateAuthTokenComplete(int rv); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void FinishGenerateAuthToken(); 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* original_callback_; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallbackImpl<HttpAuthHandler> wrapper_callback_; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_HTTP_HTTP_AUTH_HANDLER_H_ 196