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,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), 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), 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), 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", 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", 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,163 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/cipher_factory'
3
+
4
+ module Transport
5
+
6
+ class TestCipherFactory < Test::Unit::TestCase
7
+ def test_lengths_for_none
8
+ assert_equal [0,0], factory.get_lengths("none")
9
+ assert_equal [0,0], factory.get_lengths("bogus")
10
+ end
11
+
12
+ def test_lengths_for_blowfish_cbc
13
+ assert_equal [16,8], factory.get_lengths("blowfish-cbc")
14
+ end
15
+
16
+ def test_lengths_for_idea_cbc
17
+ assert_equal [16,8], factory.get_lengths("idea-cbc")
18
+ end
19
+
20
+ def test_lengths_for_rijndael_cbc
21
+ assert_equal [32,16], factory.get_lengths("rijndael-cbc@lysator.liu.se")
22
+ end
23
+
24
+ def test_lengths_for_cast128_cbc
25
+ assert_equal [16,8], factory.get_lengths("cast128-cbc")
26
+ end
27
+
28
+ def test_lengths_for_3des_cbc
29
+ assert_equal [24,8], factory.get_lengths("3des-cbc")
30
+ end
31
+
32
+ def test_lengths_for_aes192_cbc
33
+ assert_equal [24,16], factory.get_lengths("aes192-cbc")
34
+ end
35
+
36
+ def test_lengths_for_aes128_cbc
37
+ assert_equal [16,16], factory.get_lengths("aes128-cbc")
38
+ end
39
+
40
+ def test_lengths_for_aes256_cbc
41
+ assert_equal [32,16], factory.get_lengths("aes256-cbc")
42
+ end
43
+
44
+ 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"
45
+
46
+ def test_blowfish_cbc_for_encryption
47
+ assert_equal BLOWFISH, encrypt("blowfish-cbc")
48
+ end
49
+
50
+ def test_blowfish_cbc_for_decryption
51
+ assert_equal TEXT, decrypt("blowfish-cbc", BLOWFISH)
52
+ end
53
+
54
+ 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"
55
+
56
+ def test_idea_cbc_for_encryption
57
+ assert_equal IDEA, encrypt("idea-cbc")
58
+ end
59
+
60
+ def test_idea_cbc_for_decryption
61
+ assert_equal TEXT, decrypt("idea-cbc", IDEA)
62
+ end
63
+
64
+ 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"
65
+
66
+ def test_rijndael_cbc_for_encryption
67
+ assert_equal RIJNDAEL, encrypt("rijndael-cbc@lysator.liu.se")
68
+ end
69
+
70
+ def test_rijndael_cbc_for_decryption
71
+ assert_equal TEXT, decrypt("rijndael-cbc@lysator.liu.se", RIJNDAEL)
72
+ end
73
+
74
+ 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"
75
+
76
+ def test_cast128_cbc_for_encryption
77
+ assert_equal CAST128, encrypt("cast128-cbc")
78
+ end
79
+
80
+ def test_cast128_cbc_for_decryption
81
+ assert_equal TEXT, decrypt("cast128-cbc", CAST128)
82
+ end
83
+
84
+ 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"
85
+
86
+ def test_3des_cbc_for_encryption
87
+ assert_equal TRIPLE_DES, encrypt("3des-cbc")
88
+ end
89
+
90
+ def test_3des_cbc_for_decryption
91
+ assert_equal TEXT, decrypt("3des-cbc", TRIPLE_DES)
92
+ end
93
+
94
+ 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"
95
+
96
+ def test_aes128_cbc_for_encryption
97
+ assert_equal AES128, encrypt("aes128-cbc")
98
+ end
99
+
100
+ def test_aes128_cbc_for_decryption
101
+ assert_equal TEXT, decrypt("aes128-cbc", AES128)
102
+ end
103
+
104
+ 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"
105
+
106
+ def test_aes192_cbc_for_encryption
107
+ assert_equal AES192, encrypt("aes192-cbc")
108
+ end
109
+
110
+ def test_aes192_cbc_for_decryption
111
+ assert_equal TEXT, decrypt("aes192-cbc", AES192)
112
+ end
113
+
114
+ 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"
115
+
116
+ def test_aes256_cbc_for_encryption
117
+ assert_equal AES256, encrypt("aes256-cbc")
118
+ end
119
+
120
+ def test_aes256_cbc_for_decryption
121
+ assert_equal TEXT, decrypt("aes256-cbc", AES256)
122
+ end
123
+
124
+ def test_none_for_encryption
125
+ assert_equal TEXT, encrypt("none").strip
126
+ end
127
+
128
+ def test_none_for_decryption
129
+ assert_equal TEXT, decrypt("none", TEXT)
130
+ end
131
+
132
+ private
133
+
134
+ TEXT = "But soft! What light through yonder window breaks? It is the east, and Juliet is the sun!"
135
+
136
+ OPTIONS = { :iv => "ABC",
137
+ :key => "abc",
138
+ :digester => OpenSSL::Digest::MD5,
139
+ :shared => "1234567890123456780",
140
+ :hash => '!@#$%#$^%$&^&%#$@$'
141
+ }
142
+
143
+ def factory
144
+ Net::SSH::Transport::CipherFactory
145
+ end
146
+
147
+ def encrypt(type)
148
+ cipher = factory.get(type, OPTIONS.merge(:encrypt => true))
149
+ padding = TEXT.length % cipher.block_size
150
+ result = cipher.update(TEXT.dup)
151
+ result << cipher.update(" " * (cipher.block_size - padding)) if padding > 0
152
+ result << cipher.final
153
+ end
154
+
155
+ def decrypt(type, data)
156
+ cipher = factory.get(type, OPTIONS.merge(:decrypt => true))
157
+ result = cipher.update(data.dup)
158
+ result << cipher.final
159
+ result.strip
160
+ end
161
+ end
162
+
163
+ end