gssapi 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ h1. Ruby GSSAPI Library
2
+
3
+ p. This is a wrapper around the system GSSAPI library. It exposes the low-level GSSAPI methods like gss_init_sec_context and gss_wrap and also provides an easier to use wrapper on top of this for common usage scenarios.
4
+
5
+
6
+ p. I'm going to try and maintain most of the docs in the Github WIKI for this project so please check there for documentation and examples.
7
+
8
+ https://github.com/zenchild/gssapi/wiki
9
+
10
+ p. Also check out the examples directory for some stubbed out client/server examples.
@@ -0,0 +1,29 @@
1
+ desc "Build the gem"
2
+ task :gem do
3
+ system "gem build gssapi.gemspec"
4
+ end
5
+
6
+ desc "Clean the build environment"
7
+ task :clean do
8
+ system "rm gssapi*.gem"
9
+ end
10
+
11
+ desc "Increment the version by 1 minor release"
12
+ task :versionup do
13
+ ver = up_min_version
14
+ puts "New version: #{ver}"
15
+ end
16
+
17
+
18
+ def up_min_version
19
+ f = File.open('VERSION', 'r+')
20
+ ver = f.readline.chomp
21
+ v_arr = ver.split(/\./).map do |v|
22
+ v.to_i
23
+ end
24
+ v_arr[2] += 1
25
+ ver = v_arr.join('.')
26
+ f.rewind
27
+ f.write(ver)
28
+ ver
29
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
@@ -0,0 +1,26 @@
1
+ require 'gssapi'
2
+ require 'base64'
3
+ require 'socket'
4
+
5
+ host = 'example.org'
6
+ service = 'host'
7
+
8
+ sock = TCPSocket.new(host, 8082)
9
+
10
+ cli = GSSAPI::Simple.new(host, service)
11
+ tok = cli.init_context
12
+ stok = Base64.strict_encode64(tok)
13
+
14
+ sock.write("#{stok}\n") # send initial token
15
+ stok = sock.gets.chomp # get back continuation token
16
+ ctx = cli.init_context(Base64.strict_decode64(stok.chomp)) # complete security context
17
+ puts "Connection #{(ctx ? 'succeeded' : 'failed')}"
18
+
19
+ begin
20
+ print "> "
21
+ msg = STDIN.gets.chomp
22
+ emsg = cli.wrap_message(msg)
23
+ sock.write("#{Base64.strict_encode64(emsg)}\n")
24
+ end while msg != 'exit'
25
+
26
+ sock.close
@@ -0,0 +1,32 @@
1
+ require 'gssapi'
2
+ require 'base64'
3
+ require 'socket'
4
+
5
+
6
+ host = 'example.org'
7
+ service = 'host'
8
+ keytab = "#{ENV['HOME']}/.gssapi/krb5.keytab" # this is optional, but probably required if not running as root
9
+
10
+ tcpsrv = TCPServer.new(host, 8082)
11
+
12
+ srv = GSSAPI::Simple.new(host, service, keytab)
13
+ srv.acquire_credentials
14
+
15
+ loop do
16
+ Thread.start(tcpsrv.accept) do |s|
17
+ print(s, "Accepted Connection\n")
18
+ stok = s.gets.chomp
19
+ print(s, "Received string#{stok}\n")
20
+ otok = srv.accept_context(Base64.strict_decode64(stok.chomp))
21
+ s.write("#{Base64.strict_encode64(otok)}\n")
22
+
23
+ begin
24
+ emsg = s.gets.chomp
25
+ msg = srv.unwrap_message(Base64.strict_decode64(emsg.chomp))
26
+ puts "Received: #{msg}"
27
+ end while msg != 'exit'
28
+
29
+ print(s, "Closing Socket\n")
30
+ s.close
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+ require 'date'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "gssapi"
8
+ gem.version = File.open('VERSION').readline.chomp
9
+ gem.date = Date.today.to_s
10
+ gem.platform = Gem::Platform::RUBY
11
+ gem.rubyforge_project = nil
12
+
13
+ gem.author = "Dan Wanek"
14
+ gem.email = "dan.wanek@gmail.com"
15
+ gem.homepage = "http://github.com/zenchild/gssapi"
16
+
17
+ gem.summary = "A FFI wrapper around the system GSSAPI library."
18
+ gem.description = <<-EOF
19
+ A FFI wrapper around the system GSSAPI library. Please make sure and read the
20
+ Yard docs or standard GSSAPI documentation if you have any questions.
21
+
22
+ There is also a class called GSSAPI::Simple that wraps many of the common features
23
+ used for GSSAPI.
24
+ EOF
25
+
26
+ gem.files = `git ls-files`.split(/\n/)
27
+ gem.require_path = "lib"
28
+ gem.rdoc_options = %w(-x test/ -x examples/)
29
+ gem.extra_rdoc_files = %w(README.textile COPYING.txt)
30
+
31
+ gem.required_ruby_version = '>= 1.9.1'
32
+ gem.add_runtime_dependency 'ffi', '>= 1.0.1'
33
+ end
@@ -0,0 +1,22 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of the Ruby GSSAPI library.
6
+ #
7
+ # GSSAPI is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # GSSAPI is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with GSSAPI. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+ require 'gssapi/exceptions'
21
+ require 'gssapi/lib_gssapi'
22
+ require 'gssapi/simple'
@@ -0,0 +1,22 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of the Ruby GSSAPI library.
6
+ #
7
+ # GSSAPI is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # GSSAPI is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with GSSAPI. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+ module GSSAPI
21
+ class GssApiError < StandardError; end
22
+ end
@@ -0,0 +1,409 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of the Ruby GSSAPI library.
6
+ #
7
+ # GSSAPI is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # GSSAPI is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with GSSAPI. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+ require 'ffi'
21
+
22
+ module GSSAPI
23
+ module LibGSSAPI
24
+ extend FFI::Library
25
+
26
+ ffi_lib File.basename Dir.glob("/usr/lib/libgssapi*").first, FFI::Library::LIBC
27
+
28
+ # Libc functions
29
+
30
+ # void *malloc(size_t size);
31
+ attach_function :malloc, [:size_t], :pointer
32
+
33
+ # void *memcpy(void *dest, const void *src, size_t n);
34
+ attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
35
+
36
+
37
+ typedef :uint32, :OM_uint32
38
+
39
+ class GssOID < FFI::Struct
40
+ layout :length => :OM_uint32,
41
+ :elements => :pointer # pointer of :void
42
+
43
+ def self.gss_c_no_oid
44
+ self.new(GSSAPI::LibGSSAPI::GSS_C_NO_OID)
45
+ end
46
+ end
47
+
48
+
49
+ # This is a generic Managed Struct subclass that hides the [] methods.
50
+ # Classes that implement this class should provide accessor methods to get to the attributes.
51
+ class GssMStruct < FFI::ManagedStruct
52
+ private
53
+
54
+ def [](key)
55
+ super(key)
56
+ end
57
+
58
+ def []=(key,val)
59
+ super(key,val)
60
+ end
61
+ end
62
+
63
+ # This class implements the gss_buffer_desc type. Use #pointer to emulate gss_buffer_t
64
+ # @example
65
+ # buff = GssBufferDesc.new
66
+ # buff.value = "This is a test"
67
+ class GssBufferDesc < GssMStruct
68
+ layout :length => :size_t,
69
+ :value => :pointer # pointer of :void
70
+
71
+ def initialize(ptr = nil)
72
+ if(ptr.nil?)
73
+ super(FFI::Pointer.new(FFI::MemoryPointer.new(self.size)))
74
+ else
75
+ super(ptr)
76
+ end
77
+ end
78
+
79
+ # Set the value of the string for the "value" parameter. This method also
80
+ # appropriately sets the length parameter.
81
+ def value=(val)
82
+ if(val.nil?)
83
+ self[:length] = 0
84
+ self[:value] = val
85
+ elsif(val.is_a?(String))
86
+ rbuff = FFI::MemoryPointer.from_string(val)
87
+ buff = LibGSSAPI.malloc(rbuff.size)
88
+ LibGSSAPI.memcpy(buff,rbuff,rbuff.size)
89
+ self[:length] = val.length
90
+ self[:value] = buff
91
+ elsif(val.is_a?(Fixnum))
92
+ rbuff = FFI::MemoryPointer.new :uint32
93
+ buff = LibGSSAPI.malloc(rbuff.size)
94
+ LibGSSAPI.memcpy(buff,rbuff,rbuff.size)
95
+ self[:length] = val.to_s.length
96
+ self[:value] = val
97
+ else
98
+ raise StandardError, "Can't handle type #{val.class.name}"
99
+ end
100
+ end
101
+
102
+ def length
103
+ self[:length]
104
+ end
105
+
106
+ def value
107
+ if(self[:length] == 0)
108
+ nil
109
+ else
110
+ self[:value].read_string(self[:length])
111
+ end
112
+ end
113
+
114
+ def self.release(ptr)
115
+ puts "Releasing MGssBufferDesc at #{ptr.address}" if $DEBUG
116
+ min_stat = FFI::MemoryPointer.new :uint32
117
+ maj_stat = LibGSSAPI.gss_release_buffer(min_stat, ptr)
118
+ end
119
+ end
120
+
121
+ # @example
122
+ # iov_buff = GssIOVBufferDesc.new
123
+ # str = FFI::MemoryPointer.from_string("This is the string")
124
+ # iov_buff[:type] = 1
125
+ # iov_buff[:buffer][:length] = str.size
126
+ # iov_buff[:buffer][:value] = str
127
+ class GssIOVBufferDesc < FFI::Struct
128
+ layout :type => :OM_uint32,
129
+ :buffer => GssBufferDesc
130
+ end
131
+
132
+ class GssChannelBindingsStruct < FFI::Struct
133
+ layout :initiator_addrtype => :OM_uint32,
134
+ :initiator_address => GssBufferDesc,
135
+ :acceptor_addrtype => :OM_uint32,
136
+ :acceptor_address => GssBufferDesc,
137
+ :application_data => GssBufferDesc
138
+
139
+ no_chn_bind = FFI::MemoryPointer.new :pointer #
140
+ no_chn_bind.write_int 0
141
+
142
+
143
+ end
144
+
145
+ # This s a generic AutoPointer. Gss pointers that implement this class should also implement a
146
+ # class method called release_ptr that releases the structure pointed to by this pointer.
147
+ class GssPointer < FFI::AutoPointer
148
+ def address_of
149
+ ptr_p = FFI::MemoryPointer.new :pointer
150
+ ptr_p.write_pointer(self)
151
+ end
152
+
153
+ def self.release(ptr)
154
+ if( ptr.address == 0 )
155
+ puts "NULL POINTER: Not freeing" if $DEBUG
156
+ return
157
+ else
158
+ puts "Releasing #{self.name}" if $DEBUG
159
+ self.release_ptr(ptr)
160
+ end
161
+ end
162
+ end
163
+
164
+ # A wrapper around gss_name_t so that it garbage collects
165
+ class GssNameT < GssPointer
166
+ def self.release_ptr(name_ptr)
167
+ puts "Releasing gss_name_t at #{name_ptr.address}" if $DEBUG
168
+ min_stat = FFI::MemoryPointer.new :uint32
169
+ maj_stat = LibGSSAPI.gss_release_name(min_stat, name_ptr)
170
+ end
171
+ end
172
+
173
+ class GssCtxIdT < GssPointer
174
+ def self.release_ptr(context_ptr)
175
+ min_stat = FFI::MemoryPointer.new :uint32
176
+ empty_buff = LibGSSAPI::GssBufferDesc.new
177
+ empty_buff[:length] = 0
178
+ empty_buff[:value] = nil
179
+ maj_stat = LibGSSAPI.gss_delete_sec_context(min_stat, context_ptr, empty_buff.pointer)
180
+ end
181
+
182
+ def self.gss_c_no_context
183
+ self.new(GSSAPI::LibGSSAPI::GSS_C_NO_CONTEXT)
184
+ end
185
+ end
186
+
187
+ # gss_cred_id_t
188
+ class GssCredIdT < GssPointer
189
+ def self.release_ptr(cred_ptr)
190
+ min_stat = FFI::MemoryPointer.new :uint32
191
+ maj_stat = LibGSSAPI.gss_release_cred(min_stat, cred_ptr)
192
+ end
193
+ end
194
+
195
+
196
+ # OM_uint32 gss_release_buffer(OM_uint32 * minor_status, gss_buffer_t buffer);
197
+
198
+ # Function definitions
199
+ # --------------------
200
+
201
+ # OM_uint32 gss_import_name(OM_uint32 * minor_status, const gss_buffer_t input_name_buffer, const gss_OID input_name_type, gss_name_t * output_name);
202
+ # @example:
203
+ # host_str = 'host@example.com'
204
+ # buff_str = GSSAPI::LibGSSAPI::GssBufferDesc.new
205
+ # buff_str[:length] = host_str.length
206
+ # buff_str[:value] = FFI::MemoryPointer.from_string(host_str)
207
+ # name = FFI::MemoryPointer.new :pointer # gss_name_t
208
+ # min_stat = FFI::MemoryPointer.new :uint32
209
+ # maj_stat = GSSAPI::LibGSSAPI.gss_import_name(min_stat, buff_str.pointer, GSSAPI::LibGSSAPI.GSS_C_NT_HOSTBASED_SERVICE, name)
210
+ # name = name.get_pointer(0)
211
+ # Remember to free the allocated name (gss_name_t) space with gss_release_name
212
+ attach_function :gss_import_name, [:pointer, :pointer, :pointer, :pointer], :OM_uint32
213
+
214
+ # OM_uint32 gss_export_name(OM_uint32 * minor_status, const gss_name_t input_name, gss_buffer_t exported_name);
215
+ attach_function :gss_export_name, [:pointer, :pointer, :pointer], :OM_uint32
216
+
217
+ # OM_uint32 gss_canonicalize_name(OM_uint32 * minor_status, const gss_name_t input_name, const gss_OID mech_type, gss_name_t * output_name)
218
+ attach_function :gss_canonicalize_name, [:pointer, :pointer, :pointer, :pointer], :OM_uint32
219
+
220
+ # OM_uint32 gss_oid_to_str(OM_uint32 *minor_status, const gss_OID oid, gss_buffer_t oid_str);
221
+ # @example:
222
+ # min_stat = FFI::MemoryPointer.new :uint32
223
+ # oidstr = GSSAPI::LibGSSAPI::GssBufferDesc.new
224
+ # maj_stat = GSSAPI::LibGSSAPI.gss_oid_to_str(min_stat, GSSAPI::LibGSSAPI.GSS_C_NT_HOSTBASED_SERVICE, oidstr.pointer)
225
+ # oidstr[:value].read_string
226
+ attach_function :gss_oid_to_str, [:pointer, :pointer, :pointer], :OM_uint32
227
+
228
+ # OM_uint32 gss_str_to_oid(OM_uint32 *minor_status, const gss_buffer_t oid_str, gss_OID *oid);
229
+ # @example: Simulate GSS_C_NT_HOSTBASED_SERVICE
230
+ # min_stat = FFI::MemoryPointer.new :uint32
231
+ # str = "{ 1 2 840 113554 1 2 1 4 }"
232
+ # oidstr = GSSAPI::LibGSSAPI::GssBufferDesc.new
233
+ # oidstr[:length] = str.length
234
+ # oidstr[:value] = FFI::MemoryPointer.from_string str
235
+ # oid = FFI::MemoryPointer.new :pointer
236
+ # min_stat = FFI::MemoryPointer.new :uint32
237
+ # maj_stat = GSSAPI::LibGSSAPI.gss_str_to_oid(min_stat, oidstr.pointer, oid)
238
+ # oid = GSSAPI::LibGSSAPI::GssOID.new(oid.get_pointer(0))
239
+ attach_function :gss_str_to_oid, [:pointer, :pointer, :pointer], :OM_uint32
240
+
241
+ # OM_uint32 gss_init_sec_context(OM_uint32 * minor_status, const gss_cred_id_t initiator_cred_handle,
242
+ # gss_ctx_id_t * context_handle, const gss_name_t target_name, const gss_OID mech_type, OM_uint32 req_flags,
243
+ # OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token,
244
+ # gss_OID * actual_mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec);
245
+ attach_function :gss_init_sec_context, [:pointer, :pointer, :pointer, :pointer, :pointer, :OM_uint32, :OM_uint32, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :OM_uint32
246
+
247
+ # OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, const gss_cred_id_t acceptor_cred_handle,
248
+ # const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, gss_name_t *src_name, gss_OID *mech_type,
249
+ # gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec, gss_cred_id_t *delegated_cred_handle);
250
+ attach_function :gss_accept_sec_context, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :OM_uint32
251
+
252
+ # OM_uint32 gss_acquire_cred(OM_uint32 *minor_status, const gss_name_t desired_name, OM_uint32 time_req, const gss_OID_set desired_mechs,
253
+ # gss_cred_usage_t cred_usage, gss_cred_id_t *output_cred_handle, gss_OID_set *actual_mechs, OM_uint32 *time_rec);
254
+ attach_function :gss_acquire_cred, [:pointer, :pointer, :OM_uint32, :pointer, :OM_uint32, :pointer, :pointer, :pointer], :OM_uint32
255
+
256
+ # OM_uint32 gss_wrap(OM_uint32 * minor_status, const gss_ctx_id_t context_handle, int conf_req_flag,
257
+ # gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int * conf_state, gss_buffer_t output_message_buffer);
258
+ # @example:
259
+ # min_stat = FFI::MemoryPointer.new :uint32
260
+ # Remember to free the allocated output_message_buffer with gss_release_buffer
261
+ attach_function :gss_wrap, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :pointer], :OM_uint32
262
+
263
+ # OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_iov( OM_uint32 * minor_status, gss_ctx_id_t context_handle,
264
+ # int conf_req_flag, gss_qop_t qop_req, int * conf_state, gss_iov_buffer_desc * iov, int iov_count );
265
+ attach_function :gss_wrap_iov, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :int], :OM_uint32
266
+
267
+ # OM_uint32 gss_wrap_aead(OM_uint32 * minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, gss_buffer_t input_assoc_buffer,
268
+ # gss_buffer_t input_payload_buffer, int * conf_state, gss_buffer_t output_message_buffer);
269
+ attach_function :gss_wrap_aead, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :pointer, :pointer], :OM_uint32
270
+
271
+ # OM_uint32 gss_unwrap(OM_uint32 * minor_status, const gss_ctx_id_t context_handle,
272
+ # const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int * conf_state, gss_qop_t * qop_state);
273
+ # @example:
274
+ # min_stat = FFI::MemoryPointer.new :uint32
275
+ # Remember to free the allocated output_message_buffer with gss_release_buffer
276
+ attach_function :gss_unwrap, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :OM_uint32
277
+
278
+ # OM_uint32 gss_delete_sec_context(OM_uint32 * minor_status, gss_ctx_id_t * context_handle, gss_buffer_t output_token);
279
+ attach_function :gss_delete_sec_context, [:pointer, :pointer, :pointer], :OM_uint32
280
+
281
+ # OM_uint32 gss_release_name(OM_uint32 * minor_status, gss_name_t * name);
282
+ attach_function :gss_release_name, [:pointer, :pointer], :OM_uint32
283
+
284
+ # OM_uint32 gss_release_buffer(OM_uint32 * minor_status, gss_buffer_t buffer);
285
+ attach_function :gss_release_buffer, [:pointer, :pointer], :OM_uint32
286
+
287
+ # OM_uint32 gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle);
288
+ attach_function :gss_release_cred, [:pointer, :pointer], :OM_uint32
289
+
290
+ # Used to register alternate keytabs
291
+ # OM_uint32 krb5_gss_register_acceptor_identity(const char *);
292
+ attach_function :krb5_gss_register_acceptor_identity, [:string], :OM_uint32
293
+
294
+
295
+ # Variable definitions
296
+ # --------------------
297
+
298
+ attach_variable :GSS_C_NT_HOSTBASED_SERVICE, :pointer # type gss_OID
299
+ attach_variable :GSS_C_NT_EXPORT_NAME, :pointer # type gss_OID
300
+ attach_variable :gss_mech_krb5, :pointer # type gss_OID
301
+ attach_variable :gss_mech_set_krb5, :pointer # type gss_OID_set
302
+ attach_variable :gss_nt_krb5_name, :pointer # type gss_OID
303
+ attach_variable :gss_nt_krb5_principal, :pointer # type gss_OID
304
+ attach_variable :gss_nt_krb5_principal, :pointer # type gss_OID_set
305
+
306
+
307
+
308
+ # Flag bits for context-level services.
309
+ GSS_C_DELEG_FLAG = 1
310
+ GSS_C_MUTUAL_FLAG = 2
311
+ GSS_C_REPLAY_FLAG = 4
312
+ GSS_C_SEQUENCE_FLAG = 8
313
+ GSS_C_CONF_FLAG = 16
314
+ GSS_C_INTEG_FLAG = 32
315
+ GSS_C_ANON_FLAG = 64
316
+ GSS_C_PROT_READY_FLAG = 128
317
+ GSS_C_TRANS_FLAG = 256
318
+ GSS_C_DELEG_POLICY_FLAG = 32768
319
+
320
+
321
+ # Credential usage options
322
+ GSS_C_BOTH = 0
323
+ GSS_C_INITIATE = 1
324
+ GSS_C_ACCEPT = 2
325
+
326
+ # Misc Constants
327
+ GSS_C_INDEFINITE = 0xffffffff # Expiration time of 2^32-1 seconds means infinite lifetime for sec or cred context
328
+
329
+ # Message Offsets
330
+ GSS_C_CALLING_ERROR_OFFSET = 24
331
+ GSS_C_ROUTINE_ERROR_OFFSET = 16
332
+ GSS_C_SUPPLEMENTARY_OFFSET = 0
333
+ # GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
334
+ # GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
335
+ # GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
336
+
337
+
338
+ # QOP (Quality of Protection)
339
+ GSS_C_QOP_DEFAULT = 0
340
+
341
+
342
+ # GSSAPI Status & Error Codes
343
+ GSS_S_COMPLETE = 0
344
+
345
+ GSS_C_CALLING_ERRORS = {
346
+ (1 << GSS_C_CALLING_ERROR_OFFSET) => "GSS_S_CALL_INACCESSIBLE_READ",
347
+ (2 << GSS_C_CALLING_ERROR_OFFSET) => "GSS_S_CALL_INACCESSIBLE_WRITE",
348
+ (3 << GSS_C_CALLING_ERROR_OFFSET) => "GSS_S_CALL_BAD_STRUCTURE"
349
+ }
350
+
351
+ GSS_C_SUPPLEMENTARY_CODES = {
352
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) => "GSS_S_CONTINUE_NEEDED",
353
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) => "GSS_S_DUPLICATE_TOKEN",
354
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) => "GSS_S_OLD_TOKEN",
355
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) => "GSS_S_UNSEQ_TOKEN",
356
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) => "GSS_S_GAP_TOKEN"
357
+ }
358
+
359
+ GSS_C_ROUTINE_ERRORS = {
360
+ (1 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_BAD_MECH",
361
+ (2 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_BAD_NAME",
362
+ (3 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_BAD_NAMETYPE",
363
+ (4 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_BAD_BINDINGS",
364
+ (5 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_BAD_STATUS",
365
+ (6 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_BAD_SIG",
366
+ (7 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_NO_CRED",
367
+ (8 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_NO_CONTEXT",
368
+ (9 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_DEFECTIVE_TOKEN",
369
+ (10 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_DEFECTIVE_CREDENTIAL",
370
+ (11 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_CREDENTIALS_EXPIRED",
371
+ (12 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_CONTEXT_EXPIRED",
372
+ (13 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_FAILURE",
373
+ (14 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_BAD_QOP",
374
+ (15 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_UNAUTHORIZED",
375
+ (16 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_UNAVAILABLE",
376
+ (17 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_DUPLICATE_ELEMENT",
377
+ (18 << GSS_C_ROUTINE_ERROR_OFFSET) => "GSS_S_NAME_NOT_MN"
378
+ }
379
+
380
+
381
+ # IOV Buffer Types (gssapi_ext.h)
382
+ GSS_IOV_BUFFER_TYPE_EMPTY = 0
383
+ GSS_IOV_BUFFER_TYPE_DATA = 1 # Packet data
384
+ GSS_IOV_BUFFER_TYPE_HEADER = 2 # Mechanism header
385
+ GSS_IOV_BUFFER_TYPE_MECH_PARAMS = 3 # Mechanism specific parameters
386
+ GSS_IOV_BUFFER_TYPE_TRAILER = 7 # Mechanism trailer
387
+ GSS_IOV_BUFFER_TYPE_PADDING = 9 # Padding
388
+ GSS_IOV_BUFFER_TYPE_STREAM = 10 # Complete wrap token
389
+ GSS_IOV_BUFFER_TYPE_SIGN_ONLY = 11 # Sign only packet data
390
+ # Flags
391
+ GSS_IOV_BUFFER_FLAG_MASK = 0xFFFF0000
392
+ GSS_IOV_BUFFER_FLAG_ALLOCATE = 0x00010000 # indicates GSS should allocate
393
+ GSS_IOV_BUFFER_FLAG_ALLOCATED = 0x00020000 # indicates caller should free
394
+
395
+
396
+
397
+ # Various Null values. (gssapi.h)
398
+ GSS_C_NO_NAME = FFI::Pointer.new(:pointer, 0) # ((gss_name_t) 0)
399
+ GSS_C_NO_BUFFER = FFI::Pointer.new(:pointer, 0) # ((gss_buffer_t) 0)
400
+ GSS_C_NO_OID = FFI::Pointer.new(:pointer, 0) # ((gss_OID) 0)
401
+ GSS_C_NO_OID_SET = FFI::Pointer.new(:pointer, 0) # ((gss_OID_set) 0)
402
+ GSS_C_NO_CONTEXT = FFI::Pointer.new(:pointer, 0) # ((gss_ctx_id_t) 0)
403
+ GSS_C_NO_CREDENTIAL = FFI::Pointer.new(:pointer, 0) # ((gss_cred_id_t) 0)
404
+ GSS_C_NO_CHANNEL_BINDINGS = FFI::Pointer.new(:pointer, 0) # ((gss_channel_bindings_t) 0)
405
+ GSS_C_EMPTY_BUFFER = GssBufferDesc.new
406
+
407
+
408
+ end #end LibGSSAPI
409
+ end #end GSSAPI