1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_HTTP_HTTP_AUTH_CONTROLLER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h"
163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/non_thread_safe.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/completion_callback.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_auth.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AuthChallengeInfo;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HttpAuthHandler;
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass HttpAuthHandlerFactory;
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass HttpAuthCache;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HttpRequestHeaders;
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct HttpRequestInfo;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass HttpAuthController : public base::RefCounted<HttpAuthController>,
323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                           public base::NonThreadSafe {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The arguments are self explanatory except possibly for |auth_url|, which
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should be both the auth target and auth path in a single url argument.
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HttpAuthController(HttpAuth::Target target,
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                     const GURL& auth_url,
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                     HttpAuthCache* http_auth_cache,
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                     HttpAuthHandlerFactory* http_auth_handler_factory);
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Generate an authentication token for |target| if necessary. The return
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // value is a net error code. |OK| will be returned both in the case that
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a token is correctly generated synchronously, as well as when no tokens
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // were necessary.
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int MaybeGenerateAuthToken(const HttpRequestInfo* request,
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     CompletionCallback* callback,
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     const BoundNetLog& net_log);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Adds either the proxy auth header, or the origin server auth header,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as specified by |target_|.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void AddAuthorizationHeader(
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HttpRequestHeaders* authorization_headers);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Checks for and handles HTTP status code 401 or 407.
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |HandleAuthChallenge()| returns OK on success, or a network error code
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // otherwise. It may also populate |auth_info_|.
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers,
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  bool do_not_send_server_auth,
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  bool establishing_tunnel,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const BoundNetLog& net_log);
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Store the supplied credentials and prepare to restart the auth.
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void ResetAuth(const string16& username,
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         const string16& password);
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual bool HaveAuthHandler() const;
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual bool HaveAuth() const;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual scoped_refptr<AuthChallengeInfo> auth_info();
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual bool IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const;
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void DisableAuthScheme(HttpAuth::Scheme scheme);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Actions for InvalidateCurrentHandler()
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  enum InvalidateHandlerAction {
78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS,
79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    INVALIDATE_HANDLER
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  };
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // So that we can mock this object.
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class base::RefCounted<HttpAuthController>;
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~HttpAuthController();
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Searches the auth cache for an entry that encompasses the request's path.
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If such an entry is found, updates |identity_| and |handler_| with the
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // cache entry's data and returns true.
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool SelectPreemptiveAuth(const BoundNetLog& net_log);
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Invalidates the current handler.  If |action| is
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, then also invalidate
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // the cached credentials used by the handler.
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  void InvalidateCurrentHandler(InvalidateHandlerAction action);
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Invalidates any auth cache entries after authentication has failed.
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The identity that was rejected is |identity_|.
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void InvalidateRejectedAuthFromCache();
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sets |identity_| to the next identity that the transaction should try. It
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // chooses candidates by searching the auth cache and the URL for a
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // username:password. Returns true if an identity was found.
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool SelectNextAuthIdentityToTry();
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Populates auth_info_ with the challenge information, so that
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // URLRequestHttpJob can prompt for a username/password.
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void PopulateAuthChallenge();
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If |result| indicates a permanent failure, disables the current
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // auth scheme for this controller and returns true.  Returns false
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // otherwise.
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool DisableOnAuthHandlerResult(int result);
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnIOComplete(int result);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Indicates if this handler is for Proxy auth or Server auth.
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpAuth::Target target_;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Holds the {scheme, host, path, port} for the authentication target.
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL auth_url_;
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Holds the {scheme, host, port} for the authentication target.
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL auth_origin_;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The absolute path of the resource needing authentication.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For proxy authentication the path is empty.
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string auth_path_;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |handler_| encapsulates the logic for the particular auth-scheme.
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This includes the challenge's parameters. If NULL, then there is no
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // associated auth handler.
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<HttpAuthHandler> handler_;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |identity_| holds the (username/password) that should be used by
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the handler_ to generate credentials. This identity can come from
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a number of places (url, cache, prompt).
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpAuth::Identity identity_;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |auth_token_| contains the opaque string to pass to the proxy or
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // server to authenticate the client.
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string auth_token_;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Contains information about the auth challenge.
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AuthChallengeInfo> auth_info_;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // True if we've used the username/password embedded in the URL.  This
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // makes sure we use the embedded identity only once for the transaction,
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // preventing an infinite auth restart loop.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool embedded_identity_used_;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // True if default credentials have already been tried for this transaction
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in response to an HTTP authentication challenge.
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool default_credentials_used_;
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // These two are owned by the HttpNetworkSession/IOThread, which own the
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // objects which reference |this|.  Therefore, these raw pointers are valid
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // for the lifetime of this object.
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HttpAuthCache* const http_auth_cache_;
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HttpAuthHandlerFactory* const http_auth_handler_factory_;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::set<HttpAuth::Scheme> disabled_schemes_;
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CompletionCallbackImpl<HttpAuthController> io_callback_;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CompletionCallback* user_callback_;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // NET_HTTP_HTTP_AUTH_CONTROLLER_H_
171