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