Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / http / http_auth_gssapi_posix.h
blob73502c9b4353bbb46dc87f8534048f4fef68fcec
1 // Copyright (c) 2012 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.
5 #ifndef NET_HTTP_HTTP_AUTH_GSSAPI_POSIX_H_
6 #define NET_HTTP_HTTP_AUTH_GSSAPI_POSIX_H_
8 #include <string>
10 #include "base/gtest_prod_util.h"
11 #include "base/native_library.h"
12 #include "net/base/completion_callback.h"
13 #include "net/base/net_export.h"
14 #include "net/http/http_auth.h"
16 #if defined(OS_MACOSX)
17 // The OSX 10.9+ SDKs mark the functions in Kereberos.framework as deprecated,
18 // so the warnings must be manually suppressed.
19 #if defined(MAC_OS_X_VERSION_10_9) && \
20 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
21 #define GSSKRB_APPLE_DEPRECATED(x)
22 #endif
24 // Chrome supports OSX 10.6, which doesn't have access to GSS.framework. Chrome
25 // always dlopens libgssapi_krb5.dylib, which is provided by
26 // Kerberos.framework. On OSX 10.7+ this is an ABI compatible shim that loads
27 // GSS.framework.
28 #include <Kerberos/gssapi.h>
29 #elif defined(OS_FREEBSD)
30 #include <gssapi/gssapi.h>
31 #else
32 #include <gssapi.h>
33 #endif
35 namespace net {
37 class HttpAuthChallengeTokenizer;
39 // Mechanism OID for GSSAPI. We always use SPNEGO.
40 NET_EXPORT_PRIVATE extern gss_OID CHROME_GSS_SPNEGO_MECH_OID_DESC;
42 // GSSAPILibrary is introduced so unit tests can mock the calls to the GSSAPI
43 // library. The default implementation attempts to load one of the standard
44 // GSSAPI library implementations, then simply passes the arguments on to
45 // that implementation.
46 class NET_EXPORT_PRIVATE GSSAPILibrary {
47 public:
48 virtual ~GSSAPILibrary() {}
50 // Initializes the library, including any necessary dynamic libraries.
51 // This is done separately from construction (which happens at startup time)
52 // in order to delay work until the class is actually needed.
53 virtual bool Init() = 0;
55 // These methods match the ones in the GSSAPI library.
56 virtual OM_uint32 import_name(
57 OM_uint32* minor_status,
58 const gss_buffer_t input_name_buffer,
59 const gss_OID input_name_type,
60 gss_name_t* output_name) = 0;
61 virtual OM_uint32 release_name(
62 OM_uint32* minor_status,
63 gss_name_t* input_name) = 0;
64 virtual OM_uint32 release_buffer(
65 OM_uint32* minor_status,
66 gss_buffer_t buffer) = 0;
67 virtual OM_uint32 display_name(
68 OM_uint32* minor_status,
69 const gss_name_t input_name,
70 gss_buffer_t output_name_buffer,
71 gss_OID* output_name_type) = 0;
72 virtual OM_uint32 display_status(
73 OM_uint32* minor_status,
74 OM_uint32 status_value,
75 int status_type,
76 const gss_OID mech_type,
77 OM_uint32* message_contex,
78 gss_buffer_t status_string) = 0;
79 virtual OM_uint32 init_sec_context(
80 OM_uint32* minor_status,
81 const gss_cred_id_t initiator_cred_handle,
82 gss_ctx_id_t* context_handle,
83 const gss_name_t target_name,
84 const gss_OID mech_type,
85 OM_uint32 req_flags,
86 OM_uint32 time_req,
87 const gss_channel_bindings_t input_chan_bindings,
88 const gss_buffer_t input_token,
89 gss_OID* actual_mech_type,
90 gss_buffer_t output_token,
91 OM_uint32* ret_flags,
92 OM_uint32* time_rec) = 0;
93 virtual OM_uint32 wrap_size_limit(
94 OM_uint32* minor_status,
95 const gss_ctx_id_t context_handle,
96 int conf_req_flag,
97 gss_qop_t qop_req,
98 OM_uint32 req_output_size,
99 OM_uint32* max_input_size) = 0;
100 virtual OM_uint32 delete_sec_context(
101 OM_uint32* minor_status,
102 gss_ctx_id_t* context_handle,
103 gss_buffer_t output_token) = 0;
104 virtual OM_uint32 inquire_context(
105 OM_uint32* minor_status,
106 const gss_ctx_id_t context_handle,
107 gss_name_t* src_name,
108 gss_name_t* targ_name,
109 OM_uint32* lifetime_rec,
110 gss_OID* mech_type,
111 OM_uint32* ctx_flags,
112 int* locally_initiated,
113 int* open) = 0;
116 // GSSAPISharedLibrary class is defined here so that unit tests can access it.
117 class NET_EXPORT_PRIVATE GSSAPISharedLibrary : public GSSAPILibrary {
118 public:
119 // If |gssapi_library_name| is empty, hard-coded default library names are
120 // used.
121 explicit GSSAPISharedLibrary(const std::string& gssapi_library_name);
122 ~GSSAPISharedLibrary() override;
124 // GSSAPILibrary methods:
125 bool Init() override;
126 OM_uint32 import_name(OM_uint32* minor_status,
127 const gss_buffer_t input_name_buffer,
128 const gss_OID input_name_type,
129 gss_name_t* output_name) override;
130 OM_uint32 release_name(OM_uint32* minor_status,
131 gss_name_t* input_name) override;
132 OM_uint32 release_buffer(OM_uint32* minor_status,
133 gss_buffer_t buffer) override;
134 OM_uint32 display_name(OM_uint32* minor_status,
135 const gss_name_t input_name,
136 gss_buffer_t output_name_buffer,
137 gss_OID* output_name_type) override;
138 OM_uint32 display_status(OM_uint32* minor_status,
139 OM_uint32 status_value,
140 int status_type,
141 const gss_OID mech_type,
142 OM_uint32* message_contex,
143 gss_buffer_t status_string) override;
144 OM_uint32 init_sec_context(OM_uint32* minor_status,
145 const gss_cred_id_t initiator_cred_handle,
146 gss_ctx_id_t* context_handle,
147 const gss_name_t target_name,
148 const gss_OID mech_type,
149 OM_uint32 req_flags,
150 OM_uint32 time_req,
151 const gss_channel_bindings_t input_chan_bindings,
152 const gss_buffer_t input_token,
153 gss_OID* actual_mech_type,
154 gss_buffer_t output_token,
155 OM_uint32* ret_flags,
156 OM_uint32* time_rec) override;
157 OM_uint32 wrap_size_limit(OM_uint32* minor_status,
158 const gss_ctx_id_t context_handle,
159 int conf_req_flag,
160 gss_qop_t qop_req,
161 OM_uint32 req_output_size,
162 OM_uint32* max_input_size) override;
163 OM_uint32 delete_sec_context(OM_uint32* minor_status,
164 gss_ctx_id_t* context_handle,
165 gss_buffer_t output_token) override;
166 OM_uint32 inquire_context(OM_uint32* minor_status,
167 const gss_ctx_id_t context_handle,
168 gss_name_t* src_name,
169 gss_name_t* targ_name,
170 OM_uint32* lifetime_rec,
171 gss_OID* mech_type,
172 OM_uint32* ctx_flags,
173 int* locally_initiated,
174 int* open) override;
176 private:
177 typedef decltype(&gss_import_name) gss_import_name_type;
178 typedef decltype(&gss_release_name) gss_release_name_type;
179 typedef decltype(&gss_release_buffer) gss_release_buffer_type;
180 typedef decltype(&gss_display_name) gss_display_name_type;
181 typedef decltype(&gss_display_status) gss_display_status_type;
182 typedef decltype(&gss_init_sec_context) gss_init_sec_context_type;
183 typedef decltype(&gss_wrap_size_limit) gss_wrap_size_limit_type;
184 typedef decltype(&gss_delete_sec_context) gss_delete_sec_context_type;
185 typedef decltype(&gss_inquire_context) gss_inquire_context_type;
187 FRIEND_TEST_ALL_PREFIXES(HttpAuthGSSAPIPOSIXTest, GSSAPIStartup);
189 bool InitImpl();
190 // Finds a usable dynamic library for GSSAPI and loads it. The criteria are:
191 // 1. The library must exist.
192 // 2. The library must export the functions we need.
193 base::NativeLibrary LoadSharedLibrary();
194 bool BindMethods(base::NativeLibrary lib);
196 bool initialized_;
198 std::string gssapi_library_name_;
199 // Need some way to invalidate the library.
200 base::NativeLibrary gssapi_library_;
202 // Function pointers
203 gss_import_name_type import_name_;
204 gss_release_name_type release_name_;
205 gss_release_buffer_type release_buffer_;
206 gss_display_name_type display_name_;
207 gss_display_status_type display_status_;
208 gss_init_sec_context_type init_sec_context_;
209 gss_wrap_size_limit_type wrap_size_limit_;
210 gss_delete_sec_context_type delete_sec_context_;
211 gss_inquire_context_type inquire_context_;
214 // ScopedSecurityContext releases a gss_ctx_id_t when it goes out of
215 // scope.
216 class ScopedSecurityContext {
217 public:
218 explicit ScopedSecurityContext(GSSAPILibrary* gssapi_lib);
219 ~ScopedSecurityContext();
221 gss_ctx_id_t get() const { return security_context_; }
222 gss_ctx_id_t* receive() { return &security_context_; }
224 private:
225 gss_ctx_id_t security_context_;
226 GSSAPILibrary* gssapi_lib_;
228 DISALLOW_COPY_AND_ASSIGN(ScopedSecurityContext);
232 // TODO(ahendrickson): Share code with HttpAuthSSPI.
233 class NET_EXPORT_PRIVATE HttpAuthGSSAPI {
234 public:
235 HttpAuthGSSAPI(GSSAPILibrary* library,
236 const std::string& scheme,
237 const gss_OID gss_oid);
238 ~HttpAuthGSSAPI();
240 bool Init();
242 bool NeedsIdentity() const;
244 bool AllowsExplicitCredentials() const;
246 HttpAuth::AuthorizationResult ParseChallenge(
247 HttpAuthChallengeTokenizer* tok);
249 // Generates an authentication token.
251 // The return value is an error code. The authentication token will be
252 // returned in |*auth_token|. If the result code is not |OK|, the value of
253 // |*auth_token| is unspecified.
255 // If the operation cannot be completed synchronously, |ERR_IO_PENDING| will
256 // be returned and the real result code will be passed to the completion
257 // callback. Otherwise the result code is returned immediately from this
258 // call.
260 // If the HttpAuthGSSAPI object is deleted before completion then the callback
261 // will not be called.
263 // If no immediate result is returned then |auth_token| must remain valid
264 // until the callback has been called.
266 // |spn| is the Service Principal Name of the server that the token is
267 // being generated for.
269 // If this is the first round of a multiple round scheme, credentials are
270 // obtained using |*credentials|. If |credentials| is NULL, the default
271 // credentials are used instead.
272 int GenerateAuthToken(const AuthCredentials* credentials,
273 const std::string& spn,
274 std::string* auth_token,
275 const CompletionCallback& callback);
277 // Delegation is allowed on the Kerberos ticket. This allows certain servers
278 // to act as the user, such as an IIS server retrieving data from a
279 // Kerberized MSSQL server.
280 void Delegate();
282 private:
283 int GetNextSecurityToken(const std::string& spn,
284 gss_buffer_t in_token,
285 gss_buffer_t out_token);
287 std::string scheme_;
288 gss_OID gss_oid_;
289 GSSAPILibrary* library_;
290 std::string decoded_server_auth_token_;
291 ScopedSecurityContext scoped_sec_context_;
292 bool can_delegate_;
295 } // namespace net
297 #endif // NET_HTTP_HTTP_AUTH_GSSAPI_POSIX_H_