net-ssh-net-ssh 2.0.12

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 (105) hide show
  1. data/CHANGELOG.rdoc +137 -0
  2. data/Manifest +104 -0
  3. data/README.rdoc +110 -0
  4. data/Rakefile +79 -0
  5. data/THANKS.rdoc +16 -0
  6. data/lib/net/ssh.rb +215 -0
  7. data/lib/net/ssh/authentication/agent.rb +176 -0
  8. data/lib/net/ssh/authentication/constants.rb +18 -0
  9. data/lib/net/ssh/authentication/key_manager.rb +193 -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 +183 -0
  16. data/lib/net/ssh/authentication/session.rb +134 -0
  17. data/lib/net/ssh/buffer.rb +340 -0
  18. data/lib/net/ssh/buffered_io.rb +149 -0
  19. data/lib/net/ssh/config.rb +181 -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 +596 -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 +102 -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 +129 -0
  34. data/lib/net/ssh/ruby_compat.rb +7 -0
  35. data/lib/net/ssh/service/forward.rb +267 -0
  36. data/lib/net/ssh/test.rb +89 -0
  37. data/lib/net/ssh/test/channel.rb +129 -0
  38. data/lib/net/ssh/test/extensions.rb +152 -0
  39. data/lib/net/ssh/test/kex.rb +44 -0
  40. data/lib/net/ssh/test/local_packet.rb +51 -0
  41. data/lib/net/ssh/test/packet.rb +81 -0
  42. data/lib/net/ssh/test/remote_packet.rb +38 -0
  43. data/lib/net/ssh/test/script.rb +157 -0
  44. data/lib/net/ssh/test/socket.rb +59 -0
  45. data/lib/net/ssh/transport/algorithms.rb +384 -0
  46. data/lib/net/ssh/transport/cipher_factory.rb +84 -0
  47. data/lib/net/ssh/transport/constants.rb +30 -0
  48. data/lib/net/ssh/transport/hmac.rb +31 -0
  49. data/lib/net/ssh/transport/hmac/abstract.rb +78 -0
  50. data/lib/net/ssh/transport/hmac/md5.rb +12 -0
  51. data/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  52. data/lib/net/ssh/transport/hmac/none.rb +15 -0
  53. data/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  54. data/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  55. data/lib/net/ssh/transport/identity_cipher.rb +55 -0
  56. data/lib/net/ssh/transport/kex.rb +13 -0
  57. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +208 -0
  58. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +77 -0
  59. data/lib/net/ssh/transport/openssl.rb +128 -0
  60. data/lib/net/ssh/transport/packet_stream.rb +230 -0
  61. data/lib/net/ssh/transport/server_version.rb +69 -0
  62. data/lib/net/ssh/transport/session.rb +276 -0
  63. data/lib/net/ssh/transport/state.rb +206 -0
  64. data/lib/net/ssh/verifiers/lenient.rb +30 -0
  65. data/lib/net/ssh/verifiers/null.rb +12 -0
  66. data/lib/net/ssh/verifiers/strict.rb +53 -0
  67. data/lib/net/ssh/version.rb +62 -0
  68. data/net-ssh.gemspec +128 -0
  69. data/setup.rb +1585 -0
  70. data/test/authentication/methods/common.rb +28 -0
  71. data/test/authentication/methods/test_abstract.rb +51 -0
  72. data/test/authentication/methods/test_hostbased.rb +114 -0
  73. data/test/authentication/methods/test_keyboard_interactive.rb +98 -0
  74. data/test/authentication/methods/test_password.rb +50 -0
  75. data/test/authentication/methods/test_publickey.rb +127 -0
  76. data/test/authentication/test_agent.rb +205 -0
  77. data/test/authentication/test_key_manager.rb +105 -0
  78. data/test/authentication/test_session.rb +93 -0
  79. data/test/common.rb +106 -0
  80. data/test/configs/eqsign +3 -0
  81. data/test/configs/exact_match +8 -0
  82. data/test/configs/wild_cards +14 -0
  83. data/test/connection/test_channel.rb +452 -0
  84. data/test/connection/test_session.rb +488 -0
  85. data/test/test_all.rb +6 -0
  86. data/test/test_buffer.rb +336 -0
  87. data/test/test_buffered_io.rb +63 -0
  88. data/test/test_config.rb +84 -0
  89. data/test/test_key_factory.rb +67 -0
  90. data/test/transport/hmac/test_md5.rb +39 -0
  91. data/test/transport/hmac/test_md5_96.rb +25 -0
  92. data/test/transport/hmac/test_none.rb +34 -0
  93. data/test/transport/hmac/test_sha1.rb +34 -0
  94. data/test/transport/hmac/test_sha1_96.rb +25 -0
  95. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  96. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  97. data/test/transport/test_algorithms.rb +302 -0
  98. data/test/transport/test_cipher_factory.rb +171 -0
  99. data/test/transport/test_hmac.rb +34 -0
  100. data/test/transport/test_identity_cipher.rb +40 -0
  101. data/test/transport/test_packet_stream.rb +435 -0
  102. data/test/transport/test_server_version.rb +68 -0
  103. data/test/transport/test_session.rb +315 -0
  104. data/test/transport/test_state.rb +173 -0
  105. metadata +162 -0
@@ -0,0 +1,302 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/algorithms'
3
+
4
+ module Transport
5
+
6
+ class TestAlgorithms < Test::Unit::TestCase
7
+ include Net::SSH::Transport::Constants
8
+
9
+ def test_allowed_packets
10
+ (0..255).each do |type|
11
+ packet = stub("packet", :type => type)
12
+ case type
13
+ when 1..4, 6..19, 21..49 then assert(Net::SSH::Transport::Algorithms.allowed_packet?(packet), "#{type} should be allowed during key exchange")
14
+ else assert(!Net::SSH::Transport::Algorithms.allowed_packet?(packet), "#{type} should not be allowed during key exchange")
15
+ end
16
+ end
17
+ end
18
+
19
+ def test_constructor_should_build_default_list_of_preferred_algorithms
20
+ assert_equal %w(ssh-rsa ssh-dss), algorithms[:host_key]
21
+ assert_equal %w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1), algorithms[:kex]
22
+ assert_equal %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se idea-cbc none arcfour128 arcfour256), algorithms[:encryption]
23
+ assert_equal %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 none), algorithms[:hmac]
24
+ assert_equal %w(none zlib@openssh.com zlib), algorithms[:compression]
25
+ assert_equal %w(), algorithms[:language]
26
+ end
27
+
28
+ def test_constructor_should_set_client_and_server_prefs_identically
29
+ %w(encryption hmac compression language).each do |key|
30
+ assert_equal algorithms[key.to_sym], algorithms[:"#{key}_client"], key
31
+ assert_equal algorithms[key.to_sym], algorithms[:"#{key}_server"], key
32
+ end
33
+ end
34
+
35
+ def test_constructor_with_preferred_host_key_type_should_put_preferred_host_key_type_first
36
+ assert_equal %w(ssh-dss ssh-rsa), algorithms(:host_key => "ssh-dss")[:host_key]
37
+ end
38
+
39
+ def test_constructor_with_known_hosts_reporting_known_host_key_should_use_that_host_key_type
40
+ Net::SSH::KnownHosts.expects(:search_for).with("net.ssh.test,127.0.0.1", {}).returns([stub("key", :ssh_type => "ssh-dss")])
41
+ assert_equal %w(ssh-dss ssh-rsa), algorithms[:host_key]
42
+ end
43
+
44
+ def test_constructor_with_unrecognized_host_key_type_should_raise_exception
45
+ assert_raises(NotImplementedError) { algorithms(:host_key => "bogus") }
46
+ end
47
+
48
+ def test_constructor_with_preferred_kex_should_put_preferred_kex_first
49
+ assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1), algorithms(:kex => "diffie-hellman-group1-sha1")[:kex]
50
+ end
51
+
52
+ def test_constructor_with_unrecognized_kex_should_raise_exception
53
+ assert_raises(NotImplementedError) { algorithms(:kex => "bogus") }
54
+ end
55
+
56
+ def test_constructor_with_preferred_encryption_should_put_preferred_encryption_first
57
+ assert_equal %w(aes256-cbc aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc rijndael-cbc@lysator.liu.se idea-cbc none arcfour128 arcfour256), algorithms(:encryption => "aes256-cbc")[:encryption]
58
+ end
59
+
60
+ def test_constructor_with_multiple_preferred_encryption_should_put_all_preferred_encryption_first
61
+ assert_equal %w(aes256-cbc 3des-cbc idea-cbc aes128-cbc blowfish-cbc cast128-cbc aes192-cbc rijndael-cbc@lysator.liu.se none arcfour128 arcfour256), algorithms(:encryption => %w(aes256-cbc 3des-cbc idea-cbc))[:encryption]
62
+ end
63
+
64
+ def test_constructor_with_unrecognized_encryption_should_raise_exception
65
+ assert_raises(NotImplementedError) { algorithms(:encryption => "bogus") }
66
+ end
67
+
68
+ def test_constructor_with_preferred_hmac_should_put_preferred_hmac_first
69
+ assert_equal %w(hmac-md5-96 hmac-sha1 hmac-md5 hmac-sha1-96 none), algorithms(:hmac => "hmac-md5-96")[:hmac]
70
+ end
71
+
72
+ def test_constructor_with_multiple_preferred_hmac_should_put_all_preferred_hmac_first
73
+ assert_equal %w(hmac-md5-96 hmac-sha1-96 hmac-sha1 hmac-md5 none), algorithms(:hmac => %w(hmac-md5-96 hmac-sha1-96))[:hmac]
74
+ end
75
+
76
+ def test_constructor_with_unrecognized_hmac_should_raise_exception
77
+ assert_raises(NotImplementedError) { algorithms(:hmac => "bogus") }
78
+ end
79
+
80
+ def test_constructor_with_preferred_compression_should_put_preferred_compression_first
81
+ assert_equal %w(zlib none zlib@openssh.com), algorithms(:compression => "zlib")[:compression]
82
+ end
83
+
84
+ def test_constructor_with_multiple_preferred_compression_should_put_all_preferred_compression_first
85
+ assert_equal %w(zlib@openssh.com zlib none), algorithms(:compression => %w(zlib@openssh.com zlib))[:compression]
86
+ end
87
+
88
+ def test_constructor_with_general_preferred_compression_should_put_none_last
89
+ assert_equal %w(zlib@openssh.com zlib none), algorithms(:compression => true)[:compression]
90
+ end
91
+
92
+ def test_constructor_with_unrecognized_compression_should_raise_exception
93
+ assert_raises(NotImplementedError) { algorithms(:compression => "bogus") }
94
+ end
95
+
96
+ def test_initial_state_should_be_neither_pending_nor_initialized
97
+ assert !algorithms.pending?
98
+ assert !algorithms.initialized?
99
+ end
100
+
101
+ def test_key_exchange_when_initiated_by_server
102
+ transport.expect do |t, buffer|
103
+ assert_kexinit(buffer)
104
+ install_mock_key_exchange(buffer)
105
+ end
106
+
107
+ install_mock_algorithm_lookups
108
+ algorithms.accept_kexinit(kexinit)
109
+
110
+ assert_exchange_results
111
+ end
112
+
113
+ def test_key_exchange_when_initiated_by_client
114
+ state = nil
115
+ transport.expect do |t, buffer|
116
+ assert_kexinit(buffer)
117
+ state = :sent_kexinit
118
+ install_mock_key_exchange(buffer)
119
+ end
120
+
121
+ algorithms.rekey!
122
+ assert_equal state, :sent_kexinit
123
+ assert algorithms.pending?
124
+
125
+ install_mock_algorithm_lookups
126
+ algorithms.accept_kexinit(kexinit)
127
+
128
+ assert_exchange_results
129
+ end
130
+
131
+ def test_key_exchange_when_server_does_not_support_preferred_kex_should_fallback_to_secondary
132
+ kexinit :kex => "diffie-hellman-group1-sha1"
133
+ transport.expect do |t,buffer|
134
+ assert_kexinit(buffer)
135
+ install_mock_key_exchange(buffer, :kex => Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1)
136
+ end
137
+ algorithms.accept_kexinit(kexinit)
138
+ end
139
+
140
+ def test_key_exchange_when_server_does_not_support_any_preferred_kex_should_raise_error
141
+ kexinit :kex => "something-obscure"
142
+ transport.expect { |t,buffer| assert_kexinit(buffer) }
143
+ assert_raises(Net::SSH::Exception) { algorithms.accept_kexinit(kexinit) }
144
+ end
145
+
146
+ def test_allow_when_not_pending_should_be_true_for_all_packets
147
+ (0..255).each do |type|
148
+ packet = stub("packet", :type => type)
149
+ assert algorithms.allow?(packet), type
150
+ end
151
+ end
152
+
153
+ def test_allow_when_pending_should_be_true_only_for_packets_valid_during_key_exchange
154
+ transport.expect!
155
+ algorithms.rekey!
156
+ assert algorithms.pending?
157
+
158
+ (0..255).each do |type|
159
+ packet = stub("packet", :type => type)
160
+ case type
161
+ when 1..4, 6..19, 21..49 then assert(algorithms.allow?(packet), "#{type} should be allowed during key exchange")
162
+ else assert(!algorithms.allow?(packet), "#{type} should not be allowed during key exchange")
163
+ end
164
+ end
165
+ end
166
+
167
+ def test_exchange_with_zlib_compression_enabled_sets_compression_to_standard
168
+ algorithms :compression => "zlib"
169
+
170
+ transport.expect do |t, buffer|
171
+ assert_kexinit(buffer, :compression_client => "zlib,none,zlib@openssh.com", :compression_server => "zlib,none,zlib@openssh.com")
172
+ install_mock_key_exchange(buffer)
173
+ end
174
+
175
+ install_mock_algorithm_lookups
176
+ algorithms.accept_kexinit(kexinit)
177
+
178
+ assert_equal :standard, transport.client_options[:compression]
179
+ assert_equal :standard, transport.server_options[:compression]
180
+ end
181
+
182
+ def test_exchange_with_zlib_at_openssh_dot_com_compression_enabled_sets_compression_to_delayed
183
+ algorithms :compression => "zlib@openssh.com"
184
+
185
+ transport.expect do |t, buffer|
186
+ assert_kexinit(buffer, :compression_client => "zlib@openssh.com,none,zlib", :compression_server => "zlib@openssh.com,none,zlib")
187
+ install_mock_key_exchange(buffer)
188
+ end
189
+
190
+ install_mock_algorithm_lookups
191
+ algorithms.accept_kexinit(kexinit)
192
+
193
+ assert_equal :delayed, transport.client_options[:compression]
194
+ assert_equal :delayed, transport.server_options[:compression]
195
+ end
196
+
197
+ private
198
+
199
+ def install_mock_key_exchange(buffer, options={})
200
+ kex = options[:kex] || Net::SSH::Transport::Kex::DiffieHellmanGroupExchangeSHA1
201
+
202
+ Net::SSH::Transport::Kex::MAP.each do |name, klass|
203
+ next if klass == kex
204
+ klass.expects(:new).never
205
+ end
206
+
207
+ kex.expects(:new).
208
+ with(algorithms, transport,
209
+ :client_version_string => Net::SSH::Transport::ServerVersion::PROTO_VERSION,
210
+ :server_version_string => transport.server_version.version,
211
+ :server_algorithm_packet => kexinit.to_s,
212
+ :client_algorithm_packet => buffer.to_s,
213
+ :need_bytes => 20,
214
+ :logger => nil).
215
+ returns(stub("kex", :exchange_keys => { :shared_secret => shared_secret, :session_id => session_id, :hashing_algorithm => hashing_algorithm }))
216
+ end
217
+
218
+ def install_mock_algorithm_lookups(options={})
219
+ Net::SSH::Transport::CipherFactory.expects(:get).
220
+ with(options[:client_cipher] || "aes128-cbc", :iv => key("A"), :key => key("C"), :shared => shared_secret.to_ssh, :hash => session_id, :digester => hashing_algorithm, :encrypt => true).
221
+ returns(:client_cipher)
222
+ Net::SSH::Transport::CipherFactory.expects(:get).
223
+ with(options[:server_cipher] || "aes128-cbc", :iv => key("B"), :key => key("D"), :shared => shared_secret.to_ssh, :hash => session_id, :digester => hashing_algorithm, :decrypt => true).
224
+ returns(:server_cipher)
225
+
226
+ Net::SSH::Transport::HMAC.expects(:get).with(options[:client_hmac] || "hmac-sha1", key("E")).returns(:client_hmac)
227
+ Net::SSH::Transport::HMAC.expects(:get).with(options[:server_hmac] || "hmac-sha1", key("F")).returns(:server_hmac)
228
+ end
229
+
230
+ def shared_secret
231
+ @shared_secret ||= OpenSSL::BN.new("1234567890", 10)
232
+ end
233
+
234
+ def session_id
235
+ @session_id ||= "this is the session id"
236
+ end
237
+
238
+ def hashing_algorithm
239
+ OpenSSL::Digest::SHA1
240
+ end
241
+
242
+ def key(salt)
243
+ hashing_algorithm.digest(shared_secret.to_ssh + session_id + salt + session_id)
244
+ end
245
+
246
+ def cipher(type, options={})
247
+ Net::SSH::Transport::CipherFactory.get(type, options)
248
+ end
249
+
250
+ def kexinit(options={})
251
+ @kexinit ||= P(:byte, KEXINIT,
252
+ :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF),
253
+ :string, options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1",
254
+ :string, options[:host_key] || "ssh-rsa,ssh-dss",
255
+ :string, options[:encryption_client] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
256
+ :string, options[:encryption_server] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
257
+ :string, options[:hmac_client] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96",
258
+ :string, options[:hmac_server] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96",
259
+ :string, options[:compmression_client] || "none,zlib@openssh.com,zlib",
260
+ :string, options[:compmression_server] || "none,zlib@openssh.com,zlib",
261
+ :string, options[:language_client] || "",
262
+ :string, options[:langauge_server] || "",
263
+ :bool, options[:first_kex_follows])
264
+ end
265
+
266
+ def assert_kexinit(buffer, options={})
267
+ assert_equal KEXINIT, buffer.type
268
+ assert_equal 16, buffer.read(16).length
269
+ assert_equal options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1", buffer.read_string
270
+ assert_equal options[:host_key] || "ssh-rsa,ssh-dss", buffer.read_string
271
+ assert_equal options[:encryption_client] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc,none,arcfour128,arcfour256", buffer.read_string
272
+ assert_equal options[:encryption_server] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc,none,arcfour128,arcfour256", buffer.read_string
273
+ assert_equal options[:hmac_client] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96,none", buffer.read_string
274
+ assert_equal options[:hmac_server] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96,none", buffer.read_string
275
+ assert_equal options[:compression_client] || "none,zlib@openssh.com,zlib", buffer.read_string
276
+ assert_equal options[:compression_server] || "none,zlib@openssh.com,zlib", buffer.read_string
277
+ assert_equal options[:language_client] || "", buffer.read_string
278
+ assert_equal options[:language_server] || "", buffer.read_string
279
+ assert_equal options[:first_kex_follows] || false, buffer.read_bool
280
+ end
281
+
282
+ def assert_exchange_results
283
+ assert algorithms.initialized?
284
+ assert !algorithms.pending?
285
+ assert !transport.client_options[:compression]
286
+ assert !transport.server_options[:compression]
287
+ assert_equal :client_cipher, transport.client_options[:cipher]
288
+ assert_equal :server_cipher, transport.server_options[:cipher]
289
+ assert_equal :client_hmac, transport.client_options[:hmac]
290
+ assert_equal :server_hmac, transport.server_options[:hmac]
291
+ end
292
+
293
+ def algorithms(options={})
294
+ @algorithms ||= Net::SSH::Transport::Algorithms.new(transport, options)
295
+ end
296
+
297
+ def transport
298
+ @transport ||= MockTransport.new
299
+ end
300
+ end
301
+
302
+ end
@@ -0,0 +1,171 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/cipher_factory'
3
+
4
+ module Transport
5
+
6
+ class TestCipherFactory < Test::Unit::TestCase
7
+ def self.if_supported?(name)
8
+ yield if Net::SSH::Transport::CipherFactory.supported?(name)
9
+ end
10
+
11
+ def test_lengths_for_none
12
+ assert_equal [0,0], factory.get_lengths("none")
13
+ assert_equal [0,0], factory.get_lengths("bogus")
14
+ end
15
+
16
+ def test_lengths_for_blowfish_cbc
17
+ assert_equal [16,8], factory.get_lengths("blowfish-cbc")
18
+ end
19
+
20
+ if_supported?("idea-cbc") do
21
+ def test_lengths_for_idea_cbc
22
+ assert_equal [16,8], factory.get_lengths("idea-cbc")
23
+ end
24
+ end
25
+
26
+ def test_lengths_for_rijndael_cbc
27
+ assert_equal [32,16], factory.get_lengths("rijndael-cbc@lysator.liu.se")
28
+ end
29
+
30
+ def test_lengths_for_cast128_cbc
31
+ assert_equal [16,8], factory.get_lengths("cast128-cbc")
32
+ end
33
+
34
+ def test_lengths_for_3des_cbc
35
+ assert_equal [24,8], factory.get_lengths("3des-cbc")
36
+ end
37
+
38
+ def test_lengths_for_aes192_cbc
39
+ assert_equal [24,16], factory.get_lengths("aes192-cbc")
40
+ end
41
+
42
+ def test_lengths_for_aes128_cbc
43
+ assert_equal [16,16], factory.get_lengths("aes128-cbc")
44
+ end
45
+
46
+ def test_lengths_for_aes256_cbc
47
+ assert_equal [32,16], factory.get_lengths("aes256-cbc")
48
+ end
49
+
50
+ BLOWFISH = "\210\021\200\315\240_\026$\352\204g\233\244\242x\332e\370\001\327\224Nv@9_\323\037\252kb\037\036\237\375]\343/y\037\237\312Q\f7]\347Y\005\275%\377\0010$G\272\250B\265Nd\375\342\372\025r6}+Y\213y\n\237\267\\\374^\346BdJ$\353\220Ik\023<\236&H\277=\225"
51
+
52
+ def test_blowfish_cbc_for_encryption
53
+ assert_equal BLOWFISH, encrypt("blowfish-cbc")
54
+ end
55
+
56
+ def test_blowfish_cbc_for_decryption
57
+ assert_equal TEXT, decrypt("blowfish-cbc", BLOWFISH)
58
+ end
59
+
60
+ if_supported?("idea-cbc") do
61
+ IDEA = "W\234\017G\231\b\357\370H\b\256U]\343M\031k\233]~\023C\363\263\177\262-\261\341$\022\376mv\217\322\b\2763\270H\306\035\343z\313\312\3531\351\t\201\302U\022\360\300\354ul7$z\320O]\360g\024\305\005`V\005\335A\351\312\270c\320D\232\eQH1\340\265\2118\031g*\303v"
62
+
63
+ def test_idea_cbc_for_encryption
64
+ assert_equal IDEA, encrypt("idea-cbc")
65
+ end
66
+
67
+ def test_idea_cbc_for_decryption
68
+ assert_equal TEXT, decrypt("idea-cbc", IDEA)
69
+ end
70
+ end
71
+
72
+ RIJNDAEL = "$\253\271\255\005Z\354\336&\312\324\221\233\307Mj\315\360\310Fk\241EfN\037\231\213\361{'\310\204\347I\343\271\005\240`\325;\034\346uM>#\241\231C`\374\261\vo\226;Z\302:\b\250\366T\330\\#V\330\340\226\363\374!\bm\266\232\207!\232\347\340\t\307\370\356z\236\343=v\210\206y"
73
+
74
+ def test_rijndael_cbc_for_encryption
75
+ assert_equal RIJNDAEL, encrypt("rijndael-cbc@lysator.liu.se")
76
+ end
77
+
78
+ def test_rijndael_cbc_for_decryption
79
+ assert_equal TEXT, decrypt("rijndael-cbc@lysator.liu.se", RIJNDAEL)
80
+ end
81
+
82
+ CAST128 = "qW\302\331\333P\223t[9 ~(sg\322\271\227\272\022I\223\373p\255>k\326\314\260\2003\236C_W\211\227\373\205>\351\334\322\227\223\e\236\202Ii\032!P\214\035:\017\360h7D\371v\210\264\317\236a\262w1\2772\023\036\331\227\240:\f/X\351\324I\t[x\350\323E\2301\016m"
83
+
84
+ def test_cast128_cbc_for_encryption
85
+ assert_equal CAST128, encrypt("cast128-cbc")
86
+ end
87
+
88
+ def test_cast128_cbc_for_decryption
89
+ assert_equal TEXT, decrypt("cast128-cbc", CAST128)
90
+ end
91
+
92
+ TRIPLE_DES = "\322\252\216D\303Q\375gg\367A{\177\313\3436\272\353%\223K?\257\206|\r&\353/%\340\336 \203E8rY\206\234\004\274\267\031\233T/{\"\227/B!i?[qGaw\306T\206\223\213n \212\032\244%]@\355\250\334\312\265E\251\017\361\270\357\230\274KP&^\031r+r%\370"
93
+
94
+ def test_3des_cbc_for_encryption
95
+ assert_equal TRIPLE_DES, encrypt("3des-cbc")
96
+ end
97
+
98
+ def test_3des_cbc_for_decryption
99
+ assert_equal TEXT, decrypt("3des-cbc", TRIPLE_DES)
100
+ end
101
+
102
+ AES128 = "k\026\350B\366-k\224\313\3277}B\035\004\200\035\r\233\024$\205\261\231Q\2214r\245\250\360\315\237\266hg\262C&+\321\346Pf\267v\376I\215P\327\345-\232&HK\375\326_\030<\a\276\212\303g\342C\242O\233\260\006\001a&V\345`\\T\e\236.\207\223l\233ri^\v\252\363\245"
103
+
104
+ def test_aes128_cbc_for_encryption
105
+ assert_equal AES128, encrypt("aes128-cbc")
106
+ end
107
+
108
+ def test_aes128_cbc_for_decryption
109
+ assert_equal TEXT, decrypt("aes128-cbc", AES128)
110
+ end
111
+
112
+ AES192 = "\256\017)x\270\213\336\303L\003f\235'jQ\3231k9\225\267\242\364C4\370\224\201\302~\217I\202\374\2167='\272\037\225\223\177Y\r\212\376(\275\n\3553\377\177\252C\254\236\016MA\274Z@H\331<\rL\317\205\323[\305X8\376\237=\374\352bH9\244\0231\353\204\352p\226\326~J\242"
113
+
114
+ def test_aes192_cbc_for_encryption
115
+ assert_equal AES192, encrypt("aes192-cbc")
116
+ end
117
+
118
+ def test_aes192_cbc_for_decryption
119
+ assert_equal TEXT, decrypt("aes192-cbc", AES192)
120
+ end
121
+
122
+ AES256 = "$\253\271\255\005Z\354\336&\312\324\221\233\307Mj\315\360\310Fk\241EfN\037\231\213\361{'\310\204\347I\343\271\005\240`\325;\034\346uM>#\241\231C`\374\261\vo\226;Z\302:\b\250\366T\330\\#V\330\340\226\363\374!\bm\266\232\207!\232\347\340\t\307\370\356z\236\343=v\210\206y"
123
+
124
+ def test_aes256_cbc_for_encryption
125
+ assert_equal AES256, encrypt("aes256-cbc")
126
+ end
127
+
128
+ def test_aes256_cbc_for_decryption
129
+ assert_equal TEXT, decrypt("aes256-cbc", AES256)
130
+ end
131
+
132
+ def test_none_for_encryption
133
+ assert_equal TEXT, encrypt("none").strip
134
+ end
135
+
136
+ def test_none_for_decryption
137
+ assert_equal TEXT, decrypt("none", TEXT)
138
+ end
139
+
140
+ private
141
+
142
+ TEXT = "But soft! What light through yonder window breaks? It is the east, and Juliet is the sun!"
143
+
144
+ OPTIONS = { :iv => "ABC",
145
+ :key => "abc",
146
+ :digester => OpenSSL::Digest::MD5,
147
+ :shared => "1234567890123456780",
148
+ :hash => '!@#$%#$^%$&^&%#$@$'
149
+ }
150
+
151
+ def factory
152
+ Net::SSH::Transport::CipherFactory
153
+ end
154
+
155
+ def encrypt(type)
156
+ cipher = factory.get(type, OPTIONS.merge(:encrypt => true))
157
+ padding = TEXT.length % cipher.block_size
158
+ result = cipher.update(TEXT.dup)
159
+ result << cipher.update(" " * (cipher.block_size - padding)) if padding > 0
160
+ result << cipher.final
161
+ end
162
+
163
+ def decrypt(type, data)
164
+ cipher = factory.get(type, OPTIONS.merge(:decrypt => true))
165
+ result = cipher.update(data.dup)
166
+ result << cipher.final
167
+ result.strip
168
+ end
169
+ end
170
+
171
+ end