gssapi 1.0.3 → 1.1.0

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.3
1
+ 1.1.0
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+ $: << '../lib'
3
+ $: << '.'
4
+ #require 'gssapi/heimdal'
5
+ require 'gssapi'
6
+ require 'gss_iov_helpers'
7
+ require 'base64'
8
+ require 'socket'
9
+
10
+ class GssIovClient
11
+ include GssIOVHelpers
12
+
13
+ def initialize
14
+ @host = 'example.org'
15
+ @service = 'host'
16
+ @sock = TCPSocket.new(@host, 8082)
17
+ @gss = GSSAPI::Simple.new(@host, @service)
18
+ end
19
+
20
+ def run
21
+ handshake
22
+ begin
23
+ print "> "
24
+ msg = STDIN.gets.chomp
25
+ emsg = iov_encrypt(msg)
26
+ @sock.write("#{emsg.last}\n")
27
+ end while msg != 'exit'
28
+
29
+ @sock.close
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def handshake
36
+ tok = @gss.init_context
37
+ stok = Base64.strict_encode64(tok)
38
+
39
+ @sock.write("#{stok}\n") # send initial token
40
+ stok = @sock.gets.chomp # get back continuation token
41
+ ctx = @gss.init_context(Base64.strict_decode64(stok.chomp)) # complete security context
42
+ puts "Connection #{(ctx ? 'succeeded' : 'failed')}"
43
+ end
44
+
45
+ # Encrypt message
46
+ def msg_enc(msg)
47
+ emsg = @gss.wrap_message(msg)
48
+ Base64.strict_encode64(emsg)
49
+ end
50
+
51
+ end
52
+
53
+
54
+ cli = GssIovClient.new
55
+ cli.run
@@ -0,0 +1,74 @@
1
+ module GssIOVHelpers
2
+
3
+ def iov_encrypt(str)
4
+ iov_cnt = 3
5
+ iov = FFI::MemoryPointer.new(GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * iov_cnt)
6
+
7
+ iov0 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address))
8
+ iov0[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_HEADER | GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
9
+
10
+ iov1 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 1)))
11
+ iov1[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_DATA)
12
+ iov1[:buffer].value = str
13
+
14
+ iov2 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 2)))
15
+ iov2[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_PADDING | GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
16
+
17
+ conf_state = FFI::MemoryPointer.new :uint32
18
+ min_stat = FFI::MemoryPointer.new :uint32
19
+
20
+ maj_stat = GSSAPI::LibGSSAPI.gss_wrap_iov(min_stat, @gss.context, 1, GSSAPI::LibGSSAPI::GSS_C_QOP_DEFAULT, conf_state, iov, iov_cnt)
21
+
22
+ token = [iov0[:buffer].length].pack('L')
23
+ token += iov0[:buffer].value
24
+ token += iov1[:buffer].value
25
+ pad_len = iov2[:buffer].length
26
+ token += iov2[:buffer].value if pad_len > 0
27
+ [pad_len, token]
28
+ end
29
+
30
+ # @return [String] the unencrypted response string
31
+ def iov_decrypt(str)
32
+ puts "Decrypting message:\n#{str}"
33
+ iov_cnt = 3
34
+ iov = FFI::MemoryPointer.new(GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * iov_cnt)
35
+
36
+ iov0 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address))
37
+ iov0[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_HEADER | GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
38
+
39
+ iov1 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 1)))
40
+ iov1[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_DATA)
41
+
42
+ iov2 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 2)))
43
+ iov2[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_DATA)
44
+
45
+ str.force_encoding('BINARY')
46
+ #str.sub!(/^.*Content-Type: application\/octet-stream\r\n(.*)--Encrypted.*$/m, '\1')
47
+
48
+ len = str.unpack("L").first
49
+ puts "LEN: #{len}"
50
+ iov_data = str.unpack("LA#{len}A*")
51
+ iov0[:buffer].value = iov_data[1]
52
+ iov1[:buffer].value = iov_data[2]
53
+
54
+ min_stat = FFI::MemoryPointer.new :uint32
55
+ conf_state = FFI::MemoryPointer.new :uint32
56
+ conf_state.write_int(1)
57
+ qop_state = FFI::MemoryPointer.new :uint32
58
+ qop_state.write_int(0)
59
+
60
+ puts "Unwrapping IOV...."
61
+ maj_stat = GSSAPI::LibGSSAPI.gss_unwrap_iov(min_stat, @gss.context, conf_state, qop_state, iov, iov_cnt)
62
+ puts "Done Unwrapping IOV...."
63
+ if(maj_stat == 0)
64
+ puts "Success!!!"
65
+ else
66
+ puts "GSSAPI Failure. Status Codes(major: #{maj_stat}, minor: #{min_stat.read_int})"
67
+ end
68
+
69
+ puts "???HELLO???"
70
+
71
+ iov1[:buffer].value
72
+ end
73
+
74
+ end
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ $: << '../lib'
3
+ $: << '.'
4
+ #require 'gssapi/heimdal'
5
+ require 'gssapi'
6
+ require 'gss_iov_helpers'
7
+ require 'base64'
8
+ require 'socket'
9
+
10
+ class GssIovServer
11
+ include GssIOVHelpers
12
+
13
+ def initialize
14
+ @host = 'example.org'
15
+ @service = "host"
16
+ @keytab = "#{ENV['HOME']}/.gssapi/krb5.keytab" # this is optional, but probably required if not running as root
17
+ @port = 8082
18
+ @tcpsrv = TCPServer.new(@host, @port)
19
+ end
20
+
21
+ def runner
22
+ loop do
23
+ puts "Listening on port #{@port}"
24
+ Thread.start(@tcpsrv.accept) do |s|
25
+ init_krb
26
+ handshake(s)
27
+
28
+ begin
29
+ emsg = (s.gets.chomp)
30
+ puts "---> Received: #{emsg}"
31
+ msg = iov_decrypt(emsg)
32
+ puts "===> Received: #{msg}"
33
+ end while msg != 'exit'
34
+
35
+ print(s, "Closing Socket\n")
36
+ s.close
37
+ puts "Closed...."
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ private
44
+
45
+ def init_krb
46
+ @gss = GSSAPI::Simple.new(@host, @service, @keytab)
47
+ @gss.acquire_credentials
48
+ puts "HELLO"
49
+ end
50
+
51
+ def handshake(sock)
52
+ print(sock, "Accepted Connection\n")
53
+ stok = sock.gets.chomp
54
+ print(sock, "Received string#{stok}\n")
55
+ otok = @gss.accept_context(Base64.strict_decode64(stok.chomp))
56
+ sock.write("#{Base64.strict_encode64(otok)}\n")
57
+ end
58
+
59
+ # Decrypt message
60
+ def msg_dec(msg)
61
+ @gss.unwrap_message(Base64.strict_decode64(msg.chomp))
62
+ end
63
+
64
+ end
65
+
66
+ gserv = GssIovServer.new
67
+ gserv.runner
@@ -9,14 +9,13 @@ keytab = "#{ENV['HOME']}/.gssapi/krb5.keytab" # this is optional, but probably
9
9
 
10
10
  tcpsrv = TCPServer.new(host, 8082)
11
11
 
12
- srv = GSSAPI::Simple.new(host, service, keytab)
13
- srv.acquire_credentials
14
-
15
12
  loop do
16
13
  Thread.start(tcpsrv.accept) do |s|
17
14
  print(s, "Accepted Connection\n")
18
15
  stok = s.gets.chomp
19
16
  print(s, "Received string#{stok}\n")
17
+ srv = GSSAPI::Simple.new(host, service, keytab)
18
+ srv.acquire_credentials
20
19
  otok = srv.accept_context(Base64.strict_decode64(stok.chomp))
21
20
  s.write("#{Base64.strict_encode64(otok)}\n")
22
21
 
@@ -28,6 +28,6 @@ Gem::Specification.new do |gem|
28
28
  gem.rdoc_options = %w(-x test/ -x examples/)
29
29
  gem.extra_rdoc_files = %w(README.textile COPYING)
30
30
 
31
- gem.required_ruby_version = '>= 1.9.1'
31
+ gem.required_ruby_version = '>= 1.8.7'
32
32
  gem.add_runtime_dependency 'ffi', '>= 1.0.1'
33
33
  end
@@ -15,15 +15,6 @@ module GSSAPI
15
15
  # void *memcpy(void *dest, const void *src, size_t n);
16
16
  attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
17
17
 
18
- class GssOID < FFI::Struct
19
- layout :length => :OM_uint32,
20
- :elements => :pointer # pointer of :void
21
-
22
- def self.gss_c_no_oid
23
- self.new(GSSAPI::LibGSSAPI::GSS_C_NO_OID)
24
- end
25
- end
26
-
27
18
  # This is a generic Managed Struct subclass that hides the [] methods.
28
19
  # Classes that implement this class should provide accessor methods to get to the attributes.
29
20
  class GssMStruct < FFI::ManagedStruct
@@ -56,8 +47,8 @@ module GSSAPI
56
47
  module GssBufferDescLayout
57
48
  def self.included(base)
58
49
  base.class_eval do
59
- layout :length => :OM_uint32,
60
- :value => :pointer # pointer of :void
50
+ layout :length, :OM_uint32,
51
+ :value, :pointer # pointer of :void
61
52
 
62
53
  def length
63
54
  self[:length]
@@ -142,16 +133,16 @@ module GSSAPI
142
133
  # iov_buff[:buffer][:length] = str.size
143
134
  # iov_buff[:buffer][:value] = str
144
135
  class GssIOVBufferDesc < FFI::Struct
145
- layout :type => :OM_uint32,
146
- :buffer => UnManagedGssBufferDesc
136
+ layout :type, :OM_uint32,
137
+ :buffer, UnManagedGssBufferDesc
147
138
  end
148
139
 
149
140
  class GssChannelBindingsStruct < FFI::Struct
150
- layout :initiator_addrtype => :OM_uint32,
151
- :initiator_address => UnManagedGssBufferDesc,
152
- :acceptor_addrtype => :OM_uint32,
153
- :acceptor_address => UnManagedGssBufferDesc,
154
- :application_data => UnManagedGssBufferDesc
141
+ layout :initiator_addrtype, :OM_uint32,
142
+ :initiator_address, UnManagedGssBufferDesc,
143
+ :acceptor_addrtype, :OM_uint32,
144
+ :acceptor_address, UnManagedGssBufferDesc,
145
+ :application_data, UnManagedGssBufferDesc
155
146
 
156
147
  no_chn_bind = FFI::MemoryPointer.new :pointer #
157
148
  no_chn_bind.write_int 0
@@ -199,6 +190,7 @@ module GSSAPI
199
190
  # gss_cred_id_t
200
191
  class GssCredIdT < GssPointer
201
192
  def self.release_ptr(cred_ptr)
193
+ puts "Releasing gss_cred_id_t at #{cred_ptr.address.to_s(16)}" if $DEBUG
202
194
  min_stat = FFI::MemoryPointer.new :OM_uint32
203
195
  maj_stat = LibGSSAPI.gss_release_cred(min_stat, cred_ptr)
204
196
  end
@@ -335,9 +327,6 @@ module GSSAPI
335
327
  # Variable definitions
336
328
  # --------------------
337
329
 
338
- attach_variable :GSS_C_NT_HOSTBASED_SERVICE, :pointer # type gss_OID
339
- attach_variable :GSS_C_NT_EXPORT_NAME, :pointer # type gss_OID
340
-
341
330
  # Flag bits for context-level services.
342
331
  GSS_C_DELEG_FLAG = 1
343
332
  GSS_C_MUTUAL_FLAG = 2
@@ -6,35 +6,69 @@ Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.p
6
6
  module GSSAPI
7
7
  module LibGSSAPI
8
8
 
9
+ class GssOID < FFI::Struct
10
+ layout :length, :OM_uint32,
11
+ :elements, :pointer # pointer of :void
12
+
13
+ def self.gss_c_no_oid
14
+ self.new(GSSAPI::LibGSSAPI::GSS_C_NO_OID)
15
+ end
16
+ end
17
+
18
+
19
+ def self.load_mit
20
+ case RUBY_PLATFORM
21
+ when /linux/
22
+ gssapi_lib = 'libgssapi_krb5.so.2'
23
+ when /darwin/
24
+ gssapi_lib = '/usr/lib/libgssapi_krb5.dylib'
25
+ when /mswin|mingw32|windows/
26
+ # Pull the gssapi32 path from the environment if it exist, otherwise use the default in Program Files
27
+ gssapi32_path = ENV['gssapi32'] ? ENV['gssapi32'] : 'C:\Program Files (x86)\MIT\Kerberos\bin\gssapi32.dll'
28
+ ffi_lib gssapi32_path, FFI::Library::LIBC # Required the MIT Kerberos libraries to be installed
29
+ ffi_convention :stdcall
30
+ else
31
+ raise LoadError, "This platform (#{RUBY_PLATFORM}) is not supported by ruby gssapi and the MIT libraries."
32
+ end
33
+ ffi_lib gssapi_lib, FFI::Library::LIBC
34
+
35
+ # -------------------- MIT Specifics --------------------
36
+ attach_variable :__GSS_C_NT_HOSTBASED_SERVICE, :GSS_C_NT_HOSTBASED_SERVICE, :pointer # type gss_OID
37
+ attach_variable :__GSS_C_NT_EXPORT_NAME, :GSS_C_NT_EXPORT_NAME, :pointer # type gss_OID
38
+ LibGSSAPI.const_set("GSS_C_NT_HOSTBASED_SERVICE", __GSS_C_NT_HOSTBASED_SERVICE)
39
+ LibGSSAPI.const_set("GSS_C_NT_EXPORT_NAME", __GSS_C_NT_EXPORT_NAME)
40
+ end
41
+
42
+ def self.load_heimdal
43
+ case RUBY_PLATFORM
44
+ when /linux/
45
+ gssapi_lib = 'libgssapi.so.3'
46
+ when /darwin/
47
+ # use Heimdal Kerberos since Mac MIT Kerberos is OLD. Do a "require 'gssapi/heimdal'" first
48
+ gssapi_lib = '/usr/heimdal/lib/libgssapi.dylib'
49
+ else
50
+ raise LoadError, "This platform (#{RUBY_PLATFORM}) is not supported by ruby gssapi and the Heimdal libraries."
51
+ end
52
+ ffi_lib gssapi_lib, FFI::Library::LIBC
53
+
54
+ # ------------------ Heimdal Specifics ------------------
55
+ attach_variable :__gss_c_nt_hostbased_service_oid_desc, GssOID
56
+ attach_variable :__gss_c_nt_export_name_oid_desc, GssOID
57
+ LibGSSAPI.const_set("GSS_C_NT_HOSTBASED_SERVICE", FFI::Pointer.new(__gss_c_nt_hostbased_service_oid_desc.to_ptr))
58
+ LibGSSAPI.const_set("GSS_C_NT_EXPORT_NAME", FFI::Pointer.new(__gss_c_nt_export_name_oid_desc.to_ptr))
59
+ end
60
+
9
61
  # Heimdal supported the *_iov functions befor MIT did so in some OS distributions if
10
62
  # you need IOV support and MIT does not provide it try the Heimdal libs and then
11
63
  # before doing a "require 'gssapi'" do a "require 'gssapi/heimdal'" and that will attempt
12
64
  # to load the Heimdal libs
13
- case RUBY_PLATFORM
14
- when /linux/
15
- case GSSAPI_LIB_TYPE
16
- when :mit
17
- GSSAPI_LIB = 'libgssapi_krb5.so.2'
18
- when :heimdal
19
- GSSAPI_LIB = 'libgssapi.so.2'
20
- end
21
- ffi_lib GSSAPI_LIB, FFI::Library::LIBC
22
- when /darwin/
23
- case GSSAPI_LIB_TYPE
24
- when :mit
25
- GSSAPI_LIB = '/usr/lib/libgssapi_krb5.dylib'
26
- when :heimdal
27
- # use Heimdal Kerberos since Mac MIT Kerberos is OLD. Do a "require 'gssapi/heimdal'" first
28
- GSSAPI_LIB = '/usr/heimdal/lib/libgssapi.dylib'
29
- end
30
- ffi_lib GSSAPI_LIB, FFI::Library::LIBC
31
- when /mswin|mingw32|windows/
32
- # Pull the gssapi32 path from the environment if it exist, otherwise use the default in Program Files
33
- gssapi32_path = ENV['gssapi32'] ? ENV['gssapi32'] : 'C:\Program Files (x86)\MIT\Kerberos\bin\gssapi32.dll'
34
- ffi_lib gssapi32_path, FFI::Library::LIBC # Required the MIT Kerberos libraries to be installed
35
- ffi_convention :stdcall
65
+ case GSSAPI_LIB_TYPE
66
+ when :mit
67
+ load_mit
68
+ when :heimdal
69
+ load_heimdal
36
70
  else
37
- raise LoadError, "This platform (#{RUBY_PLATFORM}) is not supported by ruby gssapi."
71
+ raise LoadError, "Unexpected Lib type: #{GSSAPI_LIB_TYPE}"
38
72
  end
39
73
 
40
74
  end
@@ -38,7 +38,7 @@ module GSSAPI
38
38
  if (str =~ /[A-Za-z0-9]+\/[^@]+@.+$/)
39
39
  mech = LibGSSAPI::GssOID.gss_c_no_oid
40
40
  else
41
- mech = LibGSSAPI.GSS_C_NT_HOSTBASED_SERVICE
41
+ mech = LibGSSAPI::GSS_C_NT_HOSTBASED_SERVICE
42
42
  end
43
43
  name = FFI::MemoryPointer.new :pointer # gss_name_t
44
44
  min_stat = FFI::MemoryPointer.new :OM_uint32
metadata CHANGED
@@ -1,43 +1,46 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: gssapi
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
4
5
  prerelease:
5
- version: 1.0.3
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Dan Wanek
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-11-07 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2012-02-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: ffi
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &17171140 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
23
21
  version: 1.0.1
24
22
  type: :runtime
25
- version_requirements: *id001
26
- description: " A FFI wrapper around the system GSSAPI library. Please make sure and read the\n Yard docs or standard GSSAPI documentation if you have any questions.\n \n There is also a class called GSSAPI::Simple that wraps many of the common features\n used for GSSAPI.\n"
23
+ 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"
27
29
  email: dan.wanek@gmail.com
28
30
  executables: []
29
-
30
31
  extensions: []
31
-
32
- extra_rdoc_files:
32
+ extra_rdoc_files:
33
33
  - README.textile
34
34
  - COPYING
35
- files:
35
+ files:
36
36
  - COPYING
37
37
  - README.textile
38
38
  - Rakefile
39
39
  - VERSION
40
40
  - examples/gss_client.rb
41
+ - examples/gss_iov_client.rb
42
+ - examples/gss_iov_helpers.rb
43
+ - examples/gss_iov_server.rb
41
44
  - examples/gss_server.rb
42
45
  - gssapi.gemspec
43
46
  - lib/gssapi.rb
@@ -51,34 +54,30 @@ files:
51
54
  - test/spec/test_buffer_spec.rb
52
55
  homepage: http://github.com/zenchild/gssapi
53
56
  licenses: []
54
-
55
57
  post_install_message:
56
- rdoc_options:
58
+ rdoc_options:
57
59
  - -x
58
60
  - test/
59
61
  - -x
60
62
  - examples/
61
- require_paths:
63
+ require_paths:
62
64
  - lib
63
- required_ruby_version: !ruby/object:Gem::Requirement
65
+ required_ruby_version: !ruby/object:Gem::Requirement
64
66
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: 1.9.1
69
- required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: 1.8.7
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
72
  none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: "0"
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
75
77
  requirements: []
76
-
77
78
  rubyforge_project:
78
- rubygems_version: 1.8.11
79
+ rubygems_version: 1.8.10
79
80
  signing_key:
80
81
  specification_version: 3
81
82
  summary: A FFI wrapper around the system GSSAPI library.
82
83
  test_files: []
83
-
84
- has_rdoc: