net-ssh-kerberos 0.1.3 → 0.2.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/Rakefile +33 -4
- data/VERSION.yml +2 -2
- data/lib/net/ssh/authentication/methods/gssapi_with_mic.rb +5 -8
- data/lib/net/ssh/kerberos.rb +7 -20
- data/lib/net/ssh/kerberos/constants.rb +3 -7
- data/lib/net/ssh/kerberos/context.rb +75 -0
- data/lib/net/ssh/kerberos/drivers.rb +57 -0
- data/lib/net/ssh/kerberos/drivers/gss.rb +263 -0
- data/lib/net/ssh/kerberos/drivers/sspi.rb +216 -0
- data/test/gss_context_test.rb +3 -4
- data/test/gss_test.rb +43 -61
- data/test/sspi_context_test.rb +2 -4
- data/test/sspi_test.rb +31 -39
- metadata +7 -20
- data/lib/net/ssh/kerberos/common/context.rb +0 -71
- data/lib/net/ssh/kerberos/gss.rb +0 -9
- data/lib/net/ssh/kerberos/gss/api.rb +0 -163
- data/lib/net/ssh/kerberos/gss/context.rb +0 -115
- data/lib/net/ssh/kerberos/sspi.rb +0 -5
- data/lib/net/ssh/kerberos/sspi/api.rb +0 -228
- data/lib/net/ssh/kerberos/sspi/context.rb +0 -76
@@ -0,0 +1,216 @@
|
|
1
|
+
module Net; module SSH; module Kerberos; module Drivers
|
2
|
+
|
3
|
+
module SSPI
|
4
|
+
|
5
|
+
SEC_E_OK = 0x00000000
|
6
|
+
|
7
|
+
SEC_I_CONTINUE_NEEDED = 0x00090312
|
8
|
+
SEC_I_COMPLETE_NEEDED = 0x00090313
|
9
|
+
SEC_I_COMPLETE_AND_CONTINUE = 0x00090314
|
10
|
+
SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320
|
11
|
+
SEC_I_RENEGOTIATE = 0x00090321
|
12
|
+
|
13
|
+
SEC_E_INSUFFICIENT_MEMORY = 0x80090300
|
14
|
+
SEC_E_INVALID_HANDLE = 0x80090301
|
15
|
+
SEC_E_UNSUPPORTED_FUNCTION = 0x80090302
|
16
|
+
SEC_E_TARGET_UNKNOWN = 0x80090303
|
17
|
+
SEC_E_INTERNAL_ERROR = 0x80090304
|
18
|
+
SEC_E_SECPKG_NOT_FOUND = 0x80090305
|
19
|
+
SEC_E_NOT_OWNER = 0x80090306
|
20
|
+
SEC_E_INVALID_TOKEN = 0x80090308
|
21
|
+
SEC_E_LOGON_DENIED = 0x8009030C
|
22
|
+
SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D
|
23
|
+
SEC_E_NO_CREDENTIALS = 0x8009030E
|
24
|
+
SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311
|
25
|
+
SEC_E_WRONG_PRINCIPAL = 0x80090322
|
26
|
+
|
27
|
+
SECPKG_CRED_INBOUND = 0x00000001
|
28
|
+
SECPKG_CRED_OUTBOUND = 0x00000002
|
29
|
+
SECPKG_CRED_BOTH = 0x00000003
|
30
|
+
|
31
|
+
SECBUFFER_EMPTY = 0
|
32
|
+
SECBUFFER_DATA = 1
|
33
|
+
SECBUFFER_TOKEN = 2
|
34
|
+
|
35
|
+
SECURITY_NATIVE_DREP = 0x00000010
|
36
|
+
SECURITY_NETWORK_DREP = 0x00000000
|
37
|
+
|
38
|
+
SECPKG_ATTR_SIZES = 0
|
39
|
+
SECPKG_ATTR_NAMES = 1
|
40
|
+
|
41
|
+
ISC_REQ_DELEGATE = 0x00000001
|
42
|
+
ISC_REQ_MUTUAL_AUTH = 0x00000002
|
43
|
+
ISC_REQ_INTEGRITY = 0x00010000
|
44
|
+
|
45
|
+
module API
|
46
|
+
extend DL::Importable
|
47
|
+
include DLExtensions
|
48
|
+
|
49
|
+
dlload 'secur32'
|
50
|
+
|
51
|
+
typealias "void **", "p", PTR_REF_ENC, proc{|v| v.ptr}
|
52
|
+
typealias "SECURITY_STATUS", "L", proc{|v| v.to_i }, proc{|v| SSPIResult.new(v) }
|
53
|
+
typealias "USHORT", "unsigned short"
|
54
|
+
typealias "ULONG_REF", "unsigned long ref"
|
55
|
+
typealias "SEC_CHAR *", "char *"
|
56
|
+
typealias "PCtxtBuffer", "void **"
|
57
|
+
typealias "PCharBuffer", "P", nil, nil, "P", PTR_ENC
|
58
|
+
SecPkgInfo = struct [ "ULONG capabilities", "USHORT version", "USHORT rpcid",
|
59
|
+
"ULONG max_token", "SEC_CHAR *name", "SEC_CHAR *comment" ]
|
60
|
+
typealias "PSecPkgInfo", "p", PTR_REF_ENC, PTR_REF_DEC(SecPkgInfo)
|
61
|
+
SecHandle = struct2([ "ULONG lower", "ULONG upper" ]) do def nil?; lower.zero? && upper.zero? end end
|
62
|
+
typealias "PSecHandle", "P"
|
63
|
+
typealias "PCredHandle", "PSecHandle"
|
64
|
+
typealias "PCtxtHandle", "PSecHandle"
|
65
|
+
SecBuffer = struct2 [ "ULONG length", "ULONG type", "PCharBuffer data" ] do
|
66
|
+
def to_s; data.to_s(length) end
|
67
|
+
end
|
68
|
+
typealias "PSecBuffer", "P"
|
69
|
+
SecBufferDesc = struct2 [ "ULONG version", "ULONG count", "PSecBuffer buffers" ] do
|
70
|
+
def buffer(n) SecBuffer.new(@ptr[:buffers] + SecBuffer.size * n) end
|
71
|
+
end
|
72
|
+
typealias "PSecBufferDesc", "P"
|
73
|
+
TimeStamp = SecHandle
|
74
|
+
typealias "PTimeStamp", "P"
|
75
|
+
SecPkgSizes = struct [ "ULONG max_token", "ULONG max_signature",
|
76
|
+
"ULONG block_size", "ULONG security_trailer" ]
|
77
|
+
|
78
|
+
class SSPIResult
|
79
|
+
@@map = {}
|
80
|
+
SSPI.constants.each { |v| @@map[SSPI.const_get(v.to_s)] = v if v.to_s =~ /^SEC_[EI]_/ }
|
81
|
+
|
82
|
+
attr_reader :value
|
83
|
+
alias :to_i :value
|
84
|
+
|
85
|
+
def initialize(value)
|
86
|
+
value = [value].pack("L").unpack("L").first
|
87
|
+
raise "#{value.to_s(16)} is not a recognized result" unless @@map.has_key? value
|
88
|
+
@value = value
|
89
|
+
end
|
90
|
+
|
91
|
+
def ok?; value & 0x80000000 == 0 end
|
92
|
+
def complete?; value == 0 end
|
93
|
+
def incomplete?; SEC_I_COMPLETE_NEEDED==value || SEC_I_COMPLETE_AND_CONTINUE==value end
|
94
|
+
def failure?; value & 0x80000000 != 0 end
|
95
|
+
def temporary_failure?
|
96
|
+
value==SEC_E_LOGON_DENIED || value==SEC_E_NO_AUTHENTICATING_AUTHORITY || value==SEC_E_NO_CREDENTIALS
|
97
|
+
end
|
98
|
+
def to_s; @@map[@value].to_s end
|
99
|
+
def ==(result)
|
100
|
+
case result
|
101
|
+
when SSPIResult; @value == result.value
|
102
|
+
when Fixnum; @value == @@map[other]
|
103
|
+
else false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
extern 'SECURITY_STATUS FreeContextBuffer(void *)'
|
109
|
+
extern 'SECURITY_STATUS QuerySecurityPackageInfo(SEC_CHAR *, PSecPkgInfo)'
|
110
|
+
extern 'SECURITY_STATUS AcquireCredentialsHandle(void *, SEC_CHAR *, ULONG, void *, '+
|
111
|
+
'void *, void *, void *, PCredHandle, PTimeStamp)'
|
112
|
+
extern 'SECURITY_STATUS QueryCredentialsAttributes(PCredHandle, ULONG, PCtxtBuffer)'
|
113
|
+
extern 'SECURITY_STATUS FreeCredentialsHandle(PCredHandle)'
|
114
|
+
extern 'SECURITY_STATUS QueryContextAttributes(PCtxtHandle, ULONG, void *)'
|
115
|
+
extern 'SECURITY_STATUS CompleteAuthToken(PCtxtHandle, PSecBufferDesc)'
|
116
|
+
extern 'SECURITY_STATUS MakeSignature(PCtxtHandle, ULONG, PSecBufferDesc, ULONG)'
|
117
|
+
extern 'SECURITY_STATUS InitializeSecurityContext(PCredHandle, PCtxtHandle, char *, '+
|
118
|
+
'ULONG, ULONG, ULONG, PSecBufferDesc, ULONG, PCtxtHandle, '+
|
119
|
+
'PSecBufferDesc, ULONG_REF, PTimeStamp)'
|
120
|
+
extern 'SECURITY_STATUS DeleteSecurityContext(PCtxtHandle)'
|
121
|
+
|
122
|
+
def SecBuffer.createArray(types,data)
|
123
|
+
buffs = []
|
124
|
+
mem = DL::malloc(size * types.size)
|
125
|
+
0.upto(types.size - 1) do |n|
|
126
|
+
buff = new DL::PtrData.new(mem.to_i + (n * size), size)
|
127
|
+
buff.type = types[n]
|
128
|
+
n = data[n]
|
129
|
+
buff.data = Fixnum===n ? "\0" * n : n
|
130
|
+
buff.length = Fixnum===n ? n : n.length
|
131
|
+
buffs << buff
|
132
|
+
end
|
133
|
+
buffs
|
134
|
+
end
|
135
|
+
|
136
|
+
def SecBufferDesc.create(token)
|
137
|
+
desc = API::SecBufferDesc.malloc
|
138
|
+
desc.version = 0
|
139
|
+
desc.count = 1
|
140
|
+
desc.buffers = SecBuffer.createArray([SECBUFFER_TOKEN], [token]).first.to_ptr
|
141
|
+
desc
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.max_token; @@max_token end
|
146
|
+
|
147
|
+
# SSPI - Kerberos 5 mechanism support.
|
148
|
+
result = API.querySecurityPackageInfo "Kerberos", nil
|
149
|
+
if result.ok? and ! (pkg_info = API._args_[1]).nil?
|
150
|
+
@@max_token = pkg_info.max_token
|
151
|
+
API.freeContextBuffer pkg_info
|
152
|
+
else
|
153
|
+
raise "SSPI reports no support for Kerberos authentication"
|
154
|
+
end
|
155
|
+
|
156
|
+
class Context < Net::SSH::Kerberos::Context
|
157
|
+
def init(token=nil)
|
158
|
+
prev = @state.handle if @state && ! @state.handle.nil?
|
159
|
+
ctx = prev || API::SecHandle.malloc
|
160
|
+
input = API::SecBufferDesc.create(token) if token
|
161
|
+
output = API::SecBufferDesc.create(12288)
|
162
|
+
result = API.initializeSecurityContext @credentials, prev, @target,
|
163
|
+
ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH | ISC_REQ_INTEGRITY, 0,
|
164
|
+
SECURITY_NATIVE_DREP, input, 0, ctx, output, 0, ts=API::TimeStamp.malloc
|
165
|
+
result.failure? and raise GeneralError, "Error initializing security context: #{result}"
|
166
|
+
result = API.completeAuthToken ctx, output if result.incomplete?
|
167
|
+
result.failure? and raise GeneralError, "Error initializing security context: #{result}"
|
168
|
+
@state = State.new(ctx, result, output.buffers ? output.buffer(0).to_s : nil, ts)
|
169
|
+
if result.complete?
|
170
|
+
result = API.queryContextAttributes @state.handle, SECPKG_ATTR_SIZES, @sizes=API::SecPkgSizes.malloc
|
171
|
+
result.failure? and raise GeneralError, "Error initializing security context: #{result}"
|
172
|
+
@handle = @state.handle
|
173
|
+
end
|
174
|
+
@state.token
|
175
|
+
end
|
176
|
+
|
177
|
+
def get_mic(token)
|
178
|
+
desc = API::SecBufferDesc.malloc
|
179
|
+
desc.version = 0
|
180
|
+
desc.count = 2
|
181
|
+
desc.buffers = API::SecBuffer.createArray([SECBUFFER_DATA, SECBUFFER_TOKEN],
|
182
|
+
[token, @sizes.max_signature]).first.to_ptr
|
183
|
+
@state.result = API.makeSignature @handle, 0, desc, 0
|
184
|
+
@state.result.complete? or raise GeneralError, "Error creating the signature: #{result}"
|
185
|
+
desc.buffer(1).to_s
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
|
190
|
+
def acquire_current_credentials
|
191
|
+
result = API.acquireCredentialsHandle nil, "Kerberos", SECPKG_CRED_OUTBOUND, nil, nil, nil, nil,
|
192
|
+
creds=API::SecHandle.malloc, ts=API::TimeStamp.malloc
|
193
|
+
result.ok? or raise GeneralError, "Error acquiring credentials: #{result}"
|
194
|
+
result = API.queryCredentialsAttributes creds, SECPKG_ATTR_NAMES, nil
|
195
|
+
if result.ok?
|
196
|
+
name = API._args_[2]
|
197
|
+
begin return [creds, name.to_s]
|
198
|
+
ensure API.freeContextBuffer name
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def release_credentials(creds) API.freeCredentialsHandle creds unless creds.nil? end
|
204
|
+
|
205
|
+
def import_server_name(host) ['host/'+host, 'host/'+host] end
|
206
|
+
|
207
|
+
def release_server_name(target) end
|
208
|
+
|
209
|
+
def delete_context(handle)
|
210
|
+
API.deleteSecurityContext handle unless handle.nil?
|
211
|
+
API.freeContextBuffer @sizes unless @sizes.nil?
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end; end; end; end
|
data/test/gss_context_test.rb
CHANGED
@@ -2,10 +2,10 @@ require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
|
2
2
|
|
3
3
|
class GssContextTest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
if
|
5
|
+
if Net::SSH::Kerberos::Drivers.available.include? 'GSS'
|
6
6
|
|
7
7
|
def setup
|
8
|
-
@gss = Net::SSH::Kerberos::GSS::Context.new
|
8
|
+
@gss = Net::SSH::Kerberos::Drivers::GSS::Context.new
|
9
9
|
end
|
10
10
|
|
11
11
|
def teardown
|
@@ -22,13 +22,12 @@ if defined? Net::SSH::Kerberos::GSS::Context
|
|
22
22
|
@gss.init nil
|
23
23
|
state = @gss.send(:state)
|
24
24
|
assert ! state.handle.nil?, "Should have provided an initial context"
|
25
|
-
assert ! state.handle.handle.nil?, "Should have provided an initial context"
|
26
25
|
assert ! state.token.nil?, "Should have built an initial token"
|
27
26
|
assert state.token.length.nonzero?, "Should have built an initial token"
|
28
27
|
end
|
29
28
|
|
30
29
|
else
|
31
|
-
|
30
|
+
def test_nothing; assert true end
|
32
31
|
end
|
33
32
|
|
34
33
|
end
|
data/test/gss_test.rb
CHANGED
@@ -2,42 +2,38 @@ require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
|
2
2
|
|
3
3
|
class GssTest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
|
5
|
+
if Net::SSH::Kerberos::Drivers.available.include? 'GSS'
|
6
|
+
|
7
|
+
include Net::SSH::Kerberos::Drivers::GSS
|
6
8
|
|
7
9
|
def test_acquire_cred
|
8
|
-
|
9
|
-
result
|
10
|
-
|
10
|
+
result = API.gss_acquire_cred nil, 60, nil, GSS_C_INITIATE, nil, nil, 0
|
11
|
+
assert result.ok?, "gss_acquire_cred failed: #{result}"
|
12
|
+
creds = API._args_[4]
|
13
|
+
assert_not_equal creds, GSS_C_NO_CREDENTIAL, "Should acquire default credentials"
|
11
14
|
begin
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
assert_not_equal 0, oids.oidset.count, "Should provide the supported oids"
|
15
|
+
result = API.gss_inquire_cred creds, nil, 0, 0, nil
|
16
|
+
assert result.ok?, "gss_inquire_cred failed: #{result}"
|
17
|
+
name, oids = API._args_[1], API._args_[4]
|
18
|
+
assert_not_equal name, GSS_C_NO_NAME, "Should provide the internal name"
|
19
|
+
assert_not_equal oids, GSS_C_NO_OID_SET, "Should provide the supported oids"
|
20
|
+
assert oids.count > 0, "Should provide the supported oids"
|
19
21
|
begin
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
result = call_and_assert :gss_display_name, name.handle, buffer, oid
|
24
|
-
assert_not_equal 0, buffer.value.to_i, "Should provide the display name"
|
22
|
+
result = API.gss_display_name name, buffer=API::GssBuffer.malloc, nil
|
23
|
+
assert result.ok?, "gss_display_name failed: #{result}"
|
24
|
+
assert buffer.length > 0, "Should provide the display name"
|
25
25
|
begin
|
26
|
-
assert_not_equal
|
26
|
+
assert_not_equal API._args_[2], GSS_C_NO_OID, "Should provide the supported oid"
|
27
27
|
#$stderr.puts "credentials: #{creds.handle.to_i} #{buffer.value} (OID: #{oid.oid.length}, #{oid.oid.to_hex})"
|
28
28
|
ensure
|
29
|
-
|
29
|
+
API.gss_release_buffer buffer
|
30
30
|
end
|
31
31
|
ensure
|
32
|
-
|
33
|
-
API.
|
34
|
-
API.gss_release_oid_set minor_status, oids
|
35
|
-
assert_equal 0, name.handle.to_i, "Should release the internal name"
|
36
|
-
assert_equal 0, oids.ptr.to_i, "Should release the supported oids"
|
32
|
+
API.gss_release_name name
|
33
|
+
API.gss_release_oid_set oids
|
37
34
|
end
|
38
35
|
ensure
|
39
|
-
|
40
|
-
API.gss_release_cred minor_status, creds
|
36
|
+
API.gss_release_cred creds
|
41
37
|
end
|
42
38
|
end
|
43
39
|
|
@@ -46,52 +42,38 @@ class GssTest < Test::Unit::TestCase
|
|
46
42
|
buffer = API::GssBuffer.malloc
|
47
43
|
buffer.value = target_name
|
48
44
|
buffer.length = target_name.length
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
result =
|
54
|
-
|
55
|
-
|
56
|
-
buffer = API::GssBuffer.malloc
|
57
|
-
result = call_and_assert :gss_display_name, target_name.handle, buffer, nil
|
58
|
-
assert_not_equal 0, buffer.value.to_i, "Should provide the display name"
|
45
|
+
result = API.gss_import_name buffer, GSS_C_NT_HOSTBASED_SERVICE, nil
|
46
|
+
assert result.ok?, "gss_import_name failed: #{result}"
|
47
|
+
target = API._args_[2]
|
48
|
+
assert_not_equal target, GSS_C_NO_NAME, "Should import the name"
|
49
|
+
result = API.gss_display_name target, buffer=API::GssBuffer.malloc, nil
|
50
|
+
assert result.ok?, "gss_display_name failed: #{result}"
|
51
|
+
assert buffer.length > 0, "Should provide the display name"
|
59
52
|
#$stderr.puts "target: #{buffer.value} (OID: #{mech.length}, #{mech.to_hex})"
|
60
|
-
|
53
|
+
API.gss_release_buffer buffer
|
61
54
|
|
62
|
-
mech.elements = GSS_KRB5_MECH
|
63
|
-
mech.length = GSS_KRB5_MECH.length
|
64
|
-
actual_mech = API::GssOIDRef.malloc
|
65
|
-
context = API::GssContextRef.malloc
|
66
|
-
context.handle = GSS_C_NO_CONTEXT
|
67
55
|
buffer.value = nil
|
68
56
|
buffer.length = 0
|
69
|
-
result =
|
70
|
-
|
71
|
-
|
72
|
-
|
57
|
+
result = API.gss_init_sec_context GSS_C_NO_CREDENTIAL, GSS_C_NO_CONTEXT, target, GSS_C_KRB5,
|
58
|
+
GSS_C_DELEG_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG, 60,
|
59
|
+
GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, nil, buffer, 0, 0
|
60
|
+
assert result.ok?, "gss_init_sec_context failed: #{result}"
|
61
|
+
context, actual_mech = API._args_[1], API._args_[8]
|
62
|
+
assert_not_equal context, GSS_C_NO_CONTEXT, "Should initialize the security context"
|
73
63
|
begin
|
74
|
-
assert_equal
|
64
|
+
assert_equal result.status, GSS_S_CONTINUE_NEEDED, "Should need continued initialization of the security context"
|
75
65
|
assert buffer.length > 0, "Should output a token to send to the server"
|
66
|
+
assert_not_equal actual_mech, GSS_C_NO_OID, "Should initialize the security context"
|
76
67
|
#$stderr.puts "context: (#{buffer.length}) (OID: #{actual_mech.oid.length}, #{actual_mech.oid.to_hex})"
|
77
|
-
|
68
|
+
API.gss_release_buffer buffer
|
78
69
|
ensure
|
79
|
-
|
80
|
-
API.gss_delete_sec_context minor_status, context, nil
|
81
|
-
if buffer.value.nil?
|
82
|
-
assert_equal 0, context.handle.to_i, "Should delete the security context"
|
83
|
-
end
|
70
|
+
API.gss_delete_sec_context context, nil if context and buffer.value.nil?
|
84
71
|
end
|
85
72
|
end
|
86
73
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
result = API.send sym, minor_status, *args
|
92
|
-
assert_equal 0, (result & 0xffff0000), "#{sym} failed: 0x#{result.to_s(16)}"
|
93
|
-
assert_equal 0, minor_status.value, "#{sym} failed: minor status 0x#{minor_status.value.to_s(16)}"
|
94
|
-
result
|
95
|
-
end
|
74
|
+
else
|
75
|
+
def test_nothing; assert true end
|
76
|
+
end
|
77
|
+
|
96
78
|
end
|
97
79
|
|
data/test/sspi_context_test.rb
CHANGED
@@ -2,10 +2,10 @@ require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
|
2
2
|
|
3
3
|
class SspiContextTest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
if
|
5
|
+
if Net::SSH::Kerberos::Drivers.available.include? 'SSPI'
|
6
6
|
|
7
7
|
def setup
|
8
|
-
@gss = Net::SSH::Kerberos::SSPI::Context.new
|
8
|
+
@gss = Net::SSH::Kerberos::Drivers::SSPI::Context.new
|
9
9
|
end
|
10
10
|
|
11
11
|
def teardown
|
@@ -18,8 +18,6 @@ if defined? Net::SSH::Kerberos::SSPI::Context
|
|
18
18
|
end
|
19
19
|
|
20
20
|
else
|
21
|
-
$stderr.puts "Skipping SSPI tests on this platform: Windows SSPI was not loaded."
|
22
|
-
|
23
21
|
def test_nothing; assert true end
|
24
22
|
end
|
25
23
|
|
data/test/sspi_test.rb
CHANGED
@@ -2,69 +2,61 @@ require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
|
2
2
|
|
3
3
|
class SspiTest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
if
|
5
|
+
if Net::SSH::Kerberos::Drivers.available.include? 'SSPI'
|
6
6
|
|
7
|
-
include
|
7
|
+
include Net::SSH::Kerberos::Drivers::SSPI
|
8
8
|
|
9
9
|
def test_query_security_package_info
|
10
|
-
|
11
|
-
result
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
assert pkg_info.max_token
|
16
|
-
|
17
|
-
|
10
|
+
result = API.querySecurityPackageInfo "Kerberos", nil
|
11
|
+
assert result.ok?, "querySecurityPackageInfo failed: #{result}"
|
12
|
+
#$stderr.puts "querySecurityPackageInfo => #{pkg_info.comment} (max_token=#{pkg_info.max_token})"
|
13
|
+
pkg_info = API._args_[1]
|
14
|
+
assert_equal pkg_info.name.to_s, "Kerberos"
|
15
|
+
assert pkg_info.max_token >= 128, "The maximum token size is assumed to be greater than 127 bytes"
|
16
|
+
assert pkg_info.max_token <= 12288, "The maximum token size is assumed to be less than 12289 bytes"
|
17
|
+
result = API.freeContextBuffer pkg_info
|
18
|
+
assert result.ok?, "freeContextBuffer failed: #{result}"
|
18
19
|
end
|
19
20
|
|
20
21
|
def test_security_context_initialization
|
21
|
-
|
22
|
-
|
23
|
-
result = API::AcquireCredentialsHandle nil, "Kerberos", SECPKG_CRED_OUTBOUND, nil, nil, nil, nil, creds, ts
|
22
|
+
result = API.acquireCredentialsHandle nil, "Kerberos", SECPKG_CRED_OUTBOUND, nil, nil, nil, nil,
|
23
|
+
creds=API::SecHandle.malloc, ts=API::TimeStamp.malloc
|
24
24
|
unless result.temporary_failure?
|
25
|
-
assert result.ok?, "
|
25
|
+
assert result.ok?, "acquireCredentialsHandle failed: #{result}"
|
26
26
|
assert ! creds.nil?, "Should acquire a credentials handle"
|
27
27
|
begin
|
28
|
-
|
29
|
-
result
|
30
|
-
|
31
|
-
names = buff.to_ptr.ptr
|
28
|
+
result = API.queryCredentialsAttributes creds, SECPKG_ATTR_NAMES, nil
|
29
|
+
assert result.ok?, "queryCredentialsAttributes failed: #{result}"
|
30
|
+
names = API._args_[2]
|
32
31
|
assert ! names.nil?, "Should return the user name."
|
32
|
+
#$stderr.puts "queryCredentialsAttributes: (#{result}) #{names.to_s}"
|
33
33
|
begin
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
req = ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH
|
39
|
-
result = API::InitializeSecurityContext creds, nil, 'host/'+Socket.gethostbyname('localhost')[0],
|
40
|
-
req, 0, SECURITY_NATIVE_DREP, nil, 0, ctx, output, ctxAttr, ts
|
34
|
+
output = API::SecBufferDesc.create(12288)
|
35
|
+
result = API.initializeSecurityContext creds, nil, 'host/'+Socket.gethostbyname('localhost')[0],
|
36
|
+
ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH | ISC_REQ_INTEGRITY, 0, SECURITY_NATIVE_DREP,
|
37
|
+
nil, 0, ctx=API::SecHandle.malloc, output, 0, ts=API::TimeStamp.malloc
|
41
38
|
unless result.temporary_failure?
|
42
|
-
assert result.ok?, "
|
39
|
+
assert result.ok?, "initializeSecurityContext failed: #{result}"
|
43
40
|
begin
|
44
41
|
assert ! ctx.nil?, "Should initialize a context handle"
|
45
|
-
assert ! output.
|
46
|
-
assert output.
|
42
|
+
assert ! output.buffer(0).data.nil?, "Should output a token into the buffer"
|
43
|
+
assert output.buffer(0).length < 12288, "Should output a token into the buffer"
|
47
44
|
ensure
|
48
|
-
result = API
|
49
|
-
ctx = nil if result.ok?
|
45
|
+
ctx = nil if (result = API.deleteSecurityContext(ctx)).ok?
|
50
46
|
end
|
51
|
-
assert ctx.nil?, "
|
47
|
+
assert ctx.nil?, "deleteSecurityContext failed: #{result}"
|
52
48
|
end
|
53
49
|
ensure
|
54
|
-
result = API
|
55
|
-
names = nil if result.ok?
|
50
|
+
names = nil if (result = API.freeContextBuffer(names)).ok?
|
56
51
|
end
|
57
|
-
assert names.nil?, "
|
52
|
+
assert names.nil?, "freeContextBuffer failed: #{result}"
|
58
53
|
ensure
|
59
|
-
result = API
|
60
|
-
creds = nil if result.ok?
|
54
|
+
creds = nil if (result = API.freeCredentialsHandle(creds)).ok?
|
61
55
|
end
|
62
|
-
assert creds.nil?, "
|
56
|
+
assert creds.nil?, "freeCredentialsHandle failed: #{result}"
|
63
57
|
end
|
64
58
|
end
|
65
59
|
else
|
66
|
-
$stderr.puts "Skipping SSPI tests on this platform: Windows SSPI was not loaded."
|
67
|
-
|
68
60
|
def test_nothing; assert true end
|
69
61
|
end
|
70
62
|
|