ddollar-net-ssh 2.0.1

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.
Files changed (103) hide show
  1. data/CHANGELOG.rdoc +42 -0
  2. data/Manifest +101 -0
  3. data/README.rdoc +110 -0
  4. data/Rakefile +26 -0
  5. data/THANKS.rdoc +16 -0
  6. data/lib/net/ssh.rb +199 -0
  7. data/lib/net/ssh/authentication/agent.rb +175 -0
  8. data/lib/net/ssh/authentication/constants.rb +18 -0
  9. data/lib/net/ssh/authentication/key_manager.rb +169 -0
  10. data/lib/net/ssh/authentication/methods/abstract.rb +60 -0
  11. data/lib/net/ssh/authentication/methods/hostbased.rb +71 -0
  12. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +66 -0
  13. data/lib/net/ssh/authentication/methods/password.rb +39 -0
  14. data/lib/net/ssh/authentication/methods/publickey.rb +92 -0
  15. data/lib/net/ssh/authentication/pageant.rb +176 -0
  16. data/lib/net/ssh/authentication/session.rb +127 -0
  17. data/lib/net/ssh/buffer.rb +339 -0
  18. data/lib/net/ssh/buffered_io.rb +149 -0
  19. data/lib/net/ssh/config.rb +173 -0
  20. data/lib/net/ssh/connection/channel.rb +625 -0
  21. data/lib/net/ssh/connection/constants.rb +33 -0
  22. data/lib/net/ssh/connection/session.rb +569 -0
  23. data/lib/net/ssh/connection/term.rb +178 -0
  24. data/lib/net/ssh/errors.rb +85 -0
  25. data/lib/net/ssh/key_factory.rb +85 -0
  26. data/lib/net/ssh/known_hosts.rb +129 -0
  27. data/lib/net/ssh/loggable.rb +61 -0
  28. data/lib/net/ssh/packet.rb +102 -0
  29. data/lib/net/ssh/prompt.rb +93 -0
  30. data/lib/net/ssh/proxy/errors.rb +14 -0
  31. data/lib/net/ssh/proxy/http.rb +94 -0
  32. data/lib/net/ssh/proxy/socks4.rb +70 -0
  33. data/lib/net/ssh/proxy/socks5.rb +128 -0
  34. data/lib/net/ssh/service/forward.rb +267 -0
  35. data/lib/net/ssh/test.rb +89 -0
  36. data/lib/net/ssh/test/channel.rb +129 -0
  37. data/lib/net/ssh/test/extensions.rb +152 -0
  38. data/lib/net/ssh/test/kex.rb +44 -0
  39. data/lib/net/ssh/test/local_packet.rb +51 -0
  40. data/lib/net/ssh/test/packet.rb +81 -0
  41. data/lib/net/ssh/test/remote_packet.rb +38 -0
  42. data/lib/net/ssh/test/script.rb +157 -0
  43. data/lib/net/ssh/test/socket.rb +59 -0
  44. data/lib/net/ssh/transport/algorithms.rb +384 -0
  45. data/lib/net/ssh/transport/cipher_factory.rb +72 -0
  46. data/lib/net/ssh/transport/constants.rb +30 -0
  47. data/lib/net/ssh/transport/hmac.rb +31 -0
  48. data/lib/net/ssh/transport/hmac/abstract.rb +48 -0
  49. data/lib/net/ssh/transport/hmac/md5.rb +12 -0
  50. data/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  51. data/lib/net/ssh/transport/hmac/none.rb +15 -0
  52. data/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  53. data/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  54. data/lib/net/ssh/transport/identity_cipher.rb +40 -0
  55. data/lib/net/ssh/transport/kex.rb +13 -0
  56. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +208 -0
  57. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +77 -0
  58. data/lib/net/ssh/transport/openssl.rb +128 -0
  59. data/lib/net/ssh/transport/packet_stream.rb +230 -0
  60. data/lib/net/ssh/transport/server_version.rb +61 -0
  61. data/lib/net/ssh/transport/session.rb +262 -0
  62. data/lib/net/ssh/transport/state.rb +170 -0
  63. data/lib/net/ssh/verifiers/lenient.rb +30 -0
  64. data/lib/net/ssh/verifiers/null.rb +12 -0
  65. data/lib/net/ssh/verifiers/strict.rb +53 -0
  66. data/lib/net/ssh/version.rb +60 -0
  67. data/net-ssh.gemspec +56 -0
  68. data/setup.rb +1585 -0
  69. data/test/authentication/methods/common.rb +28 -0
  70. data/test/authentication/methods/test_abstract.rb +51 -0
  71. data/test/authentication/methods/test_hostbased.rb +108 -0
  72. data/test/authentication/methods/test_keyboard_interactive.rb +98 -0
  73. data/test/authentication/methods/test_password.rb +50 -0
  74. data/test/authentication/methods/test_publickey.rb +123 -0
  75. data/test/authentication/test_agent.rb +205 -0
  76. data/test/authentication/test_key_manager.rb +100 -0
  77. data/test/authentication/test_session.rb +93 -0
  78. data/test/common.rb +106 -0
  79. data/test/configs/exact_match +8 -0
  80. data/test/configs/wild_cards +14 -0
  81. data/test/connection/test_channel.rb +452 -0
  82. data/test/connection/test_session.rb +483 -0
  83. data/test/test_all.rb +6 -0
  84. data/test/test_buffer.rb +336 -0
  85. data/test/test_buffered_io.rb +63 -0
  86. data/test/test_config.rb +78 -0
  87. data/test/test_key_factory.rb +67 -0
  88. data/test/transport/hmac/test_md5.rb +34 -0
  89. data/test/transport/hmac/test_md5_96.rb +25 -0
  90. data/test/transport/hmac/test_none.rb +34 -0
  91. data/test/transport/hmac/test_sha1.rb +34 -0
  92. data/test/transport/hmac/test_sha1_96.rb +25 -0
  93. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  94. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  95. data/test/transport/test_algorithms.rb +302 -0
  96. data/test/transport/test_cipher_factory.rb +163 -0
  97. data/test/transport/test_hmac.rb +34 -0
  98. data/test/transport/test_identity_cipher.rb +40 -0
  99. data/test/transport/test_packet_stream.rb +433 -0
  100. data/test/transport/test_server_version.rb +55 -0
  101. data/test/transport/test_session.rb +312 -0
  102. data/test/transport/test_state.rb +173 -0
  103. metadata +222 -0
@@ -0,0 +1,28 @@
1
+ module Authentication; module Methods
2
+
3
+ module Common
4
+ include Net::SSH::Authentication::Constants
5
+
6
+ private
7
+
8
+ def socket(options={})
9
+ @socket ||= stub("socket", :client_name => "me.ssh.test")
10
+ end
11
+
12
+ def transport(options={})
13
+ @transport ||= MockTransport.new(options.merge(:socket => socket))
14
+ end
15
+
16
+ def session(options={})
17
+ @session ||= begin
18
+ sess = stub("auth-session", :logger => nil, :transport => transport(options))
19
+ def sess.next_message
20
+ transport.next_message
21
+ end
22
+ sess
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end; end
@@ -0,0 +1,51 @@
1
+ require 'common'
2
+ require 'authentication/methods/common'
3
+ require 'net/ssh/authentication/methods/abstract'
4
+
5
+ module Authentication; module Methods
6
+
7
+ class TestAbstract < Test::Unit::TestCase
8
+ include Common
9
+
10
+ def test_constructor_should_set_defaults
11
+ assert_nil subject.key_manager
12
+ end
13
+
14
+ def test_constructor_should_honor_options
15
+ assert_equal :manager, subject(:key_manager => :manager).key_manager
16
+ end
17
+
18
+ def test_session_id_should_query_session_id_from_key_exchange
19
+ transport.stubs(:algorithms).returns(stub("algorithms", :session_id => "abcxyz123"))
20
+ assert_equal "abcxyz123", subject.session_id
21
+ end
22
+
23
+ def test_send_message_should_delegate_to_transport
24
+ transport.expects(:send_message).with("abcxyz123")
25
+ subject.send_message("abcxyz123")
26
+ end
27
+
28
+ def test_userauth_request_should_build_well_formed_userauth_packet
29
+ packet = subject.userauth_request("jamis", "ssh-connection", "password")
30
+ assert_equal "\062\0\0\0\005jamis\0\0\0\016ssh-connection\0\0\0\010password", packet.to_s
31
+ end
32
+
33
+ def test_userauth_request_should_translate_extra_booleans_onto_end
34
+ packet = subject.userauth_request("jamis", "ssh-connection", "password", true, false)
35
+ assert_equal "\062\0\0\0\005jamis\0\0\0\016ssh-connection\0\0\0\010password\1\0", packet.to_s
36
+ end
37
+
38
+ def test_userauth_request_should_translate_extra_strings_onto_end
39
+ packet = subject.userauth_request("jamis", "ssh-connection", "password", "foo", "bar")
40
+ assert_equal "\062\0\0\0\005jamis\0\0\0\016ssh-connection\0\0\0\010password\0\0\0\3foo\0\0\0\3bar", packet.to_s
41
+ end
42
+
43
+ private
44
+
45
+ def subject(options={})
46
+ @subject ||= Net::SSH::Authentication::Methods::Abstract.new(session(options), options)
47
+ end
48
+
49
+ end
50
+
51
+ end; end
@@ -0,0 +1,108 @@
1
+ require 'common'
2
+ require 'net/ssh/authentication/methods/hostbased'
3
+ require 'authentication/methods/common'
4
+
5
+ module Authentication; module Methods
6
+
7
+ class TestHostbased < Test::Unit::TestCase
8
+ include Common
9
+
10
+ def test_authenticate_should_return_false_when_no_key_manager_has_been_set
11
+ assert_equal false, subject(:key_manager => nil).authenticate("ssh-connection", "jamis")
12
+ end
13
+
14
+ def test_authenticate_should_return_false_when_key_manager_has_no_keys
15
+ assert_equal false, subject(:keys => []).authenticate("ssh-connection", "jamis")
16
+ end
17
+
18
+ def test_authenticate_should_return_false_if_no_keys_can_authenticate
19
+ key_manager.expects(:sign).with(&signature_parameters(keys.first)).returns("sig-one")
20
+ key_manager.expects(:sign).with(&signature_parameters(keys.last)).returns("sig-two")
21
+
22
+ transport.expect do |t, packet|
23
+ assert_equal USERAUTH_REQUEST, packet.type
24
+ assert verify_userauth_request_packet(packet, keys.first)
25
+ assert_equal "sig-one", packet.read_string
26
+ t.return(USERAUTH_FAILURE, :string, "hostbased,password")
27
+
28
+ t.expect do |t, packet|
29
+ assert_equal USERAUTH_REQUEST, packet.type
30
+ assert verify_userauth_request_packet(packet, keys.last)
31
+ assert_equal "sig-two", packet.read_string
32
+ t.return(USERAUTH_FAILURE, :string, "hostbased,password")
33
+ end
34
+ end
35
+
36
+ assert_equal false, subject.authenticate("ssh-connection", "jamis")
37
+ end
38
+
39
+ def test_authenticate_should_return_true_if_any_key_can_authenticate
40
+ key_manager.expects(:sign).with(&signature_parameters(keys.first)).returns("sig-one")
41
+
42
+ transport.expect do |t, packet|
43
+ assert_equal USERAUTH_REQUEST, packet.type
44
+ assert verify_userauth_request_packet(packet, keys.first)
45
+ assert_equal "sig-one", packet.read_string
46
+ t.return(USERAUTH_SUCCESS)
47
+ end
48
+
49
+ assert subject.authenticate("ssh-connection", "jamis")
50
+ end
51
+
52
+ private
53
+
54
+ def signature_parameters(key)
55
+ Proc.new do |given_key, data|
56
+ next false unless given_key.to_blob == key.to_blob
57
+ buffer = Net::SSH::Buffer.new(data)
58
+ buffer.read_string == "abcxyz123" && # session-id
59
+ buffer.read_byte == USERAUTH_REQUEST && # type
60
+ verify_userauth_request_packet(buffer, key)
61
+ end
62
+ end
63
+
64
+ def verify_userauth_request_packet(packet, key)
65
+ packet.read_string == "jamis" && # user-name
66
+ packet.read_string == "ssh-connection" && # next service
67
+ packet.read_string == "hostbased" && # auth-method
68
+ packet.read_string == key.ssh_type && # key type
69
+ packet.read_buffer.read_key.to_blob == key.to_blob && # key
70
+ packet.read_string == "me.ssh.test." && # client hostname
71
+ packet.read_string == "jamis" # client username
72
+ end
73
+
74
+ @@keys = nil
75
+ def keys
76
+ @@keys ||= [OpenSSL::PKey::RSA.new(32), OpenSSL::PKey::DSA.new(32)]
77
+ end
78
+
79
+ def key_manager(options={})
80
+ @key_manager ||= stub("key_manager", :identities => options[:keys] || keys)
81
+ end
82
+
83
+ def subject(options={})
84
+ options[:key_manager] = key_manager(options) unless options.key?(:key_manager)
85
+ @subject ||= Net::SSH::Authentication::Methods::Hostbased.new(session(options), options)
86
+ end
87
+
88
+ def socket(options={})
89
+ @socket ||= stub("socket", :client_name => "me.ssh.test")
90
+ end
91
+
92
+ def transport(options={})
93
+ @transport ||= MockTransport.new(options.merge(:socket => socket))
94
+ end
95
+
96
+ def session(options={})
97
+ @session ||= begin
98
+ sess = stub("auth-session", :logger => nil, :transport => transport(options))
99
+ def sess.next_message
100
+ transport.next_message
101
+ end
102
+ sess
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ end; end
@@ -0,0 +1,98 @@
1
+ require 'common'
2
+ require 'net/ssh/authentication/methods/keyboard_interactive'
3
+ require 'authentication/methods/common'
4
+
5
+ module Authentication; module Methods
6
+
7
+ class TestKeyboardInteractive < Test::Unit::TestCase
8
+ include Common
9
+
10
+ USERAUTH_INFO_REQUEST = 60
11
+ USERAUTH_INFO_RESPONSE = 61
12
+
13
+ def test_authenticate_should_be_false_when_server_does_not_support_this_method
14
+ transport.expect do |t,packet|
15
+ assert_equal USERAUTH_REQUEST, packet.type
16
+ assert_equal "jamis", packet.read_string
17
+ assert_equal "ssh-connection", packet.read_string
18
+ assert_equal "keyboard-interactive", packet.read_string
19
+ assert_equal "", packet.read_string # language tags
20
+ assert_equal "", packet.read_string # submethods
21
+
22
+ t.return(USERAUTH_FAILURE, :string, "password")
23
+ end
24
+
25
+ assert_equal false, subject.authenticate("ssh-connection", "jamis")
26
+ end
27
+
28
+ def test_authenticate_should_be_false_if_given_password_is_not_accepted
29
+ transport.expect do |t,packet|
30
+ assert_equal USERAUTH_REQUEST, packet.type
31
+ t.return(USERAUTH_INFO_REQUEST, :string, "", :string, "", :string, "", :long, 1, :string, "Password:", :bool, false)
32
+ t.expect do |t,packet|
33
+ assert_equal USERAUTH_INFO_RESPONSE, packet.type
34
+ assert_equal 1, packet.read_long
35
+ assert_equal "the-password", packet.read_string
36
+ t.return(USERAUTH_FAILURE, :string, "publickey")
37
+ end
38
+ end
39
+
40
+ assert_equal false, subject.authenticate("ssh-connection", "jamis", "the-password")
41
+ end
42
+
43
+ def test_authenticate_should_be_true_if_given_password_is_accepted
44
+ transport.expect do |t,packet|
45
+ assert_equal USERAUTH_REQUEST, packet.type
46
+ t.return(USERAUTH_INFO_REQUEST, :string, "", :string, "", :string, "", :long, 1, :string, "Password:", :bool, false)
47
+ t.expect do |t,packet|
48
+ assert_equal USERAUTH_INFO_RESPONSE, packet.type
49
+ t.return(USERAUTH_SUCCESS)
50
+ end
51
+ end
52
+
53
+ assert subject.authenticate("ssh-connection", "jamis", "the-password")
54
+ end
55
+
56
+ def test_authenticate_should_duplicate_password_as_needed_to_fill_request
57
+ transport.expect do |t,packet|
58
+ assert_equal USERAUTH_REQUEST, packet.type
59
+ t.return(USERAUTH_INFO_REQUEST, :string, "", :string, "", :string, "", :long, 2, :string, "Password:", :bool, false, :string, "Again:", :bool, false)
60
+ t.expect do |t,packet|
61
+ assert_equal USERAUTH_INFO_RESPONSE, packet.type
62
+ assert_equal 2, packet.read_long
63
+ assert_equal "the-password", packet.read_string
64
+ assert_equal "the-password", packet.read_string
65
+ t.return(USERAUTH_SUCCESS)
66
+ end
67
+ end
68
+
69
+ assert subject.authenticate("ssh-connection", "jamis", "the-password")
70
+ end
71
+
72
+ def test_authenticate_should_prompt_for_input_when_password_is_not_given
73
+ subject.expects(:prompt).with("Name:", true).returns("name")
74
+ subject.expects(:prompt).with("Password:", false).returns("password")
75
+
76
+ transport.expect do |t,packet|
77
+ assert_equal USERAUTH_REQUEST, packet.type
78
+ t.return(USERAUTH_INFO_REQUEST, :string, "", :string, "", :string, "", :long, 2, :string, "Name:", :bool, true, :string, "Password:", :bool, false)
79
+ t.expect do |t,packet|
80
+ assert_equal USERAUTH_INFO_RESPONSE, packet.type
81
+ assert_equal 2, packet.read_long
82
+ assert_equal "name", packet.read_string
83
+ assert_equal "password", packet.read_string
84
+ t.return(USERAUTH_SUCCESS)
85
+ end
86
+ end
87
+
88
+ assert subject.authenticate("ssh-connection", "jamis", nil)
89
+ end
90
+
91
+ private
92
+
93
+ def subject(options={})
94
+ @subject ||= Net::SSH::Authentication::Methods::KeyboardInteractive.new(session(options), options)
95
+ end
96
+ end
97
+
98
+ end; end
@@ -0,0 +1,50 @@
1
+ require 'common'
2
+ require 'net/ssh/authentication/methods/password'
3
+ require 'authentication/methods/common'
4
+
5
+ module Authentication; module Methods
6
+
7
+ class TestPassword < Test::Unit::TestCase
8
+ include Common
9
+
10
+ def test_authenticate_when_password_is_unacceptible_should_return_false
11
+ transport.expect do |t,packet|
12
+ assert_equal USERAUTH_REQUEST, packet.type
13
+ assert_equal "jamis", packet.read_string
14
+ assert_equal "ssh-connection", packet.read_string
15
+ assert_equal "password", packet.read_string
16
+ assert_equal false, packet.read_bool
17
+ assert_equal "the-password", packet.read_string
18
+
19
+ t.return(USERAUTH_FAILURE, :string, "publickey")
20
+ end
21
+
22
+ assert !subject.authenticate("ssh-connection", "jamis", "the-password")
23
+ end
24
+
25
+ def test_authenticate_when_password_is_acceptible_should_return_true
26
+ transport.expect do |t,packet|
27
+ assert_equal USERAUTH_REQUEST, packet.type
28
+ t.return(USERAUTH_SUCCESS)
29
+ end
30
+
31
+ assert subject.authenticate("ssh-connection", "jamis", "the-password")
32
+ end
33
+
34
+ def test_authenticate_should_return_false_if_password_change_request_is_received
35
+ transport.expect do |t,packet|
36
+ assert_equal USERAUTH_REQUEST, packet.type
37
+ t.return(USERAUTH_PASSWD_CHANGEREQ, :string, "Change your password:", :string, "")
38
+ end
39
+
40
+ assert !subject.authenticate("ssh-connection", "jamis", "the-password")
41
+ end
42
+
43
+ private
44
+
45
+ def subject(options={})
46
+ @subject ||= Net::SSH::Authentication::Methods::Password.new(session(options), options)
47
+ end
48
+ end
49
+
50
+ end; end
@@ -0,0 +1,123 @@
1
+ require 'common'
2
+ require 'net/ssh/authentication/methods/publickey'
3
+ require 'authentication/methods/common'
4
+
5
+ module Authentication; module Methods
6
+
7
+ class TestPublickey < Test::Unit::TestCase
8
+ include Common
9
+
10
+ def test_authenticate_should_return_false_when_no_key_manager_has_been_set
11
+ assert_equal false, subject(:key_manager => nil).authenticate("ssh-connection", "jamis")
12
+ end
13
+
14
+ def test_authenticate_should_return_false_when_key_manager_has_no_keys
15
+ assert_equal false, subject(:keys => []).authenticate("ssh-connection", "jamis")
16
+ end
17
+
18
+ def test_authenticate_should_return_false_if_no_keys_can_authenticate
19
+ transport.expect do |t, packet|
20
+ assert_equal USERAUTH_REQUEST, packet.type
21
+ assert verify_userauth_request_packet(packet, keys.first, false)
22
+ t.return(USERAUTH_FAILURE, :string, "hostbased,password")
23
+
24
+ t.expect do |t, packet|
25
+ assert_equal USERAUTH_REQUEST, packet.type
26
+ assert verify_userauth_request_packet(packet, keys.last, false)
27
+ t.return(USERAUTH_FAILURE, :string, "hostbased,password")
28
+ end
29
+ end
30
+
31
+ assert_equal false, subject.authenticate("ssh-connection", "jamis")
32
+ end
33
+
34
+ def test_authenticate_should_return_false_if_signature_exchange_fails
35
+ key_manager.expects(:sign).with(&signature_parameters(keys.first)).returns("sig-one")
36
+ key_manager.expects(:sign).with(&signature_parameters(keys.last)).returns("sig-two")
37
+
38
+ transport.expect do |t, packet|
39
+ assert_equal USERAUTH_REQUEST, packet.type
40
+ assert verify_userauth_request_packet(packet, keys.first, false)
41
+ t.return(USERAUTH_PK_OK, :string, keys.first.ssh_type, :string, Net::SSH::Buffer.from(:key, keys.first))
42
+
43
+ t.expect do |t,packet|
44
+ assert_equal USERAUTH_REQUEST, packet.type
45
+ assert verify_userauth_request_packet(packet, keys.first, true)
46
+ assert_equal "sig-one", packet.read_string
47
+ t.return(USERAUTH_FAILURE, :string, "hostbased,password")
48
+
49
+ t.expect do |t, packet|
50
+ assert_equal USERAUTH_REQUEST, packet.type
51
+ assert verify_userauth_request_packet(packet, keys.last, false)
52
+ t.return(USERAUTH_PK_OK, :string, keys.last.ssh_type, :string, Net::SSH::Buffer.from(:key, keys.last))
53
+
54
+ t.expect do |t,packet|
55
+ assert_equal USERAUTH_REQUEST, packet.type
56
+ assert verify_userauth_request_packet(packet, keys.last, true)
57
+ assert_equal "sig-two", packet.read_string
58
+ t.return(USERAUTH_FAILURE, :string, "hostbased,password")
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ assert !subject.authenticate("ssh-connection", "jamis")
65
+ end
66
+
67
+ def test_authenticate_should_return_true_if_any_key_can_authenticate
68
+ key_manager.expects(:sign).with(&signature_parameters(keys.first)).returns("sig-one")
69
+
70
+ transport.expect do |t, packet|
71
+ assert_equal USERAUTH_REQUEST, packet.type
72
+ assert verify_userauth_request_packet(packet, keys.first, false)
73
+ t.return(USERAUTH_PK_OK, :string, keys.first.ssh_type, :string, Net::SSH::Buffer.from(:key, keys.first))
74
+
75
+ t.expect do |t,packet|
76
+ assert_equal USERAUTH_REQUEST, packet.type
77
+ assert verify_userauth_request_packet(packet, keys.first, true)
78
+ assert_equal "sig-one", packet.read_string
79
+ t.return(USERAUTH_SUCCESS)
80
+ end
81
+ end
82
+
83
+ assert subject.authenticate("ssh-connection", "jamis")
84
+ end
85
+
86
+ private
87
+
88
+ def signature_parameters(key)
89
+ Proc.new do |given_key, data|
90
+ next false unless given_key.to_blob == key.to_blob
91
+ buffer = Net::SSH::Buffer.new(data)
92
+ buffer.read_string == "abcxyz123" && # session-id
93
+ buffer.read_byte == USERAUTH_REQUEST && # type
94
+ verify_userauth_request_packet(buffer, key, true)
95
+ end
96
+ end
97
+
98
+ def verify_userauth_request_packet(packet, key, has_sig)
99
+ packet.read_string == "jamis" && # user-name
100
+ packet.read_string == "ssh-connection" && # next service
101
+ packet.read_string == "publickey" && # auth-method
102
+ packet.read_bool == has_sig && # whether a signature is appended
103
+ packet.read_string == key.ssh_type && # ssh key type
104
+ packet.read_buffer.read_key.to_blob == key.to_blob # key
105
+ end
106
+
107
+ @@keys = nil
108
+ def keys
109
+ @@keys ||= [OpenSSL::PKey::RSA.new(32), OpenSSL::PKey::DSA.new(32)]
110
+ end
111
+
112
+ def key_manager(options={})
113
+ @key_manager ||= stub("key_manager", :identities => options[:keys] || keys)
114
+ end
115
+
116
+ def subject(options={})
117
+ options[:key_manager] = key_manager(options) unless options.key?(:key_manager)
118
+ @subject ||= Net::SSH::Authentication::Methods::Publickey.new(session(options), options)
119
+ end
120
+
121
+ end
122
+
123
+ end; end