net-ssh 0.5.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.
Files changed (179) hide show
  1. data/doc/LICENSE-BSD +27 -0
  2. data/doc/LICENSE-GPL +280 -0
  3. data/doc/LICENSE-RUBY +56 -0
  4. data/doc/README +13 -0
  5. data/doc/manual-html/chapter-1.html +333 -0
  6. data/doc/manual-html/chapter-2.html +455 -0
  7. data/doc/manual-html/chapter-3.html +413 -0
  8. data/doc/manual-html/chapter-4.html +353 -0
  9. data/doc/manual-html/chapter-5.html +393 -0
  10. data/doc/manual-html/chapter-6.html +296 -0
  11. data/doc/manual-html/index.html +217 -0
  12. data/doc/manual-html/manual.css +192 -0
  13. data/doc/manual/chapter.erb +18 -0
  14. data/doc/manual/example.erb +18 -0
  15. data/doc/manual/index.erb +29 -0
  16. data/doc/manual/manual.css +192 -0
  17. data/doc/manual/manual.rb +240 -0
  18. data/doc/manual/manual.yml +67 -0
  19. data/doc/manual/page.erb +87 -0
  20. data/doc/manual/parts/channels_callbacks.txt +32 -0
  21. data/doc/manual/parts/channels_loop.txt +14 -0
  22. data/doc/manual/parts/channels_open.txt +20 -0
  23. data/doc/manual/parts/channels_operations.txt +15 -0
  24. data/doc/manual/parts/channels_types.txt +3 -0
  25. data/doc/manual/parts/channels_what_are.txt +7 -0
  26. data/doc/manual/parts/exec_channels.txt +28 -0
  27. data/doc/manual/parts/exec_open.txt +51 -0
  28. data/doc/manual/parts/exec_popen3.txt +35 -0
  29. data/doc/manual/parts/forward_direct.txt +37 -0
  30. data/doc/manual/parts/forward_handlers.txt +16 -0
  31. data/doc/manual/parts/forward_intro.txt +18 -0
  32. data/doc/manual/parts/forward_local.txt +18 -0
  33. data/doc/manual/parts/forward_remote.txt +14 -0
  34. data/doc/manual/parts/intro_author.txt +1 -0
  35. data/doc/manual/parts/intro_getting.txt +39 -0
  36. data/doc/manual/parts/intro_license.txt +6 -0
  37. data/doc/manual/parts/intro_support.txt +7 -0
  38. data/doc/manual/parts/intro_what_is.txt +7 -0
  39. data/doc/manual/parts/intro_what_is_not.txt +3 -0
  40. data/doc/manual/parts/proxy_http.txt +52 -0
  41. data/doc/manual/parts/proxy_intro.txt +1 -0
  42. data/doc/manual/parts/proxy_socks.txt +23 -0
  43. data/doc/manual/parts/session_key.txt +66 -0
  44. data/doc/manual/parts/session_options.txt +42 -0
  45. data/doc/manual/parts/session_session.txt +14 -0
  46. data/doc/manual/parts/session_start.txt +49 -0
  47. data/doc/manual/tutorial.erb +30 -0
  48. data/examples/channel-demo.rb +81 -0
  49. data/examples/port-forward.rb +51 -0
  50. data/examples/process-demo.rb +91 -0
  51. data/examples/remote-net-port-forward.rb +45 -0
  52. data/examples/remote-port-forward.rb +80 -0
  53. data/examples/tail-demo.rb +49 -0
  54. data/lib/net/ssh.rb +52 -0
  55. data/lib/net/ssh/connection/channel.rb +411 -0
  56. data/lib/net/ssh/connection/constants.rb +47 -0
  57. data/lib/net/ssh/connection/driver.rb +343 -0
  58. data/lib/net/ssh/connection/services.rb +72 -0
  59. data/lib/net/ssh/connection/term.rb +90 -0
  60. data/lib/net/ssh/errors.rb +27 -0
  61. data/lib/net/ssh/proxy/errors.rb +34 -0
  62. data/lib/net/ssh/proxy/http.rb +126 -0
  63. data/lib/net/ssh/proxy/socks4.rb +83 -0
  64. data/lib/net/ssh/proxy/socks5.rb +160 -0
  65. data/lib/net/ssh/service/forward/driver.rb +319 -0
  66. data/lib/net/ssh/service/forward/local-network-handler.rb +74 -0
  67. data/lib/net/ssh/service/forward/remote-network-handler.rb +81 -0
  68. data/lib/net/ssh/service/forward/services.rb +76 -0
  69. data/lib/net/ssh/service/process/driver.rb +153 -0
  70. data/lib/net/ssh/service/process/open.rb +193 -0
  71. data/lib/net/ssh/service/process/popen3.rb +160 -0
  72. data/lib/net/ssh/service/process/services.rb +66 -0
  73. data/lib/net/ssh/service/services.rb +44 -0
  74. data/lib/net/ssh/session.rb +242 -0
  75. data/lib/net/ssh/transport/algorithm-negotiator.rb +267 -0
  76. data/lib/net/ssh/transport/compress/compressor.rb +53 -0
  77. data/lib/net/ssh/transport/compress/decompressor.rb +53 -0
  78. data/lib/net/ssh/transport/compress/none-compressor.rb +39 -0
  79. data/lib/net/ssh/transport/compress/none-decompressor.rb +39 -0
  80. data/lib/net/ssh/transport/compress/services.rb +68 -0
  81. data/lib/net/ssh/transport/compress/zlib-compressor.rb +60 -0
  82. data/lib/net/ssh/transport/compress/zlib-decompressor.rb +52 -0
  83. data/lib/net/ssh/transport/constants.rb +66 -0
  84. data/lib/net/ssh/transport/errors.rb +47 -0
  85. data/lib/net/ssh/transport/identity-cipher.rb +61 -0
  86. data/lib/net/ssh/transport/kex/dh-gex.rb +106 -0
  87. data/lib/net/ssh/transport/kex/dh.rb +231 -0
  88. data/lib/net/ssh/transport/kex/services.rb +60 -0
  89. data/lib/net/ssh/transport/ossl/buffer-factory.rb +52 -0
  90. data/lib/net/ssh/transport/ossl/buffer.rb +87 -0
  91. data/lib/net/ssh/transport/ossl/cipher-factory.rb +98 -0
  92. data/lib/net/ssh/transport/ossl/digest-factory.rb +51 -0
  93. data/lib/net/ssh/transport/ossl/hmac-factory.rb +71 -0
  94. data/lib/net/ssh/transport/ossl/hmac/hmac.rb +62 -0
  95. data/lib/net/ssh/transport/ossl/hmac/md5-96.rb +44 -0
  96. data/lib/net/ssh/transport/ossl/hmac/md5.rb +46 -0
  97. data/lib/net/ssh/transport/ossl/hmac/none.rb +46 -0
  98. data/lib/net/ssh/transport/ossl/hmac/services.rb +68 -0
  99. data/lib/net/ssh/transport/ossl/hmac/sha1-96.rb +44 -0
  100. data/lib/net/ssh/transport/ossl/hmac/sha1.rb +45 -0
  101. data/lib/net/ssh/transport/ossl/key-factory.rb +113 -0
  102. data/lib/net/ssh/transport/ossl/services.rb +149 -0
  103. data/lib/net/ssh/transport/packet-stream.rb +210 -0
  104. data/lib/net/ssh/transport/services.rb +146 -0
  105. data/lib/net/ssh/transport/session.rb +296 -0
  106. data/lib/net/ssh/transport/version-negotiator.rb +73 -0
  107. data/lib/net/ssh/userauth/agent.rb +218 -0
  108. data/lib/net/ssh/userauth/constants.rb +35 -0
  109. data/lib/net/ssh/userauth/driver.rb +176 -0
  110. data/lib/net/ssh/userauth/methods/hostbased.rb +119 -0
  111. data/lib/net/ssh/userauth/methods/password.rb +70 -0
  112. data/lib/net/ssh/userauth/methods/publickey.rb +137 -0
  113. data/lib/net/ssh/userauth/methods/services.rb +63 -0
  114. data/lib/net/ssh/userauth/services.rb +126 -0
  115. data/lib/net/ssh/userauth/userkeys.rb +258 -0
  116. data/lib/net/ssh/util/buffer.rb +274 -0
  117. data/lib/net/ssh/util/openssl.rb +146 -0
  118. data/lib/net/ssh/util/prompter.rb +73 -0
  119. data/lib/net/ssh/version.rb +29 -0
  120. data/test/ALL-TESTS.rb +21 -0
  121. data/test/connection/tc_channel.rb +136 -0
  122. data/test/connection/tc_driver.rb +287 -0
  123. data/test/connection/tc_integration.rb +85 -0
  124. data/test/proxy/tc_http.rb +209 -0
  125. data/test/proxy/tc_socks4.rb +148 -0
  126. data/test/proxy/tc_socks5.rb +214 -0
  127. data/test/service/forward/tc_driver.rb +289 -0
  128. data/test/service/forward/tc_local_network_handler.rb +123 -0
  129. data/test/service/forward/tc_remote_network_handler.rb +108 -0
  130. data/test/service/process/tc_driver.rb +79 -0
  131. data/test/service/process/tc_integration.rb +117 -0
  132. data/test/service/process/tc_open.rb +179 -0
  133. data/test/service/process/tc_popen3.rb +164 -0
  134. data/test/tc_integration.rb +79 -0
  135. data/test/transport/compress/tc_none_compress.rb +41 -0
  136. data/test/transport/compress/tc_none_decompress.rb +45 -0
  137. data/test/transport/compress/tc_zlib_compress.rb +61 -0
  138. data/test/transport/compress/tc_zlib_decompress.rb +48 -0
  139. data/test/transport/kex/tc_dh.rb +304 -0
  140. data/test/transport/kex/tc_dh_gex.rb +70 -0
  141. data/test/transport/ossl/fixtures/dsa-encrypted +15 -0
  142. data/test/transport/ossl/fixtures/dsa-encrypted-bad +15 -0
  143. data/test/transport/ossl/fixtures/dsa-unencrypted +12 -0
  144. data/test/transport/ossl/fixtures/dsa-unencrypted-bad +12 -0
  145. data/test/transport/ossl/fixtures/dsa-unencrypted.pub +1 -0
  146. data/test/transport/ossl/fixtures/not-a-private-key +4 -0
  147. data/test/transport/ossl/fixtures/not-supported +2 -0
  148. data/test/transport/ossl/fixtures/rsa-encrypted +18 -0
  149. data/test/transport/ossl/fixtures/rsa-encrypted-bad +18 -0
  150. data/test/transport/ossl/fixtures/rsa-unencrypted +15 -0
  151. data/test/transport/ossl/fixtures/rsa-unencrypted-bad +15 -0
  152. data/test/transport/ossl/fixtures/rsa-unencrypted.pub +1 -0
  153. data/test/transport/ossl/hmac/tc_hmac.rb +58 -0
  154. data/test/transport/ossl/hmac/tc_md5.rb +50 -0
  155. data/test/transport/ossl/hmac/tc_md5_96.rb +50 -0
  156. data/test/transport/ossl/hmac/tc_none.rb +50 -0
  157. data/test/transport/ossl/hmac/tc_sha1.rb +50 -0
  158. data/test/transport/ossl/hmac/tc_sha1_96.rb +50 -0
  159. data/test/transport/ossl/tc_buffer.rb +97 -0
  160. data/test/transport/ossl/tc_buffer_factory.rb +67 -0
  161. data/test/transport/ossl/tc_cipher_factory.rb +84 -0
  162. data/test/transport/ossl/tc_digest_factory.rb +39 -0
  163. data/test/transport/ossl/tc_hmac_factory.rb +72 -0
  164. data/test/transport/ossl/tc_key_factory.rb +199 -0
  165. data/test/transport/tc_algorithm_negotiator.rb +169 -0
  166. data/test/transport/tc_identity_cipher.rb +52 -0
  167. data/test/transport/tc_integration.rb +110 -0
  168. data/test/transport/tc_packet_stream.rb +183 -0
  169. data/test/transport/tc_session.rb +283 -0
  170. data/test/transport/tc_version_negotiator.rb +86 -0
  171. data/test/userauth/methods/tc_hostbased.rb +136 -0
  172. data/test/userauth/methods/tc_password.rb +89 -0
  173. data/test/userauth/methods/tc_publickey.rb +167 -0
  174. data/test/userauth/tc_agent.rb +223 -0
  175. data/test/userauth/tc_driver.rb +190 -0
  176. data/test/userauth/tc_integration.rb +81 -0
  177. data/test/userauth/tc_userkeys.rb +265 -0
  178. data/test/util/tc_buffer.rb +217 -0
  179. metadata +256 -0
@@ -0,0 +1,89 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../../lib"
18
+
19
+ require 'net/ssh/userauth/methods/password'
20
+ require 'net/ssh/util/buffer'
21
+ require 'test/unit'
22
+ require 'ostruct'
23
+
24
+ class TC_Methods_Password < Test::Unit::TestCase
25
+
26
+ class Buffers
27
+ def writer
28
+ Net::SSH::Util::WriterBuffer.new
29
+ end
30
+ end
31
+
32
+ class Messenger
33
+ attr_reader :data
34
+ attr_reader :messages
35
+
36
+ def initialize
37
+ @data = []
38
+ @messages = []
39
+ end
40
+
41
+ def send_message( msg )
42
+ @messages << msg.to_s
43
+ end
44
+
45
+ def wait_for_message
46
+ @data.shift
47
+ end
48
+ end
49
+
50
+ def setup
51
+ buffers = Buffers.new
52
+ @messenger = Messenger.new
53
+ @password = Net::SSH::UserAuth::Methods::Password.new( buffers )
54
+ @password.messenger = @messenger
55
+ end
56
+
57
+ def test_authenticate_no_password
58
+ assert !@password.authenticate( "test", "test_user" )
59
+ assert @messenger.messages.empty?
60
+ end
61
+
62
+ def test_authenticate_success
63
+ @messenger.data << OpenStruct.new( :message_type => 52 )
64
+ assert @password.authenticate( "test", "test_user", :password => "passwd" )
65
+ assert_equal 1, @messenger.messages.length
66
+ assert_equal "#{50.chr}\0\0\0\11test_user\0\0\0\4test\0\0\0\10password\0\0\0\0\6passwd",
67
+ @messenger.messages.last
68
+ end
69
+
70
+ def test_authenticate_failure
71
+ @messenger.data << OpenStruct.new( :message_type => 51 )
72
+ assert !@password.authenticate( "test", "test_user", :password => "passwd" )
73
+ assert !@messenger.messages.empty?
74
+ end
75
+
76
+ def test_authenticate_passwd_changereq
77
+ @messenger.data << OpenStruct.new( :message_type => 60 )
78
+ assert !@password.authenticate( "test", "test_user", :password => "passwd" )
79
+ assert !@messenger.messages.empty?
80
+ end
81
+
82
+ def test_authenticate_bad_reply
83
+ @messenger.data << OpenStruct.new( :message_type => 0 )
84
+ assert_raise( Net::SSH::Exception ) do
85
+ @password.authenticate( "test", "test_user", :password=>"passwd" )
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,167 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../../lib"
18
+
19
+ require 'net/ssh/userauth/methods/publickey'
20
+ require 'net/ssh/util/buffer'
21
+ require 'test/unit'
22
+ require 'ostruct'
23
+
24
+ class TC_Methods_PublicKey < Test::Unit::TestCase
25
+
26
+ class Buffers
27
+ def writer
28
+ Net::SSH::Util::WriterBuffer.new
29
+ end
30
+ end
31
+
32
+ class Key < OpenStruct
33
+ def initialize( e, n )
34
+ super( :ssh_type => "ssh-rsa",
35
+ :e => OpenStruct.new( :to_ssh => [ e ].pack("N") ),
36
+ :n => OpenStruct.new( :to_ssh => [ n ].pack("N") ) )
37
+ end
38
+ end
39
+
40
+ class Messenger
41
+ attr_reader :data
42
+ attr_reader :messages
43
+
44
+ def initialize
45
+ @data = []
46
+ @messages = []
47
+ end
48
+
49
+ def send_message( msg )
50
+ @messages << msg.to_s
51
+ end
52
+
53
+ def wait_for_message
54
+ @data.shift
55
+ end
56
+ end
57
+
58
+ class KeyManager
59
+ attr_reader :identities
60
+ attr_reader :state
61
+ attr_reader :sigdata
62
+
63
+ def initialize( *identities )
64
+ @identities = identities.flatten
65
+ @state = :open
66
+ end
67
+
68
+ def sign( identity, data )
69
+ @sigdata = [ identity, data.to_s ]
70
+ "<signature>"
71
+ end
72
+
73
+ def finish
74
+ @state = :finished
75
+ end
76
+ end
77
+
78
+ def setup
79
+ buffers = Buffers.new
80
+ @messenger = Messenger.new
81
+ @method = Net::SSH::UserAuth::Methods::PublicKey.new( buffers )
82
+ @method.messenger = @messenger
83
+ @method.session_id = "test"
84
+ end
85
+
86
+ def test_authenticate_no_key_manager
87
+ assert !@method.authenticate( "test", "test_user" )
88
+ assert @messenger.messages.empty?
89
+ end
90
+
91
+ def test_authenticate_no_identities
92
+ manager = KeyManager.new
93
+ assert !@method.authenticate( "test", "test_user", :key_manager => manager )
94
+ assert_equal :finished, manager.state
95
+ end
96
+
97
+ def test_authenticate_no_acceptible_identities
98
+ manager = KeyManager.new( Key.new( 0x01010101, 0x02020202 ),
99
+ Key.new( 0x03030303, 0x04040404 ) )
100
+ @messenger.data.concat [ OpenStruct.new( :message_type => 51 ),
101
+ OpenStruct.new( :message_type => 51 ) ]
102
+ assert !@method.authenticate( "test", "test_user", :key_manager => manager )
103
+ assert_equal :finished, manager.state
104
+ assert_equal 2, @messenger.messages.length
105
+
106
+ packet1 = "#{50.chr}\0\0\0\11test_user\0\0\0\4test\0\0\0\11publickey\0\0\0\0\7ssh-rsa" +
107
+ "\0\0\0\23\0\0\0\7ssh-rsa\1\1\1\1\2\2\2\2"
108
+ assert_equal packet1, @messenger.messages[0]
109
+
110
+ packet2 = "#{50.chr}\0\0\0\11test_user\0\0\0\4test\0\0\0\11publickey\0\0\0\0\7ssh-rsa" +
111
+ "\0\0\0\23\0\0\0\7ssh-rsa\3\3\3\3\4\4\4\4"
112
+ assert_equal packet2, @messenger.messages[1]
113
+ end
114
+
115
+ def test_authenticate_unexpected_reply
116
+ manager = KeyManager.new( Key.new( 0x01010101, 0x02020202 ) )
117
+ @messenger.data.concat [ OpenStruct.new( :message_type => 0 ) ]
118
+ assert_raise( Net::SSH::Exception ) do
119
+ @method.authenticate( "test", "test_user", :key_manager => manager )
120
+ end
121
+ assert_equal :finished, manager.state
122
+ end
123
+
124
+ def test_authenticate_acceptible_identities_fail
125
+ manager = KeyManager.new( Key.new( 0x01010101, 0x02020202 ) )
126
+ @messenger.data.concat [ OpenStruct.new( :message_type => 60 ),
127
+ OpenStruct.new( :message_type => 51 ) ]
128
+ assert !@method.authenticate( "test", "test_user", :key_manager => manager )
129
+ assert_equal :finished, manager.state
130
+ assert_equal 2, @messenger.messages.length
131
+
132
+ packet1 = "#{50.chr}\0\0\0\11test_user\0\0\0\4test\0\0\0\11publickey\0\0\0\0\7ssh-rsa" +
133
+ "\0\0\0\23\0\0\0\7ssh-rsa\1\1\1\1\2\2\2\2"
134
+ assert_equal packet1, @messenger.messages[0]
135
+
136
+ packet2 = "#{50.chr}\0\0\0\11test_user\0\0\0\4test\0\0\0\11publickey\1\0\0\0\7ssh-rsa" +
137
+ "\0\0\0\23\0\0\0\7ssh-rsa\1\1\1\1\2\2\2\2" +
138
+ "\0\0\0\13<signature>"
139
+ assert_equal packet2, @messenger.messages[1]
140
+
141
+ sigdata = manager.sigdata
142
+ signature = "\0\0\0\4test" +
143
+ "#{50.chr}\0\0\0\11test_user\0\0\0\4test\0\0\0\11publickey\1\0\0\0\7ssh-rsa" +
144
+ "\0\0\0\23\0\0\0\7ssh-rsa\1\1\1\1\2\2\2\2"
145
+ assert_equal signature, sigdata[1]
146
+ end
147
+
148
+ def test_authenticate_acceptible_identities_error
149
+ manager = KeyManager.new( Key.new( 0x01010101, 0x02020202 ) )
150
+ @messenger.data.concat [ OpenStruct.new( :message_type => 60 ),
151
+ OpenStruct.new( :message_type => 0 ) ]
152
+ assert_raise( Net::SSH::Exception ) do
153
+ @method.authenticate( "test", "test_user", :key_manager => manager )
154
+ end
155
+ assert_equal 2, @messenger.messages.length
156
+ end
157
+
158
+ def test_authenticate_acceptible_identities_success
159
+ manager = KeyManager.new( Key.new( 0x01010101, 0x02020202 ) )
160
+ @messenger.data.concat [ OpenStruct.new( :message_type => 60 ),
161
+ OpenStruct.new( :message_type => 52 ) ]
162
+ assert @method.authenticate( "test", "test_user", :key_manager => manager )
163
+ assert_equal :finished, manager.state
164
+ assert_equal 2, @messenger.messages.length
165
+ end
166
+
167
+ end
@@ -0,0 +1,223 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../lib"
18
+
19
+ require 'net/ssh/userauth/agent'
20
+ require 'net/ssh/util/buffer'
21
+ require 'test/unit'
22
+
23
+ class TC_Agent < Test::Unit::TestCase
24
+
25
+ class MockReader < Net::SSH::Util::ReaderBuffer
26
+ def read_bignum
27
+ read_long
28
+ end
29
+
30
+ def read_key
31
+ OpenStruct.new(
32
+ :e => read_bignum,
33
+ :n => read_bignum )
34
+ end
35
+ end
36
+
37
+ class Buffers
38
+ def writer
39
+ Net::SSH::Util::WriterBuffer.new
40
+ end
41
+
42
+ def reader( text )
43
+ MockReader.new( text )
44
+ end
45
+ end
46
+
47
+ class SocketFactory
48
+ attr_reader :socket_name
49
+ attr_reader :events
50
+
51
+ def initialize( data )
52
+ @data = Net::SSH::Util::ReaderBuffer.new( data.to_s )
53
+ end
54
+
55
+ def open( name )
56
+ @socket_name = name
57
+ @events = []
58
+ self
59
+ end
60
+
61
+ def close
62
+ @events << :close
63
+ end
64
+
65
+ def send( data, flags )
66
+ @events << data.to_s
67
+ end
68
+
69
+ def read( bytes )
70
+ @data.read( bytes )
71
+ end
72
+ end
73
+
74
+ class Keys
75
+ def get( type )
76
+ require 'ostruct'
77
+ OpenStruct.new
78
+ end
79
+ end
80
+
81
+ def setup
82
+ @agent = Net::SSH::UserAuth::Agent.new
83
+ @agent.socket_name = "test"
84
+ @agent.version = 2
85
+ @agent.buffers = Buffers.new
86
+ @agent.keys = Keys.new
87
+ end
88
+
89
+ CONNECT_STR = "\0\0\0\1\2"
90
+
91
+ def test_connect_bad_version
92
+ @agent.socket_factory = SocketFactory.new( "\0\0\0\1\147" )
93
+ assert_raise( NotImplementedError ) { @agent.connect! }
94
+ end
95
+
96
+ def test_connect_bad_response
97
+ @agent.socket_factory = SocketFactory.new( "\0\0\0\1\0" )
98
+ assert_raise( Net::SSH::UserAuth::AgentError ) { @agent.connect! }
99
+ end
100
+
101
+ def test_connect_success
102
+ @agent.socket_factory = SocketFactory.new( CONNECT_STR )
103
+ assert_nothing_raised { @agent.connect! }
104
+ end
105
+
106
+ IDENTITIES = { 1 => 1,
107
+ 2 => 11 }
108
+
109
+ [ 1, 2 ].each do |version|
110
+ [ 5, 30, 102 ].each do |error_code|
111
+ define_method( "test_identities_v#{version}_c#{error_code}" ) do
112
+ @agent.version = version
113
+ @agent.socket_factory = factory = SocketFactory.new( CONNECT_STR + "\0\0\0\1#{error_code.chr}" )
114
+ @agent.connect!
115
+ assert_raise( Net::SSH::UserAuth::AgentError ) { @agent.identities }
116
+ assert_equal [ "\0\0\0\1#{IDENTITIES[version].chr}" ], factory.events[1..-1]
117
+ end
118
+ end
119
+
120
+ define_method( "test_identities_v#{version}_bad_auth_code" ) do
121
+ @agent.version = version
122
+ @agent.socket_factory = factory = SocketFactory.new( CONNECT_STR + "\0\0\0\1\0" )
123
+ @agent.connect!
124
+ assert_raise( Net::SSH::UserAuth::AgentError ) { @agent.identities }
125
+ assert_equal [ "\0\0\0\1#{IDENTITIES[version].chr}" ], factory.events[1..-1]
126
+ end
127
+ end
128
+
129
+ def test_identities_v1_single
130
+ @agent.version = 1
131
+ @agent.socket_factory = SocketFactory.new( CONNECT_STR + "\0\0\0\32\2\0\0\0\1\1\2\3\4\1\1\1\1\2\2\2\2\0\0\0\5hello" )
132
+ @agent.connect!
133
+ identities = nil
134
+ assert_nothing_raised { identities = @agent.identities }
135
+ assert_equal [ OpenStruct.new( :e => 0x01010101, :n => 0x02020202 ) ], identities
136
+ assert_equal "hello", identities.first.comment
137
+ end
138
+
139
+ def test_identities_v1_multiple
140
+ @agent.version = 1
141
+ @agent.socket_factory = SocketFactory.new( CONNECT_STR +
142
+ "\0\0\0\57\2" +
143
+ "\0\0\0\2" +
144
+ "\1\2\3\4\1\1\1\1\2\2\2\2\0\0\0\5hello" +
145
+ "\2\3\4\5\3\3\3\3\4\4\4\4\0\0\0\5howdy" )
146
+ @agent.connect!
147
+ identities = nil
148
+ assert_nothing_raised { identities = @agent.identities }
149
+ assert_equal [ OpenStruct.new( :e => 0x01010101, :n => 0x02020202 ),
150
+ OpenStruct.new( :e => 0x03030303, :n => 0x04040404 ) ], identities
151
+ assert_equal "hello", identities.first.comment
152
+ assert_equal "howdy", identities.last.comment
153
+ end
154
+
155
+ def test_identities_v2_single
156
+ @agent.version = 2
157
+ @agent.socket_factory = SocketFactory.new( CONNECT_STR +
158
+ "\0\0\0\32\14" +
159
+ "\0\0\0\1" +
160
+ "\0\0\0\10\1\1\1\1\2\2\2\2\0\0\0\5hello" )
161
+ @agent.connect!
162
+ identities = nil
163
+ assert_nothing_raised { identities = @agent.identities }
164
+ assert_equal [ OpenStruct.new( :e => 0x01010101, :n => 0x02020202 ) ], identities
165
+ assert_equal "hello", identities.first.comment
166
+ end
167
+
168
+ def test_identities_v2_multiple
169
+ @agent.version = 2
170
+ @agent.socket_factory = SocketFactory.new( CONNECT_STR +
171
+ "\0\0\0\57\14" +
172
+ "\0\0\0\2" +
173
+ "\0\0\0\10\1\1\1\1\2\2\2\2\0\0\0\5hello" +
174
+ "\0\0\0\10\3\3\3\3\4\4\4\4\0\0\0\5howdy" )
175
+ @agent.connect!
176
+ identities = nil
177
+ assert_nothing_raised { identities = @agent.identities }
178
+ assert_equal [ OpenStruct.new( :e => 0x01010101, :n => 0x02020202 ),
179
+ OpenStruct.new( :e => 0x03030303, :n => 0x04040404 ) ], identities
180
+ assert_equal "hello", identities.first.comment
181
+ assert_equal "howdy", identities.last.comment
182
+ end
183
+
184
+ def test_close
185
+ @agent.socket_factory = factory = SocketFactory.new( CONNECT_STR )
186
+ @agent.connect!
187
+ @agent.close
188
+ assert_equal :close, factory.events.last
189
+ end
190
+
191
+ [ 5, 30, 102 ].each do |error_code|
192
+ define_method( "test_sign_error_#{error_code}" ) do
193
+ @agent.socket_factory = SocketFactory.new( CONNECT_STR + "\0\0\0\1#{error_code.chr}" )
194
+ @agent.connect!
195
+ key = OpenStruct.new( :ssh_type => "ssh-rsa",
196
+ :e => OpenStruct.new( :to_ssh => "e" ),
197
+ :n => OpenStruct.new( :to_ssh => "n" ) )
198
+ assert_raise( Net::SSH::UserAuth::AgentError ) { @agent.sign( key, "test" ) }
199
+ end
200
+ end
201
+
202
+ def test_sign_bad_response
203
+ @agent.socket_factory = SocketFactory.new( CONNECT_STR + "\0\0\0\1\0" )
204
+ @agent.connect!
205
+ key = OpenStruct.new( :ssh_type => "ssh-rsa",
206
+ :e => OpenStruct.new( :to_ssh => "e" ),
207
+ :n => OpenStruct.new( :to_ssh => "n" ) )
208
+ assert_raise( Net::SSH::UserAuth::AgentError ) { @agent.sign( key, "test" ) }
209
+ end
210
+
211
+ def test_sign
212
+ @agent.socket_factory = factory = SocketFactory.new( CONNECT_STR + "\0\0\0\12\16\0\0\0\5howdy" )
213
+ @agent.connect!
214
+ key = OpenStruct.new( :ssh_type => "ssh-rsa",
215
+ :e => OpenStruct.new( :to_ssh => "e" ),
216
+ :n => OpenStruct.new( :to_ssh => "n" ) )
217
+ sig = nil
218
+ assert_nothing_raised { sig = @agent.sign( key, "test" ) }
219
+ assert_equal "howdy", sig
220
+ assert_equal "\0\0\0\36\15\0\0\0\15\0\0\0\7ssh-rsaen\0\0\0\4test\0\0\0\0", factory.events.last
221
+ end
222
+
223
+ end