1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
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 <string>
10#include <vector>
11
12#include "base/memory/scoped_ptr.h"
13#include "net/base/net_export.h"
14#include "net/http/http_auth.h"
15#include "net/http/url_security_manager.h"
16
17class GURL;
18
19namespace net {
20
21class BoundNetLog;
22class HostResolver;
23class HttpAuthHandler;
24class HttpAuthHandlerRegistryFactory;
25
26// An HttpAuthHandlerFactory is used to create HttpAuthHandler objects.
27// The HttpAuthHandlerFactory object _must_ outlive any of the HttpAuthHandler
28// objects that it creates.
29class NET_EXPORT HttpAuthHandlerFactory {
30 public:
31  enum CreateReason {
32    CREATE_CHALLENGE,     // Create a handler in response to a challenge.
33    CREATE_PREEMPTIVE,    // Create a handler preemptively.
34  };
35
36  HttpAuthHandlerFactory() : url_security_manager_(NULL) {}
37  virtual ~HttpAuthHandlerFactory() {}
38
39  // Sets an URL security manager.  HttpAuthHandlerFactory doesn't own the URL
40  // security manager, and the URL security manager should outlive this object.
41  void set_url_security_manager(URLSecurityManager* url_security_manager) {
42    url_security_manager_ = url_security_manager;
43  }
44
45  // Retrieves the associated URL security manager.
46  URLSecurityManager* url_security_manager() {
47    return url_security_manager_;
48  }
49
50  // Creates an HttpAuthHandler object based on the authentication
51  // challenge specified by |*challenge|. |challenge| must point to a valid
52  // non-NULL tokenizer.
53  //
54  // If an HttpAuthHandler object is successfully created it is passed back to
55  // the caller through |*handler| and OK is returned.
56  //
57  // If |*challenge| specifies an unsupported authentication scheme, |*handler|
58  // is set to NULL and ERR_UNSUPPORTED_AUTH_SCHEME is returned.
59  //
60  // If |*challenge| is improperly formed, |*handler| is set to NULL and
61  // ERR_INVALID_RESPONSE is returned.
62  //
63  // |create_reason| indicates why the handler is being created. This is used
64  // since NTLM and Negotiate schemes do not support preemptive creation.
65  //
66  // |digest_nonce_count| is specifically intended for the Digest authentication
67  // scheme, and indicates the number of handlers generated for a particular
68  // server nonce challenge.
69  //
70  // For the NTLM and Negotiate handlers:
71  // If |origin| does not match the authentication method's filters for
72  // the specified |target|, ERR_INVALID_AUTH_CREDENTIALS is returned.
73  // NOTE: This will apply to ALL |origin| values if the filters are empty.
74  //
75  // |*challenge| should not be reused after a call to |CreateAuthHandler()|,
76  virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
77                                HttpAuth::Target target,
78                                const GURL& origin,
79                                CreateReason create_reason,
80                                int digest_nonce_count,
81                                const BoundNetLog& net_log,
82                                scoped_ptr<HttpAuthHandler>* handler) = 0;
83
84  // Creates an HTTP authentication handler based on the authentication
85  // challenge string |challenge|.
86  // This is a convenience function which creates a ChallengeTokenizer for
87  // |challenge| and calls |CreateAuthHandler|. See |CreateAuthHandler| for
88  // more details on return values.
89  int CreateAuthHandlerFromString(const std::string& challenge,
90                                  HttpAuth::Target target,
91                                  const GURL& origin,
92                                  const BoundNetLog& net_log,
93                                  scoped_ptr<HttpAuthHandler>* handler);
94
95  // Creates an HTTP authentication handler based on the authentication
96  // challenge string |challenge|.
97  // This is a convenience function which creates a ChallengeTokenizer for
98  // |challenge| and calls |CreateAuthHandler|. See |CreateAuthHandler| for
99  // more details on return values.
100  int CreatePreemptiveAuthHandlerFromString(
101      const std::string& challenge,
102      HttpAuth::Target target,
103      const GURL& origin,
104      int digest_nonce_count,
105      const BoundNetLog& net_log,
106      scoped_ptr<HttpAuthHandler>* handler);
107
108  // Creates a standard HttpAuthHandlerRegistryFactory. The caller is
109  // responsible for deleting the factory.
110  // The default factory supports Basic, Digest, NTLM, and Negotiate schemes.
111  //
112  // |resolver| is used by the Negotiate authentication handler to perform
113  // CNAME lookups to generate a Kerberos SPN for the server. It must be
114  // non-NULL.  |resolver| must remain valid for the lifetime of the
115  // HttpAuthHandlerRegistryFactory and any HttpAuthHandlers created by said
116  // factory.
117  static HttpAuthHandlerRegistryFactory* CreateDefault(HostResolver* resolver);
118
119 private:
120  // The URL security manager
121  URLSecurityManager* url_security_manager_;
122
123  DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerFactory);
124};
125
126// The HttpAuthHandlerRegistryFactory dispatches create requests out
127// to other factories based on the auth scheme.
128class NET_EXPORT HttpAuthHandlerRegistryFactory
129    : public HttpAuthHandlerFactory {
130 public:
131  HttpAuthHandlerRegistryFactory();
132  virtual ~HttpAuthHandlerRegistryFactory();
133
134  // Sets an URL security manager into the factory associated with |scheme|.
135  void SetURLSecurityManager(const std::string& scheme,
136                             URLSecurityManager* url_security_manager);
137
138  // Registers a |factory| that will be used for a particular HTTP
139  // authentication scheme such as Basic, Digest, or Negotiate.
140  // The |*factory| object is assumed to be new-allocated, and its lifetime
141  // will be managed by this HttpAuthHandlerRegistryFactory object (including
142  // deleting it when it is no longer used.
143  // A NULL |factory| value means that HttpAuthHandlers's will not be created
144  // for |scheme|. If a factory object used to exist for |scheme|, it will be
145  // deleted.
146  void RegisterSchemeFactory(const std::string& scheme,
147                             HttpAuthHandlerFactory* factory);
148
149  // Retrieve the factory for the specified |scheme|. If no factory exists
150  // for the |scheme|, NULL is returned. The returned factory must not be
151  // deleted by the caller, and it is guaranteed to be valid until either
152  // a new factory is registered for the same scheme, or until this
153  // registry factory is destroyed.
154  HttpAuthHandlerFactory* GetSchemeFactory(const std::string& scheme) const;
155
156  // Creates an HttpAuthHandlerRegistryFactory.
157  //
158  // |supported_schemes| is a list of authentication schemes. Valid values
159  // include "basic", "digest", "ntlm", and "negotiate", where case matters.
160  //
161  // |security_manager| is used by the NTLM and Negotiate authenticators
162  // to determine which servers Integrated Authentication can be used with. If
163  // NULL, Integrated Authentication will not be used with any server.
164  //
165  // |host_resolver| is used by the Negotiate authentication handler to perform
166  // CNAME lookups to generate a Kerberos SPN for the server. If the "negotiate"
167  // scheme is used and |negotiate_disable_cname_lookup| is false,
168  // |host_resolver| must not be NULL.
169  //
170  // |gssapi_library_name| specifies the name of the GSSAPI library that will
171  // be loaded on all platforms except Windows.
172  //
173  // |negotiate_disable_cname_lookup| and |negotiate_enable_port| both control
174  // how Negotiate does SPN generation, by default these should be false.
175  static HttpAuthHandlerRegistryFactory* Create(
176      const std::vector<std::string>& supported_schemes,
177      URLSecurityManager* security_manager,
178      HostResolver* host_resolver,
179      const std::string& gssapi_library_name,
180      bool negotiate_disable_cname_lookup,
181      bool negotiate_enable_port);
182
183  // Creates an auth handler by dispatching out to the registered factories
184  // based on the first token in |challenge|.
185  virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
186                                HttpAuth::Target target,
187                                const GURL& origin,
188                                CreateReason reason,
189                                int digest_nonce_count,
190                                const BoundNetLog& net_log,
191                                scoped_ptr<HttpAuthHandler>* handler) OVERRIDE;
192
193 private:
194  typedef std::map<std::string, HttpAuthHandlerFactory*> FactoryMap;
195
196  FactoryMap factory_map_;
197  DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerRegistryFactory);
198};
199
200}  // namespace net
201
202#endif  // NET_HTTP_HTTP_AUTH_HANDLER_FACTORY_H_
203