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