gssapi 1.0.1 → 1.0.2

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.1
1
+ 1.0.2
@@ -7,6 +7,7 @@ require 'ffi'
7
7
  module GSSAPI
8
8
  module LibGSSAPI
9
9
  extend FFI::Library
10
+ FFI::add_typedef(:uint32, :OM_uint32)
10
11
 
11
12
  GSSAPI_LIB_TYPE = :mit unless defined?(GSSAPI_LIB_TYPE)
12
13
  end
@@ -4,5 +4,39 @@ Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
4
4
  Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
5
5
  =end
6
6
  module GSSAPI
7
- class GssApiError < StandardError; end
7
+ class GssApiError < StandardError
8
+
9
+ include LibGSSAPI
10
+
11
+ def message; to_s + ": " + @s; end
12
+
13
+ def initialize(maj_stat = nil, min_stat = nil)
14
+ if(maj_stat.nil? && min_stat.nil?)
15
+ @s = '(no error info)'
16
+ else
17
+ min = FFI::MemoryPointer.new :OM_uint32
18
+ message_context = FFI::MemoryPointer.new :OM_uint32
19
+ @s = ''
20
+ oid = GssOID.gss_c_no_oid
21
+ min_stat = min_stat.read_uint32
22
+ [[maj_stat, GSS_C_GSS_CODE], [min_stat, GSS_C_MECH_CODE]].each do |m, t|
23
+ message_context.write_int 0
24
+ begin
25
+ out_buff = ManagedGssBufferDesc.new
26
+ maj = gss_display_status(min, m, t, oid, message_context, out_buff.pointer)
27
+ if (maj != 0)
28
+ @s += "failed to retrieve GSSAPI display for status #{m}"
29
+ @s += " of major status #{maj_stat}, minor_status #{min_stat}\n"
30
+ @s += "(with major status #{maj}, minor status #{min.read_uint32}\n"
31
+ break
32
+ end
33
+ @s += out_buff.value.to_s + "\n"
34
+ end while message_context.read_int != 0
35
+ end
36
+ end
37
+
38
+ # We need to call this so we can pass the message to the Error when we have no arguments
39
+ super()
40
+ end
41
+ end
8
42
  end
@@ -10,12 +10,10 @@ module GSSAPI
10
10
  # Libc functions
11
11
 
12
12
  # void *malloc(size_t size);
13
- attach_function :malloc, [:uint32], :pointer
13
+ attach_function :malloc, [:size_t], :pointer
14
14
 
15
15
  # void *memcpy(void *dest, const void *src, size_t n);
16
- attach_function :memcpy, [:pointer, :pointer, :uint32], :pointer
17
-
18
- typedef :uint32, :OM_uint32
16
+ attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
19
17
 
20
18
  class GssOID < FFI::Struct
21
19
  layout :length => :OM_uint32,
@@ -58,8 +56,8 @@ module GSSAPI
58
56
  module GssBufferDescLayout
59
57
  def self.included(base)
60
58
  base.class_eval do
61
- layout :length => :size_t,
62
- :value => :pointer # pointer of :void
59
+ layout :length => :OM_uint32,
60
+ :value => :pointer # pointer of :void
63
61
 
64
62
  def length
65
63
  self[:length]
@@ -108,7 +106,7 @@ module GSSAPI
108
106
  elsif(val.is_a?(Fixnum))
109
107
  buff = FFI::MemoryPointer.new :OM_uint32
110
108
  buff.write_int val
111
- self[:length] = val.to_s.length
109
+ self[:length] = FFI::type_size :OM_uint32
112
110
  self[:value] = buff
113
111
  else
114
112
  raise StandardError, "Can't handle type #{val.class.name}"
@@ -190,11 +188,7 @@ module GSSAPI
190
188
  class GssCtxIdT < GssPointer
191
189
  def self.release_ptr(context_ptr)
192
190
  min_stat = FFI::MemoryPointer.new :OM_uint32
193
- # FIXME: change to GSS_C_NO_BUFFER
194
- empty_buff = LibGSSAPI::UnManagedGssBufferDesc.new
195
- empty_buff[:length] = 0
196
- empty_buff[:value] = nil
197
- maj_stat = LibGSSAPI.gss_delete_sec_context(min_stat, context_ptr, empty_buff.pointer)
191
+ maj_stat = LibGSSAPI.gss_delete_sec_context(min_stat, context_ptr, LibGSSAPI::GSS_C_NO_BUFFER)
198
192
  end
199
193
 
200
194
  def self.gss_c_no_context
@@ -335,6 +329,8 @@ module GSSAPI
335
329
  # OM_uint32 krb5_gss_register_acceptor_identity(const char *);
336
330
  attach_function :krb5_gss_register_acceptor_identity, [:string], :OM_uint32
337
331
 
332
+ # 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)
333
+ attach_function :gss_display_status, [:pointer, :OM_uint32, :int, :pointer, :pointer, :pointer], :OM_uint32
338
334
 
339
335
  # Variable definitions
340
336
  # --------------------
@@ -377,7 +373,9 @@ module GSSAPI
377
373
 
378
374
 
379
375
  # GSSAPI Status & Error Codes
380
- GSS_S_COMPLETE = 0
376
+ GSS_S_COMPLETE = 0
377
+ GSS_C_GSS_CODE = 1
378
+ GSS_C_MECH_CODE = 2
381
379
 
382
380
  GSS_C_CALLING_ERRORS = {
383
381
  (1 << GSS_C_CALLING_ERROR_OFFSET) => "GSS_S_CALL_INACCESSIBLE_READ",
@@ -386,11 +384,11 @@ module GSSAPI
386
384
  }
387
385
 
388
386
  GSS_C_SUPPLEMENTARY_CODES = {
389
- (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) => "GSS_S_CONTINUE_NEEDED",
390
- (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) => "GSS_S_DUPLICATE_TOKEN",
391
- (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) => "GSS_S_OLD_TOKEN",
392
- (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) => "GSS_S_UNSEQ_TOKEN",
393
- (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) => "GSS_S_GAP_TOKEN"
387
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) => "GSS_S_CONTINUE_NEEDED",
388
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) => "GSS_S_DUPLICATE_TOKEN",
389
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) => "GSS_S_OLD_TOKEN",
390
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) => "GSS_S_UNSEQ_TOKEN",
391
+ (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) => "GSS_S_GAP_TOKEN"
394
392
  }
395
393
 
396
394
  GSS_C_ROUTINE_ERRORS = {
@@ -417,10 +415,10 @@ module GSSAPI
417
415
 
418
416
  # IOV Buffer Types (gssapi_ext.h)
419
417
  GSS_IOV_BUFFER_TYPE_EMPTY = 0
420
- GSS_IOV_BUFFER_TYPE_DATA = 1 # Packet data
421
- GSS_IOV_BUFFER_TYPE_HEADER = 2 # Mechanism header
422
- GSS_IOV_BUFFER_TYPE_MECH_PARAMS = 3 # Mechanism specific parameters
423
- GSS_IOV_BUFFER_TYPE_TRAILER = 7 # Mechanism trailer
418
+ GSS_IOV_BUFFER_TYPE_DATA = 1 # Packet data
419
+ GSS_IOV_BUFFER_TYPE_HEADER = 2 # Mechanism header
420
+ GSS_IOV_BUFFER_TYPE_MECH_PARAMS = 3 # Mechanism specific parameters
421
+ GSS_IOV_BUFFER_TYPE_TRAILER = 7 # Mechanism trailer
424
422
  GSS_IOV_BUFFER_TYPE_PADDING = 9 # Padding
425
423
  GSS_IOV_BUFFER_TYPE_STREAM = 10 # Complete wrap token
426
424
  GSS_IOV_BUFFER_TYPE_SIGN_ONLY = 11 # Sign only packet data
@@ -432,13 +430,13 @@ module GSSAPI
432
430
 
433
431
 
434
432
  # Various Null values. (gssapi.h)
435
- GSS_C_NO_NAME = FFI::Pointer.new(:pointer, 0) # ((gss_name_t) 0)
436
- GSS_C_NO_BUFFER = FFI::Pointer.new(:pointer, 0) # ((gss_buffer_t) 0)
437
- GSS_C_NO_OID = FFI::Pointer.new(:pointer, 0) # ((gss_OID) 0)
438
- GSS_C_NO_OID_SET = FFI::Pointer.new(:pointer, 0) # ((gss_OID_set) 0)
439
- GSS_C_NO_CONTEXT = FFI::Pointer.new(:pointer, 0) # ((gss_ctx_id_t) 0)
440
- GSS_C_NO_CREDENTIAL = FFI::Pointer.new(:pointer, 0) # ((gss_cred_id_t) 0)
441
- GSS_C_NO_CHANNEL_BINDINGS = FFI::Pointer.new(:pointer, 0) # ((gss_channel_bindings_t) 0)
433
+ GSS_C_NO_NAME = FFI::Pointer.new(:pointer, 0) # ((gss_name_t) 0)
434
+ GSS_C_NO_BUFFER = FFI::Pointer.new(:pointer, 0) # ((gss_buffer_t) 0)
435
+ GSS_C_NO_OID = FFI::Pointer.new(:pointer, 0) # ((gss_OID) 0)
436
+ GSS_C_NO_OID_SET = FFI::Pointer.new(:pointer, 0) # ((gss_OID_set) 0)
437
+ GSS_C_NO_CONTEXT = FFI::Pointer.new(:pointer, 0) # ((gss_ctx_id_t) 0)
438
+ GSS_C_NO_CREDENTIAL = FFI::Pointer.new(:pointer, 0) # ((gss_cred_id_t) 0)
439
+ GSS_C_NO_CHANNEL_BINDINGS = FFI::Pointer.new(:pointer, 0) # ((gss_channel_bindings_t) 0)
442
440
  GSS_C_EMPTY_BUFFER = ManagedGssBufferDesc.new
443
441
 
444
442
  end #end LibGSSAPI
@@ -13,9 +13,12 @@ module GSSAPI
13
13
 
14
14
  # Initialize a new GSSAPI::Simple object
15
15
  # @param [String] host_name the fully qualified host name
16
- # @param [String] service_name the service name. This can either be in the form svc@example.org
17
- # or just svc. If there is no '@example.org' part the host_name will be appended. If no
18
- # service_name is given at all the default service of 'host' will be used.
16
+ # @param [String] service_name The service name. This can either be a
17
+ # GSS_KRB5_NT_PRINCIPAL_NAME in the form of srvc/fqdn@REALM
18
+ # or
19
+ # GSS_C_NT_HOSTBASED_SERVICE in the form of srvc@fqdn
20
+ # If there is no '@fqdn' part, the host_name will be appended.
21
+ # If no service_name is given at all the default service of 'host@fqdn' will be used.
19
22
  def initialize(host_name, service_name=nil, keytab=nil)
20
23
  @host = host_name
21
24
  @service = service_name.nil? ? "host@#{@host}" : (service_name.include?('@') ? service_name : "#{service_name}@#{@host}")
@@ -31,13 +34,17 @@ module GSSAPI
31
34
  def import_name(str)
32
35
  buff_str = LibGSSAPI::UnManagedGssBufferDesc.new
33
36
  buff_str.value = str
34
- mech = LibGSSAPI::GssOID.gss_c_no_oid
35
- #mech = LibGSSAPI.GSS_C_NT_HOSTBASED_SERVICE
37
+ # Choose the appropriate mechanism based on the string passed.
38
+ if (str =~ /[A-Za-z0-9]+\/[^@]+@.+$/)
39
+ mech = LibGSSAPI::GssOID.gss_c_no_oid
40
+ else
41
+ mech = LibGSSAPI.GSS_C_NT_HOSTBASED_SERVICE
42
+ end
36
43
  name = FFI::MemoryPointer.new :pointer # gss_name_t
37
- min_stat = FFI::MemoryPointer.new :uint32
44
+ min_stat = FFI::MemoryPointer.new :OM_uint32
38
45
 
39
46
  maj_stat = LibGSSAPI.gss_import_name(min_stat, buff_str.pointer, mech, name)
40
- raise GssApiError, "gss_import_name did not return GSS_S_COMPLETE. Error code: maj: #{maj_stat}, min: #{min_stat.read_int}" if maj_stat != 0
47
+ raise GssApiError.new(maj_stat, min_stat), "gss_import_name did not return GSS_S_COMPLETE" if maj_stat != 0
41
48
 
42
49
  LibGSSAPI::GssNameT.new(name.get_pointer(0))
43
50
  end
@@ -53,7 +60,7 @@ module GSSAPI
53
60
  # @return [String, true] if a continuation flag is set it will return the output token that is needed to send
54
61
  # to the remote host. Otherwise it returns true and the GSS security context has been established.
55
62
  def init_context(in_token = nil, opts = {})
56
- min_stat = FFI::MemoryPointer.new :uint32
63
+ min_stat = FFI::MemoryPointer.new :OM_uint32
57
64
  ctx = (@context.nil? ? LibGSSAPI::GssCtxIdT.gss_c_no_context.address_of : @context.address_of)
58
65
  mech = LibGSSAPI::GssOID.gss_c_no_oid
59
66
  if(opts[:flags])
@@ -66,7 +73,7 @@ module GSSAPI
66
73
  in_tok = LibGSSAPI::UnManagedGssBufferDesc.new
67
74
  in_tok.value = in_token
68
75
  out_tok = LibGSSAPI::ManagedGssBufferDesc.new
69
- ret_flags = FFI::MemoryPointer.new :uint32
76
+ ret_flags = FFI::MemoryPointer.new :OM_uint32
70
77
 
71
78
 
72
79
  maj_stat = LibGSSAPI.gss_init_sec_context(min_stat,
@@ -83,7 +90,7 @@ module GSSAPI
83
90
  ret_flags,
84
91
  nil)
85
92
 
86
- raise GssApiError, "gss_init_sec_context did not return GSS_S_COMPLETE. Error code: maj: #{maj_stat}, min: #{min_stat.read_int}" if maj_stat > 1
93
+ raise GssApiError.new(maj_stat, min_stat), "gss_init_sec_context did not return GSS_S_COMPLETE" if maj_stat > 1
87
94
 
88
95
  @context = LibGSSAPI::GssCtxIdT.new(ctx.get_pointer(0))
89
96
  maj_stat == 1 ? out_tok.value : true
@@ -97,7 +104,7 @@ module GSSAPI
97
104
  def accept_context(in_token)
98
105
  raise GssApiError, "No credentials yet acquired. Call #{self.class.name}#acquire_credentials first" if @scred.nil?
99
106
 
100
- min_stat = FFI::MemoryPointer.new :uint32
107
+ min_stat = FFI::MemoryPointer.new :OM_uint32
101
108
  ctx = (@context.nil? ? LibGSSAPI::GssCtxIdT.gss_c_no_context.address_of : @context.address_of)
102
109
  no_chn_bind = LibGSSAPI::GSS_C_NO_CHANNEL_BINDINGS
103
110
  client = FFI::MemoryPointer.new :pointer # Will hold the initiating client name after the call
@@ -105,7 +112,7 @@ module GSSAPI
105
112
  in_tok = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
106
113
  in_tok.value = in_token
107
114
  out_tok = GSSAPI::LibGSSAPI::ManagedGssBufferDesc.new
108
- ret_flags = FFI::MemoryPointer.new :uint32
115
+ ret_flags = FFI::MemoryPointer.new :OM_uint32
109
116
 
110
117
  maj_stat = LibGSSAPI.gss_accept_sec_context(min_stat,
111
118
  ctx,
@@ -118,7 +125,7 @@ module GSSAPI
118
125
  ret_flags,
119
126
  nil, nil)
120
127
 
121
- raise GssApiError, "gss_accept_sec_context did not return GSS_S_COMPLETE. Error code: maj: #{maj_stat}, min: #{min_stat.read_int}" if maj_stat > 1
128
+ raise GssApiError.new(maj_stat, min_stat), "gss_accept_sec_context did not return GSS_S_COMPLETE" if maj_stat > 1
122
129
 
123
130
  @context = LibGSSAPI::GssCtxIdT.new(ctx.get_pointer(0))
124
131
  out_tok.length > 0 ? out_tok.value : true
@@ -132,7 +139,7 @@ module GSSAPI
132
139
  # @return [true] It will return true if everything succeeds and the @scred variable will be set for future methods. If
133
140
  # an error ocurrs an exception will be raised.
134
141
  def acquire_credentials(princ = @int_svc_name, opts = {:usage => :accept})
135
- min_stat = FFI::MemoryPointer.new :uint32
142
+ min_stat = FFI::MemoryPointer.new :OM_uint32
136
143
  scred = FFI::MemoryPointer.new :pointer
137
144
 
138
145
  case opts[:usage]
@@ -147,7 +154,7 @@ module GSSAPI
147
154
  end
148
155
 
149
156
  maj_stat = LibGSSAPI.gss_acquire_cred(min_stat, princ, 0, LibGSSAPI::GSS_C_NO_OID_SET, usage, scred, nil, nil)
150
- raise GssApiError, "gss_acquire_cred did not return GSS_S_COMPLETE. Error code: maj: #{maj_stat}, min: #{min_stat.read_int}" if maj_stat != 0
157
+ raise GssApiError.new(maj_stat, min_stat), "gss_acquire_cred did not return GSS_S_COMPLETE" if maj_stat != 0
151
158
 
152
159
  @scred = LibGSSAPI::GssCredIdT.new(scred.get_pointer(0))
153
160
  true
@@ -158,15 +165,15 @@ module GSSAPI
158
165
  # @param [Boolean] encrypt Whether or not to encrypt the message or just sign it. The default is to encrypt.
159
166
  # @return [String] The wrapped message. It will raise an exception on error
160
167
  def wrap_message(msg, encrypt = true)
161
- min_stat = FFI::MemoryPointer.new :uint32
168
+ min_stat = FFI::MemoryPointer.new :OM_uint32
162
169
  conf_req = (encrypt ? 1 : 0)
163
170
  qop_req = GSSAPI::LibGSSAPI::GSS_C_QOP_DEFAULT
164
171
  in_buff = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
165
172
  in_buff.value = msg
166
- conf_state = FFI::MemoryPointer.new :uint32
173
+ conf_state = FFI::MemoryPointer.new :OM_uint32
167
174
  out_buff = GSSAPI::LibGSSAPI::ManagedGssBufferDesc.new
168
175
  maj_stat = GSSAPI::LibGSSAPI.gss_wrap(min_stat, @context, conf_req, qop_req, in_buff.pointer, conf_state, out_buff.pointer)
169
- raise GssApiError, "Failed to gss_wrap message. Error code: maj: #{maj_stat}, min: #{min_stat.read_int}" if maj_stat != 0
176
+ raise GssApiError.new(maj_stat, min_stat), "Failed to gss_wrap message" if maj_stat != 0
170
177
  out_buff.value
171
178
  end
172
179
 
@@ -174,16 +181,16 @@ module GSSAPI
174
181
  # @param [String] msg The message to unwrap
175
182
  # @param [Boolean] encrypted Whether or not this message was encrypted (true) or just signed (false)
176
183
  def unwrap_message(msg, encrypted = true)
177
- min_stat = FFI::MemoryPointer.new :uint32
184
+ min_stat = FFI::MemoryPointer.new :OM_uint32
178
185
  in_buff = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
179
186
  in_buff.value = msg
180
187
  out_buff = GSSAPI::LibGSSAPI::ManagedGssBufferDesc.new
181
188
  conf_state = FFI::MemoryPointer.new :int
182
189
  conf_state.write_int((encrypted ? 1 : 0))
183
- q_op = FFI::MemoryPointer.new :uint32
190
+ q_op = FFI::MemoryPointer.new :OM_uint32
184
191
  q_op.write_int(0)
185
192
  maj_stat = GSSAPI::LibGSSAPI.gss_unwrap(min_stat, @context, in_buff.pointer, out_buff.pointer, conf_state, q_op)
186
- raise GssApiError, "Failed to gss_unwrap message. Error code: maj: #{maj_stat}, min: #{min_stat.read_int}" if maj_stat != 0
193
+ raise GssApiError.new(maj_stat, min_stat), "Failed to gss_unwrap message" if maj_stat != 0
187
194
  out_buff.value
188
195
  end
189
196
 
@@ -191,7 +198,7 @@ module GSSAPI
191
198
  # @param [String] keytab the path to the keytab
192
199
  def set_keytab(keytab)
193
200
  maj_stat = LibGSSAPI.krb5_gss_register_acceptor_identity(keytab)
194
- raise GssApiError, "krb5_gss_register_acceptor_identity did not return GSS_S_COMPLETE. Error code: maj: #{maj_stat}, min: #{min_stat.read_int}" if maj_stat != 0
201
+ raise GssApiError.new(maj_stat, min_stat), "krb5_gss_register_acceptor_identity did not return GSS_S_COMPLETE" if maj_stat != 0
195
202
  true
196
203
  end
197
204
 
@@ -0,0 +1,24 @@
1
+ $: << File.dirname(__FILE__) + '/../../lib/'
2
+ require 'gssapi'
3
+ require 'base64'
4
+ require 'yaml'
5
+
6
+
7
+ describe GSSAPI::Simple, 'Test the Simple GSSAPI interface' do
8
+
9
+ before :all do
10
+ @conf = YAML.load_file "#{File.dirname(__FILE__)}/conf_file.yaml"
11
+ end
12
+
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
17
+ end
18
+
19
+ 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
22
+ end
23
+
24
+ end
@@ -0,0 +1,15 @@
1
+ $: << File.dirname(__FILE__) + '/../../lib/'
2
+ require 'gssapi'
3
+
4
+ describe GSSAPI::LibGSSAPI::UnManagedGssBufferDesc, 'Unmanaged Buffer Test' do
5
+ it 'should create a new UnManagedGssBufferDesc and assign to it and test GC' do
6
+ 0.upto 100 do |i|
7
+ b = GSSAPI::LibGSSAPI::UnManagedGssBufferDesc.new
8
+ GC.start
9
+ b.value = 'asdf'
10
+ end
11
+
12
+ # If we get here without any errors we should be golden
13
+ true.should be_true
14
+ end
15
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: gssapi
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.0.1
5
+ version: 1.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Dan Wanek
@@ -10,8 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-08-22 00:00:00 -05:00
14
- default_executable:
13
+ date: 2011-09-10 00:00:00 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: ffi
@@ -48,7 +47,8 @@ files:
48
47
  - lib/gssapi/lib_gssapi_loader.rb
49
48
  - lib/gssapi/simple.rb
50
49
  - preamble
51
- has_rdoc: true
50
+ - test/spec/gssapi_simple_spec.rb
51
+ - test/spec/test_buffer_spec.rb
52
52
  homepage: http://github.com/zenchild/gssapi
53
53
  licenses: []
54
54
 
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  requirements: []
76
76
 
77
77
  rubyforge_project:
78
- rubygems_version: 1.6.2
78
+ rubygems_version: 1.8.10
79
79
  signing_key:
80
80
  specification_version: 3
81
81
  summary: A FFI wrapper around the system GSSAPI library.