net-ssh-kerberos 0.1.0 → 0.1.2

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.
@@ -1,6 +1,10 @@
1
1
  = net-ssh-kerberos
2
2
 
3
- Adds Kerberos support to Net::SSH
3
+ Adds Kerberos support to Net::SSH.
4
+
5
+ Windows support uses Microsoft SSPI for Kerberos integration.
6
+
7
+ Kerberos support for UNIX and OS X coming soon.
4
8
 
5
9
  == Copyright
6
10
 
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 1
4
- :patch: 0
4
+ :patch: 2
@@ -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 = #"\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*")
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
- sspi = nil
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
- sspi = Net::SSH::Kerberos::SSPI::GSSContext.new
47
- sspi.create username, hostname
48
+ gss = gss_klass.new
49
+ gss.create username, hostname
48
50
  debug { "gssapi-with-mic handshaking" }
49
- until sspi.established?
50
- token = sspi.init(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 sspi.established?
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 = sspi.get_mic Net::SSH::Buffer.from(:string, session_id, :byte, USERAUTH_REQUEST, :string, username,
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
- sspi and sspi.dispose
96
+ gss and gss.dispose
95
97
  end
96
98
 
97
99
  private
@@ -1,7 +1,18 @@
1
1
  require 'net/ssh'
2
2
  require 'net/ssh/kerberos/constants'
3
3
  #require 'net/ssh/kerberos/kex'
4
- require 'net/ssh/kerberos/sspi'
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
@@ -0,0 +1,7 @@
1
+ $stderr.puts "warning: Kerberos support for non-Windows systems is not yet implemented."
2
+
3
+ require 'net/ssh/kerberos/gss/api'
4
+ require 'net/ssh/kerberos/gss/context'
5
+
6
+ module Net; module SSH; module Kerberos; module GSS
7
+ end; end; end; end
@@ -0,0 +1,4 @@
1
+
2
+ module Net; module SSH; module Kerberos; module GSS; class API
3
+
4
+ end; end; end; end; end
@@ -0,0 +1,7 @@
1
+ require 'net/ssh/kerberos/gss/api'
2
+
3
+ module Net; module SSH; module Kerberos; module GSS; class Context
4
+
5
+ class GeneralError < StandardError; end
6
+
7
+ end; end; end; end; end
@@ -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
- module SSPI
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 test_something_for_real
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
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
+
@@ -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
+
@@ -3,7 +3,7 @@ require 'test/unit'
3
3
 
4
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
5
5
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- require 'net_ssh_kerberos'
6
+ require 'net/ssh/kerberos'
7
7
 
8
8
  class Test::Unit::TestCase
9
9
  end
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.0
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