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