gssapi 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: