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 +1 -1
- data/lib/gssapi.rb +1 -0
- data/lib/gssapi/exceptions.rb +35 -1
- data/lib/gssapi/lib_gssapi.rb +27 -29
- data/lib/gssapi/simple.rb +29 -22
- data/test/spec/gssapi_simple_spec.rb +24 -0
- data/test/spec/test_buffer_spec.rb +15 -0
- metadata +5 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/lib/gssapi.rb
CHANGED
data/lib/gssapi/exceptions.rb
CHANGED
@@ -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
|
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
|
data/lib/gssapi/lib_gssapi.rb
CHANGED
@@ -10,12 +10,10 @@ module GSSAPI
|
|
10
10
|
# Libc functions
|
11
11
|
|
12
12
|
# void *malloc(size_t size);
|
13
|
-
attach_function :malloc, [:
|
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, :
|
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 => :
|
62
|
-
:value
|
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] =
|
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
|
-
|
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
|
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
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
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
|
421
|
-
GSS_IOV_BUFFER_TYPE_HEADER = 2
|
422
|
-
GSS_IOV_BUFFER_TYPE_MECH_PARAMS = 3
|
423
|
-
GSS_IOV_BUFFER_TYPE_TRAILER = 7
|
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
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
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
|
data/lib/gssapi/simple.rb
CHANGED
@@ -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
|
17
|
-
#
|
18
|
-
#
|
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
|
-
|
35
|
-
|
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 :
|
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
|
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 :
|
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 :
|
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
|
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 :
|
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 :
|
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
|
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 :
|
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
|
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 :
|
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 :
|
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
|
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 :
|
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 :
|
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
|
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
|
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.
|
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-
|
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
|
-
|
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.
|
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.
|