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