net-ssh-kerberos 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -1
- data/VERSION.yml +1 -1
- data/lib/net/ssh/authentication/methods/gssapi_with_mic.rb +13 -11
- data/lib/net/ssh/kerberos.rb +12 -1
- data/lib/net/ssh/kerberos/gss.rb +7 -0
- data/lib/net/ssh/kerberos/gss/api.rb +4 -0
- data/lib/net/ssh/kerberos/gss/context.rb +7 -0
- data/lib/net/ssh/kerberos/sspi.rb +3 -52
- data/lib/net/ssh/kerberos/sspi/api.rb +38 -92
- data/lib/net/ssh/kerberos/sspi/context.rb +87 -0
- data/test/net_ssh_kerberos_test.rb +3 -3
- data/test/sspi_context_test.rb +27 -0
- data/test/sspi_test.rb +70 -0
- data/test/test_helper.rb +1 -1
- metadata +9 -1
data/README.rdoc
CHANGED
data/VERSION.yml
CHANGED
@@ -10,13 +10,15 @@ module Net
|
|
10
10
|
class GssapiWithMic < Abstract
|
11
11
|
include Net::SSH::Kerberos::Constants
|
12
12
|
|
13
|
-
# OID 1.2.840.113554.1.2.2
|
14
|
-
SUPPORTED_OID =
|
15
|
-
|
13
|
+
# OID 1.2.840.113554.1.2.2 - Kerberos 5 (RFC 1964)
|
14
|
+
SUPPORTED_OID = "\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"
|
15
|
+
#[ 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x1, 0x2, 0x2 ].pack("C*")
|
16
16
|
|
17
17
|
# Attempts to perform gssapi-with-mic Kerberos authentication
|
18
18
|
def authenticate(next_service, username, password=nil)
|
19
|
-
|
19
|
+
gss_klass = (defined?(Net::SSH::Kerberos::SSPI::Context) ?
|
20
|
+
Net::SSH::Kerberos::SSPI::Context : Net::SSH::Kerberos::GSS::Context)
|
21
|
+
gss = nil
|
20
22
|
|
21
23
|
# Try to start gssapi-with-mic authentication.
|
22
24
|
debug { "trying kerberos authentication" }
|
@@ -43,14 +45,14 @@ module Net
|
|
43
45
|
end
|
44
46
|
|
45
47
|
# Try to complete the handshake.
|
46
|
-
|
47
|
-
|
48
|
+
gss = gss_klass.new
|
49
|
+
gss.create username, hostname
|
48
50
|
debug { "gssapi-with-mic handshaking" }
|
49
|
-
until
|
50
|
-
token =
|
51
|
+
until gss.established?
|
52
|
+
token = gss.init(token)
|
51
53
|
if token && token.length > 0
|
52
54
|
send_message Net::SSH::Buffer.from(:byte, USERAUTH_GSSAPI_TOKEN, :string, token)
|
53
|
-
unless
|
55
|
+
unless gss.established?
|
54
56
|
message = session.next_message
|
55
57
|
case message.type
|
56
58
|
when USERAUTH_GSSAPI_ERROR
|
@@ -72,7 +74,7 @@ module Net
|
|
72
74
|
|
73
75
|
# Attempt the actual authentication.
|
74
76
|
debug { "gssapi-with-mic authenticating" }
|
75
|
-
mic =
|
77
|
+
mic = gss.get_mic Net::SSH::Buffer.from(:string, session_id, :byte, USERAUTH_REQUEST, :string, username,
|
76
78
|
:string, next_service, :string, "gssapi-with-mic").to_s
|
77
79
|
if mic.nil?
|
78
80
|
info { "gssapi-with-mic failed (context#get_mic)" }
|
@@ -91,7 +93,7 @@ module Net
|
|
91
93
|
raise Net::SSH::Exception, "unexpected server response to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
|
92
94
|
end
|
93
95
|
ensure
|
94
|
-
|
96
|
+
gss and gss.dispose
|
95
97
|
end
|
96
98
|
|
97
99
|
private
|
data/lib/net/ssh/kerberos.rb
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
require 'net/ssh'
|
2
2
|
require 'net/ssh/kerberos/constants'
|
3
3
|
#require 'net/ssh/kerberos/kex'
|
4
|
-
|
4
|
+
if RUBY_PLATFORM.include?('win') && ! RUBY_PLATFORM.include?('dar'); then
|
5
|
+
begin
|
6
|
+
require 'net/ssh/kerberos/sspi'
|
7
|
+
rescue Exception => e
|
8
|
+
if RuntimeError === e and e.message =~ /^LoadLibrary: ([^\s]+)/
|
9
|
+
$stderr.puts "error: While loading Kerberos SSPI: failed to load library: #{$1}"
|
10
|
+
else
|
11
|
+
raise e
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
require 'net/ssh/kerberos/gss' unless defined?(Net::SSH::Kerberos::SSPI::Context)
|
5
16
|
require 'net/ssh/authentication/methods/gssapi_with_mic'
|
6
17
|
|
7
18
|
module Net
|
@@ -1,54 +1,5 @@
|
|
1
1
|
require 'net/ssh/kerberos/sspi/api'
|
2
|
+
require 'net/ssh/kerberos/sspi/context'
|
2
3
|
|
3
|
-
module Net; module SSH; module Kerberos
|
4
|
-
|
5
|
-
|
6
|
-
class State
|
7
|
-
attr_accessor :name, :realm, :valid
|
8
|
-
alias :valid? :valid
|
9
|
-
end
|
10
|
-
|
11
|
-
# Acquires credentials for SSPI (GSSAPI) authentication, and determines
|
12
|
-
# the credential's username and realm.
|
13
|
-
def sspi_acquire_credentials(state)
|
14
|
-
#SecPkgCredentials_Names names
|
15
|
-
#char *delimiter, *cp
|
16
|
-
|
17
|
-
state.valid? and return true
|
18
|
-
|
19
|
-
#sspi->from_server_token.BufferType = SECBUFFER_TOKEN | SECBUFFER_READONLY;
|
20
|
-
|
21
|
-
# Acquire credentials
|
22
|
-
sspi_acquire_credentials_handle
|
23
|
-
names = sspi_query_credentials_names
|
24
|
-
state.name, state.realm = *names.user_name.split('@')
|
25
|
-
|
26
|
-
#debug((" FreeContextBuffer(%x)\n", names.sUserName));
|
27
|
-
#result = SSPIResult.new(API::FreeContextBuffer(names.user.to_p))
|
28
|
-
sspi_free_context_buffer names
|
29
|
-
sspi_free_credentials_handle
|
30
|
-
|
31
|
-
# Sometimes, Microsoft SSPI returns a UPN of the form "user@REALM@",
|
32
|
-
# (Seen under WinXP pro after ksetup to a MIT realm). Deal with that.
|
33
|
-
realm.chop if realm[-1] == '@'
|
34
|
-
|
35
|
-
# Initialise the request flags.
|
36
|
-
#sspi->request_flags = ISC_REQ_MUTUAL_AUTH |
|
37
|
-
# ISC_REQ_INTEGRITY |
|
38
|
-
# ISC_REQ_CONFIDENTIALITY |
|
39
|
-
# ISC_REQ_ALLOCATE_MEMORY;
|
40
|
-
#if (ssh->cfg.sspi_fwd_ticket)
|
41
|
-
# sspi->request_flags |= ISC_REQ_DELEGATE;
|
42
|
-
|
43
|
-
if ! sspi_construct_service_name state
|
44
|
-
state.valid = true
|
45
|
-
#if (!sspi_construct_service_name(ssh, sspi)) {
|
46
|
-
#debug((" FreeCredentialsHandle(%s)\n", HDL(&sspi->credentials)));
|
47
|
-
else
|
48
|
-
sspi_free_credentials_handle
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end; end; end
|
53
|
-
|
54
|
-
|
4
|
+
module Net; module SSH; module Kerberos; module SSPI
|
5
|
+
end; end; end; end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'win32/sspi'
|
2
|
-
require 'dl'
|
2
|
+
require 'dl'
|
3
3
|
|
4
4
|
module Win32; module SSPI
|
5
5
|
|
@@ -77,9 +77,43 @@ module Win32; module SSPI
|
|
77
77
|
CompleteAuthToken = Win32API.new("secur32", "CompleteAuthToken", 'pp', 'L')
|
78
78
|
MakeSignature = Win32API.new("secur32", "MakeSignature", 'pLpL', 'L')
|
79
79
|
FreeContextBuffer = Win32API.new("secur32", "FreeContextBuffer", 'P', 'L')
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def self.method_missing(symbol, *args)
|
84
|
+
return super unless const_defined? symbol and Win32API === (api = const_get(symbol))
|
85
|
+
result = SSPIResult.new api.call(*args)
|
86
|
+
args = (1..(args.length)).inject([]) { |v,n| v << "a#{n}" }.join ', '
|
87
|
+
class_eval "def self.#{symbol}(#{args}); SSPIResult.new #{symbol}.call(#{args}) end"
|
88
|
+
result
|
89
|
+
end
|
80
90
|
end
|
81
91
|
|
82
92
|
SecPkgCredentialsNames = Struct.new(:user_name)
|
93
|
+
|
94
|
+
class SecurityHandle
|
95
|
+
def nil?; @struct.unpack('Q').first.zero? end
|
96
|
+
alias :to_str :to_p
|
97
|
+
end
|
98
|
+
|
99
|
+
class TimeStamp
|
100
|
+
def nil?; @struct.unpack('Q').first.zero? end
|
101
|
+
alias :to_str :to_p
|
102
|
+
end
|
103
|
+
|
104
|
+
class SSPIResult
|
105
|
+
def ok?; (value & 0x80000000).zero? end
|
106
|
+
|
107
|
+
def complete?; value.zero? end
|
108
|
+
|
109
|
+
def incomplete?; SEC_I_COMPLETE_NEEDED==value || SEC_I_COMPLETE_AND_CONTINUE==value end
|
110
|
+
|
111
|
+
def failure?; (value & 0x80000000).nonzero? end
|
112
|
+
|
113
|
+
def temporary_failure?
|
114
|
+
value==SEC_E_LOGON_DENIED || value==SEC_E_NO_AUTHENTICATING_AUTHORITY || value==SEC_E_NO_CREDENTIALS
|
115
|
+
end
|
116
|
+
end
|
83
117
|
|
84
118
|
class SecPkgInfo
|
85
119
|
attr_reader :struct
|
@@ -94,6 +128,7 @@ module Win32; module SSPI
|
|
94
128
|
end
|
95
129
|
|
96
130
|
def to_p; @struct ||= "\0" * 4 end
|
131
|
+
alias :to_str :to_p
|
97
132
|
end
|
98
133
|
|
99
134
|
class SecPkgSizes
|
@@ -109,6 +144,7 @@ module Win32; module SSPI
|
|
109
144
|
end
|
110
145
|
|
111
146
|
def to_p; @struct ||= "\0" * 16 end
|
147
|
+
alias :to_str :to_p
|
112
148
|
end
|
113
149
|
|
114
150
|
# Creates binary representaiton of a SecBufferDesc structure,
|
@@ -167,6 +203,7 @@ module Win32; module SSPI
|
|
167
203
|
end.pack("LLP" * @bufferTokens.size)
|
168
204
|
@struct ||= [SECBUFFER_VERSION, @bufferTokens.size, @sec_buffers].pack("LLP")
|
169
205
|
end
|
206
|
+
alias :to_str :to_p
|
170
207
|
|
171
208
|
private
|
172
209
|
|
@@ -189,94 +226,3 @@ module Win32; module SSPI
|
|
189
226
|
end
|
190
227
|
|
191
228
|
end; end
|
192
|
-
|
193
|
-
module Net; module SSH; module Kerberos; module SSPI; class GSSContext
|
194
|
-
|
195
|
-
class GeneralError < StandardError; end
|
196
|
-
|
197
|
-
include Win32::SSPI
|
198
|
-
|
199
|
-
def create(user, host)
|
200
|
-
dispose if @credentials or @handle
|
201
|
-
@credentials = CredHandle.new
|
202
|
-
ts=TimeStamp.new
|
203
|
-
|
204
|
-
result = SSPIResult.new(API::AcquireCredentialsHandle.call(
|
205
|
-
nil, "Kerberos", SECPKG_CRED_OUTBOUND, nil, nil,
|
206
|
-
nil, nil, @credentials.to_p, ts.to_p
|
207
|
-
))
|
208
|
-
unless result.ok?
|
209
|
-
@credentials = nil
|
210
|
-
raise GeneralError, "Error acquiring credentials: #{result}"
|
211
|
-
end
|
212
|
-
|
213
|
-
buff = "\0\0\0\0"
|
214
|
-
result = SSPIResult.new(API::QueryCredentialsAttributes.call(@credentials.to_p, SECPKG_CRED_ATTR_NAMES, buff))
|
215
|
-
if result.ok?
|
216
|
-
names = buff.to_ptr.ptr
|
217
|
-
begin
|
218
|
-
@cred_name = names.to_s.sub /^.*\\/, ''
|
219
|
-
@cred_krb_name = @cred_name.gsub '@', '/';
|
220
|
-
@server_name = Socket.gethostbyname(host)[0]
|
221
|
-
@server_krb_name = "host/" + @server_name
|
222
|
-
ensure
|
223
|
-
API::FreeContextBuffer.call(names)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
cred_names = SecPkgCredentialsNames.new(names)
|
227
|
-
end
|
228
|
-
|
229
|
-
def init(token=nil)
|
230
|
-
ctx = CtxtHandle.new
|
231
|
-
ts = TimeStamp.new
|
232
|
-
prev = @state[:handle].to_p if @state and @state[:handle]
|
233
|
-
req = ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH | ISC_REQ_INTEGRITY
|
234
|
-
output = SecurityBuffer.new
|
235
|
-
input = SecurityBuffer.new(token) if token
|
236
|
-
ctxAttr = "\0" * 4
|
237
|
-
result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, prev, @server_krb_name,
|
238
|
-
req, 0, SECURITY_NATIVE_DREP, input ? input.to_p : nil,
|
239
|
-
0, ctx.to_p, output.to_p, ctxAttr, ts.to_p))
|
240
|
-
if SEC_I_COMPLETE_NEEDED == result || SEC_I_COMPLETE_AND_CONTINUE == result
|
241
|
-
result = SSPIResult.new(API::CompleteAuthToken.call(ctx.to_p, output.to_p))
|
242
|
-
end
|
243
|
-
unless result.ok?
|
244
|
-
input.token
|
245
|
-
raise GeneralError, "Error initializing security context: #{result} #{input.inspect}"
|
246
|
-
end
|
247
|
-
@state = { :handle => ctx, :result => result, :token => output.token, :stamp => ts }
|
248
|
-
if result.value == 0
|
249
|
-
@sizes = SecPkgSizes.new
|
250
|
-
result = SSPIResult.new(API::QueryContextAttributes.call(ctx.to_p, SECPKG_ATTR_SIZES, @sizes.to_p))
|
251
|
-
@handle = @state[:handle]
|
252
|
-
end
|
253
|
-
@state[:token]
|
254
|
-
end
|
255
|
-
|
256
|
-
def established?
|
257
|
-
@handle && (@handle.upper.nonzero? || @handle.lower.nonzero?) && (@state.nil? || @state[:result].value.zero?)
|
258
|
-
end
|
259
|
-
|
260
|
-
def get_mic(token=nil)
|
261
|
-
buffers = SecurityBuffer.new 2
|
262
|
-
buffers.set_buffer 0, SECBUFFER_DATA, token
|
263
|
-
buffers.set_buffer 1, SECBUFFER_TOKEN, nil, @sizes.max_signature
|
264
|
-
@state[:result] = SSPIResult.new(API::MakeSignature.call(@handle.to_p, 0, buffers.to_p, 0))
|
265
|
-
unless @state[:result].ok?
|
266
|
-
raise GeneralError, "Error creating the signature: #{result}"
|
267
|
-
end
|
268
|
-
return buffers.token(1).dup
|
269
|
-
end
|
270
|
-
|
271
|
-
def dispose()
|
272
|
-
if @credentials
|
273
|
-
API::FreeCredentialsHandle.call(@credentials.to_p)
|
274
|
-
@credentials = nil
|
275
|
-
end
|
276
|
-
if @handle
|
277
|
-
API::DeleteSecurityContext.call(@handle.to_p)
|
278
|
-
@handle = nil
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
end; end; end; end; end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'net/ssh/kerberos/sspi/api'
|
2
|
+
|
3
|
+
module Net; module SSH; module Kerberos; module SSPI; class Context
|
4
|
+
|
5
|
+
class GeneralError < StandardError; end
|
6
|
+
|
7
|
+
include Win32::SSPI
|
8
|
+
|
9
|
+
attr_reader :cred_name, :cred_krb_name, :server_name, :server_krb_name
|
10
|
+
|
11
|
+
def create(user, host)
|
12
|
+
dispose if @credentials or @handle
|
13
|
+
creds = CredHandle.new
|
14
|
+
ts = TimeStamp.new
|
15
|
+
|
16
|
+
result = API::AcquireCredentialsHandle nil, "Kerberos", SECPKG_CRED_OUTBOUND, nil, nil, nil, nil, creds, ts
|
17
|
+
result.ok? or raise GeneralError, "Error acquiring credentials: #{result}"
|
18
|
+
|
19
|
+
buff = "\0\0\0\0"
|
20
|
+
result = API::QueryCredentialsAttributes creds, SECPKG_CRED_ATTR_NAMES, buff
|
21
|
+
if result.ok?
|
22
|
+
names = buff.to_ptr.ptr
|
23
|
+
begin
|
24
|
+
@cred_name = names.to_s.sub(/^[^\\\/]*[\\\/]/, '')
|
25
|
+
@cred_krb_name = @cred_name.gsub('@', '/');
|
26
|
+
@server_name = Socket.gethostbyname(host)[0]
|
27
|
+
@server_krb_name = "host/" + @server_name
|
28
|
+
|
29
|
+
z = (user.include?('@') ? user.gsub('@','/') : user+'/')
|
30
|
+
unless z.downcase == @cred_krb_name[0,z.length].downcase
|
31
|
+
raise GeneralError, "Credentials mismatch: current is #{@cred_name}, requested is #{user}"
|
32
|
+
end
|
33
|
+
@credentials = creds
|
34
|
+
ensure
|
35
|
+
@credentials or API::FreeCredentialsHandle creds
|
36
|
+
API::FreeContextBuffer names
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def credentials?; ! @credentials.nil? end
|
42
|
+
|
43
|
+
def init(token=nil)
|
44
|
+
ctx = CtxtHandle.new
|
45
|
+
ts = TimeStamp.new
|
46
|
+
prev = @state[:handle] if @state
|
47
|
+
req = ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH | ISC_REQ_INTEGRITY
|
48
|
+
output = SecurityBuffer.new
|
49
|
+
input = SecurityBuffer.new(token) if token
|
50
|
+
ctxAttr = "\0" * 4
|
51
|
+
result = API::InitializeSecurityContext @credentials, prev, @server_krb_name, req, 0,
|
52
|
+
SECURITY_NATIVE_DREP, input, 0, ctx, output, ctxAttr, ts
|
53
|
+
result = API::CompleteAuthToken ctx, output if result.incomplete?
|
54
|
+
if result.failure?
|
55
|
+
input.token and raise GeneralError, "Error initializing security context: #{result} #{input.inspect}"
|
56
|
+
end
|
57
|
+
@state = { :handle => ctx, :result => result, :token => output.token, :stamp => ts }
|
58
|
+
if result.complete?
|
59
|
+
result = API::QueryContextAttributes ctx, SECPKG_ATTR_SIZES, @sizes=SecPkgSizes.new
|
60
|
+
@handle = @state[:handle]
|
61
|
+
end
|
62
|
+
@state[:token]
|
63
|
+
end
|
64
|
+
|
65
|
+
def established?
|
66
|
+
! @handle.nil? && (@state.nil? || @state[:result].value.zero?)
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_mic(token=nil)
|
70
|
+
buffers = SecurityBuffer.new 2
|
71
|
+
buffers.set_buffer 0, SECBUFFER_DATA, token
|
72
|
+
buffers.set_buffer 1, SECBUFFER_TOKEN, nil, @sizes.max_signature
|
73
|
+
@state[:result] = API::MakeSignature @handle, 0, buffers, 0
|
74
|
+
unless @state[:result].ok?
|
75
|
+
raise GeneralError, "Error creating the signature: #{result}"
|
76
|
+
end
|
77
|
+
return buffers.token(1).dup
|
78
|
+
end
|
79
|
+
|
80
|
+
def dispose()
|
81
|
+
@credentials and API::FreeCredentialsHandle @credentials
|
82
|
+
@handle and API::DeleteSecurityContext @handle
|
83
|
+
ensure
|
84
|
+
@credentials = @handle = nil
|
85
|
+
end
|
86
|
+
|
87
|
+
end; end; end; end; end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'test_helper'
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
2
|
|
3
3
|
class NetSshKerberosTest < Test::Unit::TestCase
|
4
|
-
def
|
5
|
-
flunk "
|
4
|
+
def test_net_ssh_integration
|
5
|
+
flunk "write some unit tests for Net::SSH integration"
|
6
6
|
end
|
7
7
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
+
|
3
|
+
include Win32::SSPI
|
4
|
+
|
5
|
+
class SspiContextTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
if defined? Net::SSH::Kerberos::SSPI::Context
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@gss = Net::SSH::Kerberos::SSPI::Context.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@gss.dispose
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_create
|
18
|
+
@gss.create ENV['USER'], Socket.gethostbyname('localhost')[0]
|
19
|
+
assert @gss.credentials?, "Should have acquired credentials"
|
20
|
+
end
|
21
|
+
|
22
|
+
else
|
23
|
+
$stderr.puts "Skipping SSPI tests on this platform: Windows SSPI was not loaded."
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
data/test/sspi_test.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
+
|
3
|
+
include Win32::SSPI
|
4
|
+
|
5
|
+
class SspiTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
if defined? Net::SSH::Kerberos::SSPI::Context
|
8
|
+
|
9
|
+
def test_query_security_package_info
|
10
|
+
pkg_info = SecPkgInfo.new
|
11
|
+
result = API::QuerySecurityPackageInfo "Kerberos", pkg_info
|
12
|
+
assert result.ok?, "QuerySecurityPackageInfo failed: #{result}"
|
13
|
+
assert_equal pkg_info.name, "Kerberos"
|
14
|
+
assert pkg_info.max_token >= 128, "The maximum token size is assumed to be greater than 128 bytes"
|
15
|
+
assert pkg_info.max_token <= 12288, "The maximum token size is assumed to be less than 12288 bytes"
|
16
|
+
result = API::FreeContextBuffer pkg_info
|
17
|
+
assert result.ok?, "FreeContextBuffer failed: #{result}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_security_context_initialization
|
21
|
+
creds = SecurityHandle.new
|
22
|
+
ts = TimeStamp.new
|
23
|
+
result = API::AcquireCredentialsHandle nil, "Kerberos", SECPKG_CRED_OUTBOUND, nil, nil, nil, nil, creds, ts
|
24
|
+
unless result.temporary_failure?
|
25
|
+
assert result.ok?, "AcquireCredentialsHandle failed: #{result}"
|
26
|
+
assert ! creds.nil?, "Should acquire a credentials handle"
|
27
|
+
begin
|
28
|
+
buff = "\0\0\0\0"
|
29
|
+
result = API::QueryCredentialsAttributes creds, SECPKG_CRED_ATTR_NAMES, buff
|
30
|
+
assert result.ok?, "QueryCredentialsAttributes failed: #{result}"
|
31
|
+
names = buff.to_ptr.ptr
|
32
|
+
assert ! names.nil?, "Should return the user name."
|
33
|
+
begin
|
34
|
+
ts = TimeStamp.new
|
35
|
+
output = SecurityBuffer.new
|
36
|
+
ctx = CtxtHandle.new
|
37
|
+
ctxAttr = "\0" * 4
|
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
|
41
|
+
unless result.temporary_failure?
|
42
|
+
assert result.ok?, "InitializeSecurityContext failed: #{result}"
|
43
|
+
begin
|
44
|
+
assert ! ctx.nil?, "Should initialize a context handle"
|
45
|
+
assert ! output.token.nil?, "Should output a token into the buffer"
|
46
|
+
assert output.bufferSize.nonzero?, "Should output a token into the buffer"
|
47
|
+
ensure
|
48
|
+
result = API::DeleteSecurityContext ctx
|
49
|
+
ctx = nil if result.ok?
|
50
|
+
end
|
51
|
+
assert ctx.nil?, "DeleteSecurityContext failed: #{result}"
|
52
|
+
end
|
53
|
+
ensure
|
54
|
+
result = API::FreeContextBuffer names
|
55
|
+
names = nil if result.ok?
|
56
|
+
end
|
57
|
+
assert names.nil?, "FreeContextBuffer failed: #{result}"
|
58
|
+
ensure
|
59
|
+
result = API::FreeCredentialsHandle creds
|
60
|
+
creds = nil if result.ok?
|
61
|
+
end
|
62
|
+
assert creds.nil?, "FreeCredentialsHandle failed: #{result}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
else
|
66
|
+
$stderr.puts "Skipping SSPI tests on this platform: Windows SSPI was not loaded."
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ssh-kerberos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Khoobyar
|
@@ -51,12 +51,18 @@ files:
|
|
51
51
|
- lib/net/ssh/authentication/methods/gssapi_with_mic.rb
|
52
52
|
- lib/net/ssh/kerberos.rb
|
53
53
|
- lib/net/ssh/kerberos/constants.rb
|
54
|
+
- lib/net/ssh/kerberos/gss.rb
|
55
|
+
- lib/net/ssh/kerberos/gss/api.rb
|
56
|
+
- lib/net/ssh/kerberos/gss/context.rb
|
54
57
|
- lib/net/ssh/kerberos/kex.rb
|
55
58
|
- lib/net/ssh/kerberos/kex/krb5_diffie_hellman_group1_sha1.rb
|
56
59
|
- lib/net/ssh/kerberos/kex/krb5_diffie_hellman_group_exchange_sha1.rb
|
57
60
|
- lib/net/ssh/kerberos/sspi.rb
|
58
61
|
- lib/net/ssh/kerberos/sspi/api.rb
|
62
|
+
- lib/net/ssh/kerberos/sspi/context.rb
|
59
63
|
- test/net_ssh_kerberos_test.rb
|
64
|
+
- test/sspi_context_test.rb
|
65
|
+
- test/sspi_test.rb
|
60
66
|
- test/test_helper.rb
|
61
67
|
has_rdoc: true
|
62
68
|
homepage: http://github.com/joekhoobyar/net-ssh-kerberos
|
@@ -88,4 +94,6 @@ specification_version: 3
|
|
88
94
|
summary: Add Kerberos support to Net::SSH
|
89
95
|
test_files:
|
90
96
|
- test/net_ssh_kerberos_test.rb
|
97
|
+
- test/sspi_context_test.rb
|
98
|
+
- test/sspi_test.rb
|
91
99
|
- test/test_helper.rb
|