gssapi 1.1.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3783cdc3cf7cac849ba482b3b03e5f73593f91beab95e31b8dfdd296a8cd0e4a
4
+ data.tar.gz: 11d7a7b367ad6f7e8f3420c094976dceee1bdedb7907bef5614e6a5846164cb4
5
+ SHA512:
6
+ metadata.gz: 462afcc325ae6e9c0c3b63ba711569bda177c6443792031a857a01808ba63e9e5a90c0cc455518c431e39275dc68421b6b426a89bd6cb5bd61a5aebd53a04a3b
7
+ data.tar.gz: d76e23ca9d859dc7a11589c8490d92c455e6874336efc00a070442f695713aa5adcc008767fc3943176aaec8a4dfe0f86b5f70cfc003650ab33f0d4bfea9d916
@@ -0,0 +1,11 @@
1
+ Gemfile.lock
2
+
3
+ # RVM setup
4
+ /.ruby-version
5
+ /.ruby-gemset
6
+
7
+ # Vim swap files
8
+ *.sw[op]
9
+
10
+ # VS Code Dir
11
+ /.vscode
@@ -0,0 +1,23 @@
1
+ ## Version 1.1.1
2
+ * Allow GssApiError to be initialized with string.
3
+ * Add display_name wrapper for gss_display_name to GSSAPI::Simple
4
+ * gss_iov examples
5
+ * Ruby 1.8.x support
6
+ * Change loader for MIT and Heimdal to be a bit cleaner. Fix syntax in simple.rb
7
+ * Do a gss_acquire_cred for every connection to the server.
8
+ * updating path to gssapi32.dll
9
+
10
+ ## Version 1.1.2
11
+ * add gss_get_mic
12
+
13
+ ## Version 1.2.0
14
+ * Move IOV and AEAD to gssapi/extensions.rb so it can be loaded separately when needed
15
+
16
+ ## Version 1.3.0
17
+
18
+ Sorry everyone that this has taken so long to go out. I don't really work much
19
+ with GSSAPI so it hasn't been a priority for me.
20
+
21
+ * Implemented delegation and added verify_mic. Thanks @mfazekas
22
+ * Add loading of MIT GSS libs for solaris/smartos. Thanks @fac
23
+ * Fix corruption in iov_decrypt example. Thanks @Iristyle
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -0,0 +1,22 @@
1
+ # Ruby GSSAPI Library
2
+
3
+ This is a wrapper around the system GSSAPI library (MIT only at this time). 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
+ 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
+
11
+ Also check out the examples directory for some stubbed out client/server examples.
12
+
13
+
14
+ ## Note on IOV and AEAD functions
15
+
16
+ If you require the IOV and AEAD functions you will have to `require "gssapi/extensions"` to gain access to them.
17
+
18
+
19
+ #### License
20
+
21
+ Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
22
+ Ruby gssapi is licensed under the MIT license (see COPYING)
data/Rakefile CHANGED
@@ -1,29 +1,11 @@
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
1
+ require "bundler/gem_tasks"
2
+
3
+ desc "Open a Pry Console"
4
+ task :console do
5
+ require "pry"
6
+ require "pathname"
7
+ $: << (Pathname(__FILE__).dirname + "lib").to_s
8
+ require "gssapi"
9
+ ARGV.clear
10
+ Pry.start
29
11
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.3.1
@@ -47,7 +47,7 @@ module GssIOVHelpers
47
47
 
48
48
  len = str.unpack("L").first
49
49
  puts "LEN: #{len}"
50
- iov_data = str.unpack("LA#{len}A*")
50
+ iov_data = str.unpack("La#{len}a*")
51
51
  iov0[:buffer].value = iov_data[1]
52
52
  iov1[:buffer].value = iov_data[2]
53
53
 
@@ -4,21 +4,22 @@ $:.unshift lib unless $:.include?(lib)
4
4
  require 'date'
5
5
 
6
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
7
+ gem.name = "gssapi"
8
+ gem.version = File.open('VERSION').readline.chomp
9
+ gem.date = Date.today.to_s
10
10
  gem.platform = Gem::Platform::RUBY
11
11
  gem.rubyforge_project = nil
12
12
 
13
13
  gem.author = "Dan Wanek"
14
14
  gem.email = "dan.wanek@gmail.com"
15
15
  gem.homepage = "http://github.com/zenchild/gssapi"
16
+ gem.license = "MIT"
16
17
 
17
18
  gem.summary = "A FFI wrapper around the system GSSAPI library."
18
19
  gem.description = <<-EOF
19
20
  A FFI wrapper around the system GSSAPI library. Please make sure and read the
20
21
  Yard docs or standard GSSAPI documentation if you have any questions.
21
-
22
+
22
23
  There is also a class called GSSAPI::Simple that wraps many of the common features
23
24
  used for GSSAPI.
24
25
  EOF
@@ -26,8 +27,10 @@ Gem::Specification.new do |gem|
26
27
  gem.files = `git ls-files`.split(/\n/)
27
28
  gem.require_path = "lib"
28
29
  gem.rdoc_options = %w(-x test/ -x examples/)
29
- gem.extra_rdoc_files = %w(README.textile COPYING)
30
+ gem.extra_rdoc_files = %w(README.md COPYING Changelog.md)
30
31
 
31
32
  gem.required_ruby_version = '>= 1.8.7'
32
33
  gem.add_runtime_dependency 'ffi', '>= 1.0.1'
34
+
35
+ gem.add_development_dependency "pry-byebug"
33
36
  end
@@ -11,6 +11,14 @@ module GSSAPI
11
11
  def message; to_s + ": " + @s; end
12
12
 
13
13
  def initialize(maj_stat = nil, min_stat = nil)
14
+
15
+ # If raised as class (raise GssApiError, "msg) the error message is given
16
+ # as the first parameter.
17
+ if maj_stat.class == String
18
+ @s = maj_stat
19
+ return super maj_stat
20
+ end
21
+
14
22
  if(maj_stat.nil? && min_stat.nil?)
15
23
  @s = '(no error info)'
16
24
  else
@@ -0,0 +1,40 @@
1
+ =begin
2
+ Copyright © 2014 Dan Wanek <dan.wanek@gmail.com>
3
+
4
+ Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
5
+ =end
6
+ module GSSAPI
7
+ module LibGSSAPI
8
+
9
+ # Some versions of GSSAPI might not have support for IOV yet.
10
+ begin
11
+ # OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_iov( OM_uint32 * minor_status, gss_ctx_id_t context_handle,
12
+ # int conf_req_flag, gss_qop_t qop_req, int * conf_state, gss_iov_buffer_desc * iov, int iov_count );
13
+ attach_function :gss_wrap_iov, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :int], :OM_uint32
14
+
15
+ # OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap_iov ( OM_uint32 * minor_status, gss_ctx_id_t context_handle,
16
+ # int * conf_state, gss_qop_t * qop_state, gss_iov_buffer_desc * iov, int iov_count )
17
+ attach_function :gss_unwrap_iov, [:pointer, :pointer, :pointer, :pointer, :pointer, :int], :OM_uint32
18
+
19
+ # OM_uint32 GSSAPI_LIB_CALL gss_wrap_iov_length ( OM_uint32 * minor_status, gss_ctx_id_t context_handle,
20
+ # int conf_req_flag, gss_qop_t qop_req, int * conf_state, gss_iov_buffer_desc * iov, int iov_count)
21
+ attach_function :gss_wrap_iov_length, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :int], :OM_uint32
22
+ rescue FFI::NotFoundError => ex
23
+ warn "WARNING: Could not load IOV methods. Check your GSSAPI C library for an update"
24
+ end
25
+
26
+ begin
27
+ # OM_uint32 gss_wrap_aead(OM_uint32 * minor_status, gss_ctx_id_t context_handle, int conf_req_flag,
28
+ # gss_qop_t qop_req, gss_buffer_t input_assoc_buffer,
29
+ # gss_buffer_t input_payload_buffer, int * conf_state, gss_buffer_t output_message_buffer);
30
+ attach_function :gss_wrap_aead, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :pointer, :pointer], :OM_uint32
31
+
32
+ # OM_uint32 gss_unwrap_aead(OM_uint32 * minor_status, gss_ctx_id_t context_handle, gss_buffer_t input_message_buffer,
33
+ # gss_buffer_t input_assoc_buffer, gss_buffer_t output_payload_buffer, int * conf_state, gss_qop_t * qop_state);
34
+ attach_function :gss_unwrap_aead, [:pointer,:pointer,:pointer,:pointer,:pointer,:pointer,:pointer], :OM_uint32
35
+ rescue FFI::NotFoundError => ex
36
+ warn "WARNING: Could not load AEAD methods. Check your GSSAPI C library for an update"
37
+ end
38
+
39
+ end
40
+ end
@@ -158,7 +158,7 @@ module GSSAPI
158
158
 
159
159
  def self.release(ptr)
160
160
  if( ptr.address == 0 )
161
- puts "NULL POINTER: Not freeing" if $DEBUG
161
+ puts "Releasing #{self.name} NULL POINTER: Not freeing" if $DEBUG
162
162
  return
163
163
  else
164
164
  puts "Releasing #{self.name} at #{ptr.address.to_s(16)}" if $DEBUG
@@ -179,11 +179,13 @@ module GSSAPI
179
179
  class GssCtxIdT < GssPointer
180
180
  def self.release_ptr(context_ptr)
181
181
  min_stat = FFI::MemoryPointer.new :OM_uint32
182
- maj_stat = LibGSSAPI.gss_delete_sec_context(min_stat, context_ptr, LibGSSAPI::GSS_C_NO_BUFFER)
182
+ ptr_p = FFI::MemoryPointer.new :pointer
183
+ ctx_ptr = ptr_p.write_pointer(context_ptr)
184
+ maj_stat = LibGSSAPI.gss_delete_sec_context(min_stat, ctx_ptr, LibGSSAPI::GSS_C_NO_BUFFER)
183
185
  end
184
186
 
185
187
  def self.gss_c_no_context
186
- self.new(GSSAPI::LibGSSAPI::GSS_C_NO_CONTEXT)
188
+ GssPointer.new(GSSAPI::LibGSSAPI::GSS_C_NO_CONTEXT)
187
189
  end
188
190
  end
189
191
 
@@ -257,6 +259,9 @@ module GSSAPI
257
259
  # gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec, gss_cred_id_t *delegated_cred_handle);
258
260
  attach_function :gss_accept_sec_context, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :OM_uint32
259
261
 
262
+ # OM_uint32 gss_display_name(OM_uint32 * minor_status, gss_name_t input_name, gss_buffer_t output_name_buffer, gss_OID * output_name_type);
263
+ attach_function :gss_display_name, [:pointer, :pointer, :pointer, :pointer], :OM_uint32
264
+
260
265
  # 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,
261
266
  # gss_cred_usage_t cred_usage, gss_cred_id_t *output_cred_handle, gss_OID_set *actual_mechs, OM_uint32 *time_rec);
262
267
  attach_function :gss_acquire_cred, [:pointer, :pointer, :OM_uint32, :pointer, :OM_uint32, :pointer, :pointer, :pointer], :OM_uint32
@@ -267,36 +272,6 @@ module GSSAPI
267
272
  # min_stat = FFI::MemoryPointer.new :OM_uint32
268
273
  # Remember to free the allocated output_message_buffer with gss_release_buffer
269
274
  attach_function :gss_wrap, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :pointer], :OM_uint32
270
-
271
- # Some versions of GSSAPI might not have support for IOV yet.
272
- begin
273
- # OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_iov( OM_uint32 * minor_status, gss_ctx_id_t context_handle,
274
- # int conf_req_flag, gss_qop_t qop_req, int * conf_state, gss_iov_buffer_desc * iov, int iov_count );
275
- attach_function :gss_wrap_iov, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :int], :OM_uint32
276
-
277
- # OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap_iov ( OM_uint32 * minor_status, gss_ctx_id_t context_handle,
278
- # int * conf_state, gss_qop_t * qop_state, gss_iov_buffer_desc * iov, int iov_count )
279
- attach_function :gss_unwrap_iov, [:pointer, :pointer, :pointer, :pointer, :pointer, :int], :OM_uint32
280
-
281
- # OM_uint32 GSSAPI_LIB_CALL gss_wrap_iov_length ( OM_uint32 * minor_status, gss_ctx_id_t context_handle,
282
- # int conf_req_flag, gss_qop_t qop_req, int * conf_state, gss_iov_buffer_desc * iov, int iov_count)
283
- attach_function :gss_wrap_iov_length, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :int], :OM_uint32
284
- rescue FFI::NotFoundError => ex
285
- warn "WARNING: Could not load IOV methods. Check your GSSAPI C library for an update"
286
- end
287
-
288
- begin
289
- # OM_uint32 gss_wrap_aead(OM_uint32 * minor_status, gss_ctx_id_t context_handle, int conf_req_flag,
290
- # gss_qop_t qop_req, gss_buffer_t input_assoc_buffer,
291
- # gss_buffer_t input_payload_buffer, int * conf_state, gss_buffer_t output_message_buffer);
292
- attach_function :gss_wrap_aead, [:pointer, :pointer, :int, :OM_uint32, :pointer, :pointer, :pointer, :pointer], :OM_uint32
293
-
294
- # OM_uint32 gss_unwrap_aead(OM_uint32 * minor_status, gss_ctx_id_t context_handle, gss_buffer_t input_message_buffer,
295
- # gss_buffer_t input_assoc_buffer, gss_buffer_t output_payload_buffer, int * conf_state, gss_qop_t * qop_state);
296
- attach_function :gss_unwrap_aead, [:pointer,:pointer,:pointer,:pointer,:pointer,:pointer,:pointer], :OM_uint32
297
- rescue FFI::NotFoundError => ex
298
- warn "WARNING: Could not load AEAD methods. Check your GSSAPI C library for an update"
299
- end
300
275
 
301
276
  # OM_uint32 gss_unwrap(OM_uint32 * minor_status, const gss_ctx_id_t context_handle,
302
277
  # const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int * conf_state, gss_qop_t * qop_state);
@@ -305,6 +280,12 @@ module GSSAPI
305
280
  # Remember to free the allocated output_message_buffer with gss_release_buffer
306
281
  attach_function :gss_unwrap, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :OM_uint32
307
282
 
283
+ # OM_uint32 gss_get_mic(OM_uint32 * minor_status, const gss_ctx_id_t context_handle, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer)
284
+ attach_function :gss_get_mic, [:pointer, :pointer, :OM_uint32, :pointer, :pointer], :OM_uint32
285
+
286
+ # OM_uint32 gss_verify_mic (OM_uint32 *minor_status,const gss_ctx_id_t context_handle, const gss_buffer_t message_buffer,const gss_buffer_t token_buffer, gss_qop_t qop_state)
287
+ attach_function :gss_verify_mic, [:pointer, :pointer, :pointer, :pointer, :OM_uint32], :OM_uint32
288
+
308
289
  # OM_uint32 gss_delete_sec_context(OM_uint32 * minor_status, gss_ctx_id_t * context_handle, gss_buffer_t output_token);
309
290
  attach_function :gss_delete_sec_context, [:pointer, :pointer, :pointer], :OM_uint32
310
291
 
@@ -324,6 +305,9 @@ module GSSAPI
324
305
  # OM_uint32 gss_display_status(OM_uint32 *minor_status, OM_uint32 status_value, int status_type, gss_OID mech_type, OM_uint32 *message_context, gss_buffer_t status_string)
325
306
  attach_function :gss_display_status, [:pointer, :OM_uint32, :int, :pointer, :pointer, :pointer], :OM_uint32
326
307
 
308
+ # OM_uint32 gss_krb5_copy_ccache(OM_uint32 *minor_status, gss_cred_id_t cred_handle, krb5_ccache out_ccache)
309
+ attach_function :gss_krb5_copy_ccache, [:pointer, :pointer, :pointer], :OM_uint32
310
+
327
311
  # Variable definitions
328
312
  # --------------------
329
313
 
@@ -17,22 +17,26 @@ module GSSAPI
17
17
 
18
18
 
19
19
  def self.load_mit
20
- case RUBY_PLATFORM
20
+ host_os = RbConfig::CONFIG['host_os']
21
+ case host_os
21
22
  when /linux/
22
23
  gssapi_lib = 'libgssapi_krb5.so.2'
24
+ ffi_lib gssapi_lib, FFI::Library::LIBC
23
25
  when /darwin/
24
26
  gssapi_lib = '/usr/lib/libgssapi_krb5.dylib'
27
+ ffi_lib gssapi_lib, FFI::Library::LIBC
25
28
  when /mswin|mingw32|windows/
26
29
  # Pull the gssapi32 path from the environment if it exist, otherwise use the default in Program Files
27
30
  gssapi32_path = ENV['gssapi32'] ? ENV['gssapi32'] : 'C:\Program Files (x86)\MIT\Kerberos\bin\gssapi32.dll'
28
31
  ffi_lib gssapi32_path, FFI::Library::LIBC # Required the MIT Kerberos libraries to be installed
29
32
  ffi_convention :stdcall
33
+ when /solaris/
34
+ ffi_lib 'libgss.so', 'mech_krb5.so', FFI::Library::LIBC
30
35
  else
31
- raise LoadError, "This platform (#{RUBY_PLATFORM}) is not supported by ruby gssapi and the MIT libraries."
36
+ raise LoadError, "This host OS (#{host_os}) is not supported by ruby gssapi and the MIT libraries."
32
37
  end
33
- ffi_lib gssapi_lib, FFI::Library::LIBC
34
38
 
35
- # -------------------- MIT Specifics --------------------
39
+ # -------------------- MIT Specifics --------------------
36
40
  attach_variable :__GSS_C_NT_HOSTBASED_SERVICE, :GSS_C_NT_HOSTBASED_SERVICE, :pointer # type gss_OID
37
41
  attach_variable :__GSS_C_NT_EXPORT_NAME, :GSS_C_NT_EXPORT_NAME, :pointer # type gss_OID
38
42
  LibGSSAPI.const_set("GSS_C_NT_HOSTBASED_SERVICE", __GSS_C_NT_HOSTBASED_SERVICE)
@@ -40,25 +44,26 @@ module GSSAPI
40
44
  end
41
45
 
42
46
  def self.load_heimdal
43
- case RUBY_PLATFORM
47
+ host_os = RbConfig::CONFIG['host_os']
48
+ case host_os
44
49
  when /linux/
45
50
  gssapi_lib = 'libgssapi.so.3'
46
51
  when /darwin/
47
52
  # use Heimdal Kerberos since Mac MIT Kerberos is OLD. Do a "require 'gssapi/heimdal'" first
48
53
  gssapi_lib = '/usr/heimdal/lib/libgssapi.dylib'
49
54
  else
50
- raise LoadError, "This platform (#{RUBY_PLATFORM}) is not supported by ruby gssapi and the Heimdal libraries."
55
+ raise LoadError, "This host OS (#{host_os}) is not supported by ruby gssapi and the Heimdal libraries."
51
56
  end
52
57
  ffi_lib gssapi_lib, FFI::Library::LIBC
53
58
 
54
- # ------------------ Heimdal Specifics ------------------
59
+ # ------------------ Heimdal Specifics ------------------
55
60
  attach_variable :__gss_c_nt_hostbased_service_oid_desc, GssOID
56
61
  attach_variable :__gss_c_nt_export_name_oid_desc, GssOID
57
62
  LibGSSAPI.const_set("GSS_C_NT_HOSTBASED_SERVICE", FFI::Pointer.new(__gss_c_nt_hostbased_service_oid_desc.to_ptr))
58
63
  LibGSSAPI.const_set("GSS_C_NT_EXPORT_NAME", FFI::Pointer.new(__gss_c_nt_export_name_oid_desc.to_ptr))
59
64
  end
60
65
 
61
- # Heimdal supported the *_iov functions befor MIT did so in some OS distributions if
66
+ # Heimdal supported the *_iov functions before MIT did so in some OS distributions if
62
67
  # you need IOV support and MIT does not provide it try the Heimdal libs and then
63
68
  # before doing a "require 'gssapi'" do a "require 'gssapi/heimdal'" and that will attempt
64
69
  # to load the Heimdal libs
@@ -10,6 +10,7 @@ module GSSAPI
10
10
  class Simple
11
11
 
12
12
  attr_reader :context
13
+ attr_reader :delegated_credentials
13
14
 
14
15
  # Initialize a new GSSAPI::Simple object
15
16
  # @param [String] host_name the fully qualified host name
@@ -26,6 +27,7 @@ module GSSAPI
26
27
  @context = nil # the security context
27
28
  @scred = nil # the service credentials. really only used for the server-side via acquire_credentials
28
29
  set_keytab(keytab) unless keytab.nil?
30
+ @delegated_credentials = nil
29
31
  end
30
32
 
31
33
 
@@ -57,11 +59,12 @@ module GSSAPI
57
59
  # @option opts [Fixnum] :flags override all other flags. If you set the :delegate option this option will override it.
58
60
  # @see http://tools.ietf.org/html/rfc4121#section-4.1.1.1
59
61
  # @option opts [Boolean] :delegate if true set the credential delegate flag
62
+ # [Credentials] :credentials set to open the context in behalf of someone (delegated_credentials)
60
63
  # @return [String, true] if a continuation flag is set it will return the output token that is needed to send
61
64
  # to the remote host. Otherwise it returns true and the GSS security context has been established.
62
65
  def init_context(in_token = nil, opts = {})
63
66
  min_stat = FFI::MemoryPointer.new :OM_uint32
64
- ctx = (@context.nil? ? LibGSSAPI::GssCtxIdT.gss_c_no_context.address_of : @context.address_of)
67
+ pctx = (@context.nil? ? LibGSSAPI::GssCtxIdT.gss_c_no_context.address_of : @context.address_of)
65
68
  mech = LibGSSAPI::GssOID.gss_c_no_oid
66
69
  if(opts[:flags])
67
70
  flags = opts[:flags]
@@ -77,8 +80,8 @@ module GSSAPI
77
80
 
78
81
 
79
82
  maj_stat = LibGSSAPI.gss_init_sec_context(min_stat,
80
- nil,
81
- ctx,
83
+ opts[:credentials],
84
+ pctx,
82
85
  @int_svc_name,
83
86
  mech,
84
87
  flags,
@@ -91,8 +94,13 @@ module GSSAPI
91
94
  nil)
92
95
 
93
96
  raise GssApiError.new(maj_stat, min_stat), "gss_init_sec_context did not return GSS_S_COMPLETE" if maj_stat > 1
94
-
95
- @context = LibGSSAPI::GssCtxIdT.new(ctx.get_pointer(0))
97
+
98
+ # The returned context may be equal to the passed in @context. If so, we
99
+ # must not create another AutoPointer to the same gss_buffer_t. If we do
100
+ # we will double delete it.
101
+ ctx = pctx.get_pointer(0)
102
+ @context = LibGSSAPI::GssCtxIdT.new(ctx) if ctx != @context
103
+
96
104
  maj_stat == 1 ? out_tok.value : true
97
105
  end
98
106
 
@@ -105,33 +113,88 @@ module GSSAPI
105
113
  raise GssApiError, "No credentials yet acquired. Call #{self.class.name}#acquire_credentials first" if @scred.nil?
106
114
 
107
115
  min_stat = FFI::MemoryPointer.new :OM_uint32
108
- ctx = (@context.nil? ? LibGSSAPI::GssCtxIdT.gss_c_no_context.address_of : @context.address_of)
116
+ pctx = (@context.nil? ? LibGSSAPI::GssCtxIdT.gss_c_no_context.address_of : @context.address_of)
109
117
  no_chn_bind = LibGSSAPI::GSS_C_NO_CHANNEL_BINDINGS
110
- client = FFI::MemoryPointer.new :pointer # Will hold the initiating client name after the call
118
+ @client = FFI::MemoryPointer.new :pointer # Will hold the initiating client name after the call
111
119
  mech = FFI::MemoryPointer.new :pointer # Will hold the mech being used after the call
112
120
  in_tok = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
113
121
  in_tok.value = in_token
114
122
  out_tok = GSSAPI::LibGSSAPI::ManagedGssBufferDesc.new
115
123
  ret_flags = FFI::MemoryPointer.new :OM_uint32
124
+ delegated_cred_handle = FFI::MemoryPointer.new :pointer
116
125
 
117
126
  maj_stat = LibGSSAPI.gss_accept_sec_context(min_stat,
118
- ctx,
127
+ pctx,
119
128
  @scred,
120
129
  in_tok.pointer,
121
130
  no_chn_bind,
122
- client,
131
+ @client,
123
132
  mech,
124
133
  out_tok.pointer,
125
134
  ret_flags,
126
- nil, nil)
135
+ nil,
136
+ delegated_cred_handle)
127
137
 
128
138
  raise GssApiError.new(maj_stat, min_stat), "gss_accept_sec_context did not return GSS_S_COMPLETE" if maj_stat > 1
129
139
 
130
- @context = LibGSSAPI::GssCtxIdT.new(ctx.get_pointer(0))
140
+ if (ret_flags.read_uint32 & LibGSSAPI::GSS_C_DELEG_FLAG) != 0
141
+ @delegated_credentials = LibGSSAPI::GssCredIdT.new(delegated_cred_handle.get_pointer(0))
142
+ end
143
+
144
+ # The returned context may be equal to the passed in @context. If so, we
145
+ # must not create another AutoPointer to the same gss_buffer_t. If we do
146
+ # we will double delete it.
147
+ ctx = pctx.get_pointer(0)
148
+ @context = LibGSSAPI::GssCtxIdT.new(ctx) if ctx != @context
149
+
131
150
  out_tok.length > 0 ? out_tok.value : true
132
151
  end
133
152
 
134
153
 
154
+ def get_mic(token)
155
+
156
+ min_stat = FFI::MemoryPointer.new :OM_uint32
157
+ qop_req = GSSAPI::LibGSSAPI::GSS_C_QOP_DEFAULT
158
+ in_buff = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
159
+ in_buff.value = token
160
+ out_buff = GSSAPI::LibGSSAPI::ManagedGssBufferDesc.new
161
+ maj_stat = GSSAPI::LibGSSAPI.gss_get_mic(min_stat, @context, qop_req, in_buff.pointer, out_buff.pointer)
162
+ raise GssApiError.new(maj_stat, min_stat), "Failed to gss_get_mic" if maj_stat != 0
163
+ out_buff.value
164
+ end
165
+
166
+ def verify_mic(token,mic)
167
+ min_stat = FFI::MemoryPointer.new :OM_uint32
168
+ in_buff = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
169
+ in_buff.value = token
170
+ mic_buff = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
171
+ mic_buff.value = mic
172
+ maj_stat = GSSAPI::LibGSSAPI.gss_verify_mic(min_stat, @context, in_buff.pointer, mic_buff.pointer, 0)
173
+ raise GssApiError.new(maj_stat, min_stat), "Failed to gss_verify_mic" if maj_stat != 0
174
+ return (maj_stat == 0)
175
+ end
176
+
177
+ # Get textual representation of internal GSS name
178
+ # @return [String] textual representation of internal GSS name
179
+ def display_name
180
+ raise GssApiError.new(), "No context accepted yet. Call #{self.class.name}#accept_context(in_token) first" if @client.nil?
181
+
182
+ output_name = GSSAPI::LibGSSAPI::ManagedGssBufferDesc.new
183
+
184
+ min_stat = FFI::MemoryPointer.new :OM_uint32
185
+ maj_stat = LibGSSAPI.gss_display_name(min_stat,
186
+ @client.get_pointer(0),
187
+ output_name.pointer,
188
+ nil)
189
+
190
+ if maj_stat != GSSAPI::LibGSSAPI::GSS_S_COMPLETE
191
+ raise GssApiError.new(maj_stat, min_stat),
192
+ "gss_display_name did not return GSS_S_COMPLETE but #{ maj_stat }"
193
+ end
194
+
195
+ output_name.value
196
+ end
197
+
135
198
  # Acquire security credentials. This does not log you in. It grabs the credentials from a cred cache or keytab.
136
199
  # @param [Hash] opts options to pass to the gss_acquire_cred function.
137
200
  # @option opts [String] :usage The credential usage type (:accept, :initiate, :both). It defaults to 'accept' since
@@ -6,19 +6,65 @@ require 'yaml'
6
6
 
7
7
  describe GSSAPI::Simple, 'Test the Simple GSSAPI interface' do
8
8
 
9
- before :all do
10
- @conf = YAML.load_file "#{File.dirname(__FILE__)}/conf_file.yaml"
11
- end
9
+ let(:conf) { YAML.load_file "#{File.dirname(__FILE__)}/conf_file.yaml" }
10
+ let(:cli) { GSSAPI::Simple.new(conf['s_host'], conf['s_service']) }
11
+ let(:srv ) { GSSAPI::Simple.new(conf['s_host'], conf['s_service'], conf['keytab']) }
12
12
 
13
13
  it 'should get the initial context for a client' do
14
- gsscli = GSSAPI::Simple.new(@conf[:c_host], @conf[:c_service])
15
- token = gsscli.init_context
16
- token.should_not be_empty
14
+ token = cli.init_context
15
+ expect(token).not_to be_empty
17
16
  end
18
17
 
19
18
  it 'should acquire credentials for a server service' do
20
- gsscli = GSSAPI::Simple.new(@conf[:s_host], @conf[:s_service], @conf[:keytab])
21
- gsscli.acquire_credentials.should be_true
19
+ expect(srv.acquire_credentials).to eq(true)
22
20
  end
23
21
 
22
+ def play_handshake(cli,srv,clioptions={})
23
+ clitoken = cli.init_context(nil, clioptions)
24
+ expect(clitoken).not_to be_empty
25
+
26
+ expect(srv.acquire_credentials).to eq(true)
27
+
28
+ srvoktok = srv.accept_context(clitoken)
29
+ expect(srvoktok).not_to be_empty
30
+
31
+ ret = cli.init_context(srvoktok)
32
+ expect(ret).to eq(true)
33
+ end
34
+
35
+ it 'client server should handshake' do
36
+ play_handshake(cli,srv)
37
+ end
38
+
39
+ it 'mic' do
40
+ play_handshake(cli,srv)
41
+
42
+ secret = "this is secreta"
43
+
44
+ mic = cli.get_mic(secret)
45
+
46
+ expect(srv.verify_mic(secret,mic)).to eq(true)
47
+ end
48
+
49
+ context "no delegation" do
50
+ it "sets delegated_credentials to nil" do
51
+ play_handshake(cli,srv,:delegate => false)
52
+ expect(srv.delegated_credentials).to be_nil
53
+ end
54
+ end
55
+
56
+ describe "delegation" do
57
+ it "sets delegated_credentials to valid" do
58
+ play_handshake(cli,srv,:delegate => true)
59
+ expect(srv.delegated_credentials).not_to be_nil
60
+ delegated_display_name = srv.display_name
61
+
62
+ host2 = conf['s_host2'] || conf['s_host']
63
+ service2 = conf['s_service2'] || conf['s_service']
64
+ cli_del = GSSAPI::Simple.new(host2, service2)
65
+ srv_del = GSSAPI::Simple.new(host2, service2, conf['keytab2'])
66
+ play_handshake(cli_del,srv_del,:credentials => srv.delegated_credentials)
67
+ expect(srv_del.display_name).to eq(delegated_display_name)
68
+ end
69
+ end
24
70
  end
@@ -10,6 +10,6 @@ describe GSSAPI::LibGSSAPI::UnManagedGssBufferDesc, 'Unmanaged Buffer Test' do
10
10
  end
11
11
 
12
12
  # If we get here without any errors we should be golden
13
- true.should be_true
13
+ expect(true).to eq(true)
14
14
  end
15
15
  end
metadata CHANGED
@@ -1,40 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gssapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ version: 1.3.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Dan Wanek
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-02-10 00:00:00.000000000 Z
11
+ date: 2020-11-24 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: ffi
16
- requirement: &17171140 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 1.0.1
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *17171140
25
- description: ! " A FFI wrapper around the system GSSAPI library. Please make sure
26
- and read the\n Yard docs or standard GSSAPI documentation if you have any questions.\n
27
- \ \n There is also a class called GSSAPI::Simple that wraps many of the common
28
- features\n used for GSSAPI.\n"
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry-byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |2
42
+ A FFI wrapper around the system GSSAPI library. Please make sure and read the
43
+ Yard docs or standard GSSAPI documentation if you have any questions.
44
+
45
+ There is also a class called GSSAPI::Simple that wraps many of the common features
46
+ used for GSSAPI.
29
47
  email: dan.wanek@gmail.com
30
48
  executables: []
31
49
  extensions: []
32
50
  extra_rdoc_files:
33
- - README.textile
51
+ - README.md
34
52
  - COPYING
53
+ - Changelog.md
35
54
  files:
55
+ - ".gitignore"
36
56
  - COPYING
37
- - README.textile
57
+ - Changelog.md
58
+ - Gemfile
59
+ - README.md
38
60
  - Rakefile
39
61
  - VERSION
40
62
  - examples/gss_client.rb
@@ -45,6 +67,7 @@ files:
45
67
  - gssapi.gemspec
46
68
  - lib/gssapi.rb
47
69
  - lib/gssapi/exceptions.rb
70
+ - lib/gssapi/extensions.rb
48
71
  - lib/gssapi/heimdal.rb
49
72
  - lib/gssapi/lib_gssapi.rb
50
73
  - lib/gssapi/lib_gssapi_loader.rb
@@ -53,31 +76,30 @@ files:
53
76
  - test/spec/gssapi_simple_spec.rb
54
77
  - test/spec/test_buffer_spec.rb
55
78
  homepage: http://github.com/zenchild/gssapi
56
- licenses: []
57
- post_install_message:
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
58
83
  rdoc_options:
59
- - -x
84
+ - "-x"
60
85
  - test/
61
- - -x
86
+ - "-x"
62
87
  - examples/
63
88
  require_paths:
64
89
  - lib
65
90
  required_ruby_version: !ruby/object:Gem::Requirement
66
- none: false
67
91
  requirements:
68
- - - ! '>='
92
+ - - ">="
69
93
  - !ruby/object:Gem::Version
70
94
  version: 1.8.7
71
95
  required_rubygems_version: !ruby/object:Gem::Requirement
72
- none: false
73
96
  requirements:
74
- - - ! '>='
97
+ - - ">="
75
98
  - !ruby/object:Gem::Version
76
99
  version: '0'
77
100
  requirements: []
78
- rubyforge_project:
79
- rubygems_version: 1.8.10
80
- signing_key:
81
- specification_version: 3
101
+ rubygems_version: 3.0.8
102
+ signing_key:
103
+ specification_version: 4
82
104
  summary: A FFI wrapper around the system GSSAPI library.
83
105
  test_files: []
@@ -1,16 +0,0 @@
1
- h1. Ruby GSSAPI Library
2
-
3
- p. This is a wrapper around the system GSSAPI library (MIT only at this time). 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.
11
-
12
-
13
- h4. License
14
-
15
- Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
16
- Ruby gssapi is licensed under the MIT license (see COPYING)