minmb-net-ssh 2.5.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 (137) hide show
  1. data/CHANGELOG.rdoc +291 -0
  2. data/Manifest +132 -0
  3. data/README.rdoc +184 -0
  4. data/Rakefile +86 -0
  5. data/Rudyfile +96 -0
  6. data/THANKS.rdoc +19 -0
  7. data/lib/net/ssh.rb +223 -0
  8. data/lib/net/ssh/authentication/agent.rb +23 -0
  9. data/lib/net/ssh/authentication/agent/java_pageant.rb +85 -0
  10. data/lib/net/ssh/authentication/agent/socket.rb +170 -0
  11. data/lib/net/ssh/authentication/constants.rb +18 -0
  12. data/lib/net/ssh/authentication/key_manager.rb +253 -0
  13. data/lib/net/ssh/authentication/methods/abstract.rb +60 -0
  14. data/lib/net/ssh/authentication/methods/hostbased.rb +75 -0
  15. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +70 -0
  16. data/lib/net/ssh/authentication/methods/password.rb +43 -0
  17. data/lib/net/ssh/authentication/methods/publickey.rb +96 -0
  18. data/lib/net/ssh/authentication/pageant.rb +301 -0
  19. data/lib/net/ssh/authentication/session.rb +154 -0
  20. data/lib/net/ssh/buffer.rb +350 -0
  21. data/lib/net/ssh/buffered_io.rb +207 -0
  22. data/lib/net/ssh/config.rb +207 -0
  23. data/lib/net/ssh/connection/channel.rb +630 -0
  24. data/lib/net/ssh/connection/constants.rb +33 -0
  25. data/lib/net/ssh/connection/session.rb +603 -0
  26. data/lib/net/ssh/connection/term.rb +178 -0
  27. data/lib/net/ssh/errors.rb +88 -0
  28. data/lib/net/ssh/key_factory.rb +107 -0
  29. data/lib/net/ssh/known_hosts.rb +141 -0
  30. data/lib/net/ssh/loggable.rb +61 -0
  31. data/lib/net/ssh/packet.rb +102 -0
  32. data/lib/net/ssh/prompt.rb +93 -0
  33. data/lib/net/ssh/proxy/command.rb +75 -0
  34. data/lib/net/ssh/proxy/errors.rb +14 -0
  35. data/lib/net/ssh/proxy/http.rb +94 -0
  36. data/lib/net/ssh/proxy/socks4.rb +70 -0
  37. data/lib/net/ssh/proxy/socks5.rb +142 -0
  38. data/lib/net/ssh/ruby_compat.rb +77 -0
  39. data/lib/net/ssh/service/forward.rb +327 -0
  40. data/lib/net/ssh/test.rb +89 -0
  41. data/lib/net/ssh/test/channel.rb +129 -0
  42. data/lib/net/ssh/test/extensions.rb +152 -0
  43. data/lib/net/ssh/test/kex.rb +44 -0
  44. data/lib/net/ssh/test/local_packet.rb +51 -0
  45. data/lib/net/ssh/test/packet.rb +81 -0
  46. data/lib/net/ssh/test/remote_packet.rb +38 -0
  47. data/lib/net/ssh/test/script.rb +157 -0
  48. data/lib/net/ssh/test/socket.rb +64 -0
  49. data/lib/net/ssh/transport/algorithms.rb +407 -0
  50. data/lib/net/ssh/transport/cipher_factory.rb +106 -0
  51. data/lib/net/ssh/transport/constants.rb +32 -0
  52. data/lib/net/ssh/transport/ctr.rb +95 -0
  53. data/lib/net/ssh/transport/hmac.rb +45 -0
  54. data/lib/net/ssh/transport/hmac/abstract.rb +79 -0
  55. data/lib/net/ssh/transport/hmac/md5.rb +12 -0
  56. data/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  57. data/lib/net/ssh/transport/hmac/none.rb +15 -0
  58. data/lib/net/ssh/transport/hmac/ripemd160.rb +13 -0
  59. data/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  60. data/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  61. data/lib/net/ssh/transport/hmac/sha2_256.rb +15 -0
  62. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +13 -0
  63. data/lib/net/ssh/transport/hmac/sha2_512.rb +14 -0
  64. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +13 -0
  65. data/lib/net/ssh/transport/identity_cipher.rb +55 -0
  66. data/lib/net/ssh/transport/kex.rb +28 -0
  67. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +44 -0
  68. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +216 -0
  69. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +80 -0
  70. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +15 -0
  71. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +93 -0
  72. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +13 -0
  73. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +13 -0
  74. data/lib/net/ssh/transport/key_expander.rb +26 -0
  75. data/lib/net/ssh/transport/openssl.rb +237 -0
  76. data/lib/net/ssh/transport/packet_stream.rb +235 -0
  77. data/lib/net/ssh/transport/server_version.rb +71 -0
  78. data/lib/net/ssh/transport/session.rb +278 -0
  79. data/lib/net/ssh/transport/state.rb +206 -0
  80. data/lib/net/ssh/verifiers/lenient.rb +30 -0
  81. data/lib/net/ssh/verifiers/null.rb +12 -0
  82. data/lib/net/ssh/verifiers/strict.rb +53 -0
  83. data/lib/net/ssh/version.rb +62 -0
  84. data/net-ssh.gemspec +164 -0
  85. data/setup.rb +1585 -0
  86. data/support/arcfour_check.rb +20 -0
  87. data/support/ssh_tunnel_bug.rb +65 -0
  88. data/test/authentication/methods/common.rb +28 -0
  89. data/test/authentication/methods/test_abstract.rb +51 -0
  90. data/test/authentication/methods/test_hostbased.rb +114 -0
  91. data/test/authentication/methods/test_keyboard_interactive.rb +100 -0
  92. data/test/authentication/methods/test_password.rb +52 -0
  93. data/test/authentication/methods/test_publickey.rb +148 -0
  94. data/test/authentication/test_agent.rb +205 -0
  95. data/test/authentication/test_key_manager.rb +218 -0
  96. data/test/authentication/test_session.rb +106 -0
  97. data/test/common.rb +107 -0
  98. data/test/configs/eqsign +3 -0
  99. data/test/configs/exact_match +8 -0
  100. data/test/configs/host_plus +10 -0
  101. data/test/configs/multihost +4 -0
  102. data/test/configs/wild_cards +14 -0
  103. data/test/connection/test_channel.rb +467 -0
  104. data/test/connection/test_session.rb +488 -0
  105. data/test/known_hosts/github +1 -0
  106. data/test/test_all.rb +9 -0
  107. data/test/test_buffer.rb +426 -0
  108. data/test/test_buffered_io.rb +63 -0
  109. data/test/test_config.rb +120 -0
  110. data/test/test_key_factory.rb +121 -0
  111. data/test/test_known_hosts.rb +13 -0
  112. data/test/transport/hmac/test_md5.rb +39 -0
  113. data/test/transport/hmac/test_md5_96.rb +25 -0
  114. data/test/transport/hmac/test_none.rb +34 -0
  115. data/test/transport/hmac/test_ripemd160.rb +34 -0
  116. data/test/transport/hmac/test_sha1.rb +34 -0
  117. data/test/transport/hmac/test_sha1_96.rb +25 -0
  118. data/test/transport/hmac/test_sha2_256.rb +35 -0
  119. data/test/transport/hmac/test_sha2_256_96.rb +25 -0
  120. data/test/transport/hmac/test_sha2_512.rb +35 -0
  121. data/test/transport/hmac/test_sha2_512_96.rb +25 -0
  122. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +13 -0
  123. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  124. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  125. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +33 -0
  126. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +161 -0
  127. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +37 -0
  128. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +37 -0
  129. data/test/transport/test_algorithms.rb +330 -0
  130. data/test/transport/test_cipher_factory.rb +441 -0
  131. data/test/transport/test_hmac.rb +34 -0
  132. data/test/transport/test_identity_cipher.rb +40 -0
  133. data/test/transport/test_packet_stream.rb +1745 -0
  134. data/test/transport/test_server_version.rb +78 -0
  135. data/test/transport/test_session.rb +315 -0
  136. data/test/transport/test_state.rb +179 -0
  137. metadata +208 -0
@@ -0,0 +1,37 @@
1
+ require 'openssl'
2
+
3
+ unless defined?(OpenSSL::PKey::EC)
4
+ puts "Skipping tests for ecdh-sha2-nistp384 key exchange"
5
+ else
6
+ module Transport; module Kex
7
+ class TestEcdhSHA2NistP384 < TestEcdhSHA2NistP256
8
+
9
+ def setup
10
+ @ecdh = @algorithms = @connection = @server_key =
11
+ @packet_data = @shared_secret = nil
12
+ end
13
+
14
+ def test_exchange_keys_should_return_expected_results_when_successful
15
+ result = exchange!
16
+ assert_equal session_id, result[:session_id]
17
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
18
+ assert_equal shared_secret, result[:shared_secret]
19
+ assert_equal digester, result[:hashing_algorithm]
20
+ end
21
+
22
+ private
23
+
24
+ def digester
25
+ OpenSSL::Digest::SHA384
26
+ end
27
+
28
+ def subject
29
+ Net::SSH::Transport::Kex::EcdhSHA2NistP384
30
+ end
31
+
32
+ def ecparam
33
+ "secp384r1"
34
+ end
35
+ end
36
+ end; end
37
+ end
@@ -0,0 +1,37 @@
1
+ require 'openssl'
2
+
3
+ unless defined?(OpenSSL::PKey::EC)
4
+ puts "Skipping tests for ecdh-sha2-nistp521 key exchange"
5
+ else
6
+ module Transport; module Kex
7
+ class TestEcdhSHA2NistP521 < TestEcdhSHA2NistP256
8
+
9
+ def setup
10
+ @ecdh = @algorithms = @connection = @server_key =
11
+ @packet_data = @shared_secret = nil
12
+ end
13
+
14
+ def test_exchange_keys_should_return_expected_results_when_successful
15
+ result = exchange!
16
+ assert_equal session_id, result[:session_id]
17
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
18
+ assert_equal shared_secret, result[:shared_secret]
19
+ assert_equal digester, result[:hashing_algorithm]
20
+ end
21
+
22
+ private
23
+
24
+ def digester
25
+ OpenSSL::Digest::SHA512
26
+ end
27
+
28
+ def subject
29
+ Net::SSH::Transport::Kex::EcdhSHA2NistP521
30
+ end
31
+
32
+ def ecparam
33
+ "secp521r1"
34
+ end
35
+ end
36
+ end; end
37
+ end
@@ -0,0 +1,330 @@
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
+ if defined?(OpenSSL::PKey::EC)
21
+ assert_equal %w(ssh-rsa ssh-dss ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521), algorithms[:host_key]
22
+ assert_equal %w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521), algorithms[:kex]
23
+ else
24
+ assert_equal %w(ssh-rsa ssh-dss), algorithms[:host_key]
25
+ assert_equal %w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256), algorithms[:kex]
26
+ end
27
+ 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 arcfour aes128-ctr aes192-ctr aes256-ctr camellia128-cbc camellia192-cbc camellia256-cbc camellia128-cbc@openssh.org camellia192-cbc@openssh.org camellia256-cbc@openssh.org camellia128-ctr camellia192-ctr camellia256-ctr camellia128-ctr@openssh.org camellia192-ctr@openssh.org camellia256-ctr@openssh.org cast128-ctr blowfish-ctr 3des-ctr), algorithms[:encryption]
28
+ if defined?(OpenSSL::Digest::SHA256)
29
+ assert_equal %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 hmac-ripemd160 hmac-ripemd160@openssh.com hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms[:hmac]
30
+ else
31
+ assert_equal %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 hmac-ripemd160 hmac-ripemd160@openssh.com none), algorithms[:hmac]
32
+ end
33
+ assert_equal %w(none zlib@openssh.com zlib), algorithms[:compression]
34
+ assert_equal %w(), algorithms[:language]
35
+ end
36
+
37
+ def test_constructor_should_set_client_and_server_prefs_identically
38
+ %w(encryption hmac compression language).each do |key|
39
+ assert_equal algorithms[key.to_sym], algorithms[:"#{key}_client"], key
40
+ assert_equal algorithms[key.to_sym], algorithms[:"#{key}_server"], key
41
+ end
42
+ end
43
+
44
+ def test_constructor_with_preferred_host_key_type_should_put_preferred_host_key_type_first
45
+ if defined?(OpenSSL::PKey::EC)
46
+ assert_equal %w(ssh-dss ssh-rsa ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521), algorithms(:host_key => "ssh-dss")[:host_key]
47
+ else
48
+ assert_equal %w(ssh-dss ssh-rsa), algorithms(:host_key => "ssh-dss")[:host_key]
49
+ end
50
+ end
51
+
52
+ def test_constructor_with_known_hosts_reporting_known_host_key_should_use_that_host_key_type
53
+ Net::SSH::KnownHosts.expects(:search_for).with("net.ssh.test,127.0.0.1", {}).returns([stub("key", :ssh_type => "ssh-dss")])
54
+ if defined?(OpenSSL::PKey::EC)
55
+ assert_equal %w(ssh-dss ssh-rsa ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521), algorithms[:host_key]
56
+ else
57
+ assert_equal %w(ssh-dss ssh-rsa), algorithms[:host_key]
58
+ end
59
+ end
60
+
61
+ def test_constructor_with_unrecognized_host_key_type_should_raise_exception
62
+ assert_raises(NotImplementedError) { algorithms(:host_key => "bogus") }
63
+ end
64
+
65
+ def test_constructor_with_preferred_kex_should_put_preferred_kex_first
66
+ if defined?(OpenSSL::PKey::EC)
67
+ assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521), algorithms(:kex => "diffie-hellman-group1-sha1")[:kex]
68
+ else
69
+ assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256), algorithms(:kex => "diffie-hellman-group1-sha1")[:kex]
70
+ end
71
+ end
72
+
73
+ def test_constructor_with_unrecognized_kex_should_raise_exception
74
+ assert_raises(NotImplementedError) { algorithms(:kex => "bogus") }
75
+ end
76
+
77
+ def test_constructor_with_preferred_encryption_should_put_preferred_encryption_first
78
+ 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 arcfour aes128-ctr aes192-ctr aes256-ctr camellia128-cbc camellia192-cbc camellia256-cbc camellia128-cbc@openssh.org camellia192-cbc@openssh.org camellia256-cbc@openssh.org camellia128-ctr camellia192-ctr camellia256-ctr camellia128-ctr@openssh.org camellia192-ctr@openssh.org camellia256-ctr@openssh.org cast128-ctr blowfish-ctr 3des-ctr), algorithms(:encryption => "aes256-cbc")[:encryption]
79
+ end
80
+
81
+ def test_constructor_with_multiple_preferred_encryption_should_put_all_preferred_encryption_first
82
+ 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 arcfour aes128-ctr aes192-ctr aes256-ctr camellia128-cbc camellia192-cbc camellia256-cbc camellia128-cbc@openssh.org camellia192-cbc@openssh.org camellia256-cbc@openssh.org camellia128-ctr camellia192-ctr camellia256-ctr camellia128-ctr@openssh.org camellia192-ctr@openssh.org camellia256-ctr@openssh.org cast128-ctr blowfish-ctr 3des-ctr), algorithms(:encryption => %w(aes256-cbc 3des-cbc idea-cbc))[:encryption]
83
+ end
84
+
85
+ def test_constructor_with_unrecognized_encryption_should_raise_exception
86
+ assert_raises(NotImplementedError) { algorithms(:encryption => "bogus") }
87
+ end
88
+
89
+ def test_constructor_with_preferred_hmac_should_put_preferred_hmac_first
90
+ assert_equal %w(hmac-md5-96 hmac-sha1 hmac-md5 hmac-sha1-96 hmac-ripemd160 hmac-ripemd160@openssh.com hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms(:hmac => "hmac-md5-96")[:hmac]
91
+ end
92
+
93
+ def test_constructor_with_multiple_preferred_hmac_should_put_all_preferred_hmac_first
94
+ assert_equal %w(hmac-md5-96 hmac-sha1-96 hmac-sha1 hmac-md5 hmac-ripemd160 hmac-ripemd160@openssh.com hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms(:hmac => %w(hmac-md5-96 hmac-sha1-96))[:hmac]
95
+ end
96
+
97
+ def test_constructor_with_unrecognized_hmac_should_raise_exception
98
+ assert_raises(NotImplementedError) { algorithms(:hmac => "bogus") }
99
+ end
100
+
101
+ def test_constructor_with_preferred_compression_should_put_preferred_compression_first
102
+ assert_equal %w(zlib none zlib@openssh.com), algorithms(:compression => "zlib")[:compression]
103
+ end
104
+
105
+ def test_constructor_with_multiple_preferred_compression_should_put_all_preferred_compression_first
106
+ assert_equal %w(zlib@openssh.com zlib none), algorithms(:compression => %w(zlib@openssh.com zlib))[:compression]
107
+ end
108
+
109
+ def test_constructor_with_general_preferred_compression_should_put_none_last
110
+ assert_equal %w(zlib@openssh.com zlib none), algorithms(:compression => true)[:compression]
111
+ end
112
+
113
+ def test_constructor_with_unrecognized_compression_should_raise_exception
114
+ assert_raises(NotImplementedError) { algorithms(:compression => "bogus") }
115
+ end
116
+
117
+ def test_initial_state_should_be_neither_pending_nor_initialized
118
+ assert !algorithms.pending?
119
+ assert !algorithms.initialized?
120
+ end
121
+
122
+ def test_key_exchange_when_initiated_by_server
123
+ transport.expect do |t, buffer|
124
+ assert_kexinit(buffer)
125
+ install_mock_key_exchange(buffer)
126
+ end
127
+
128
+ install_mock_algorithm_lookups
129
+ algorithms.accept_kexinit(kexinit)
130
+
131
+ assert_exchange_results
132
+ end
133
+
134
+ def test_key_exchange_when_initiated_by_client
135
+ state = nil
136
+ transport.expect do |t, buffer|
137
+ assert_kexinit(buffer)
138
+ state = :sent_kexinit
139
+ install_mock_key_exchange(buffer)
140
+ end
141
+
142
+ algorithms.rekey!
143
+ assert_equal state, :sent_kexinit
144
+ assert algorithms.pending?
145
+
146
+ install_mock_algorithm_lookups
147
+ algorithms.accept_kexinit(kexinit)
148
+
149
+ assert_exchange_results
150
+ end
151
+
152
+ def test_key_exchange_when_server_does_not_support_preferred_kex_should_fallback_to_secondary
153
+ kexinit :kex => "diffie-hellman-group1-sha1"
154
+ transport.expect do |t,buffer|
155
+ assert_kexinit(buffer)
156
+ install_mock_key_exchange(buffer, :kex => Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1)
157
+ end
158
+ algorithms.accept_kexinit(kexinit)
159
+ end
160
+
161
+ def test_key_exchange_when_server_does_not_support_any_preferred_kex_should_raise_error
162
+ kexinit :kex => "something-obscure"
163
+ transport.expect { |t,buffer| assert_kexinit(buffer) }
164
+ assert_raises(Net::SSH::Exception) { algorithms.accept_kexinit(kexinit) }
165
+ end
166
+
167
+ def test_allow_when_not_pending_should_be_true_for_all_packets
168
+ (0..255).each do |type|
169
+ packet = stub("packet", :type => type)
170
+ assert algorithms.allow?(packet), type.to_s
171
+ end
172
+ end
173
+
174
+ def test_allow_when_pending_should_be_true_only_for_packets_valid_during_key_exchange
175
+ transport.expect!
176
+ algorithms.rekey!
177
+ assert algorithms.pending?
178
+
179
+ (0..255).each do |type|
180
+ packet = stub("packet", :type => type)
181
+ case type
182
+ when 1..4, 6..19, 21..49 then assert(algorithms.allow?(packet), "#{type} should be allowed during key exchange")
183
+ else assert(!algorithms.allow?(packet), "#{type} should not be allowed during key exchange")
184
+ end
185
+ end
186
+ end
187
+
188
+ def test_exchange_with_zlib_compression_enabled_sets_compression_to_standard
189
+ algorithms :compression => "zlib"
190
+
191
+ transport.expect do |t, buffer|
192
+ assert_kexinit(buffer, :compression_client => "zlib,none,zlib@openssh.com", :compression_server => "zlib,none,zlib@openssh.com")
193
+ install_mock_key_exchange(buffer)
194
+ end
195
+
196
+ install_mock_algorithm_lookups
197
+ algorithms.accept_kexinit(kexinit)
198
+
199
+ assert_equal :standard, transport.client_options[:compression]
200
+ assert_equal :standard, transport.server_options[:compression]
201
+ end
202
+
203
+ def test_exchange_with_zlib_at_openssh_dot_com_compression_enabled_sets_compression_to_delayed
204
+ algorithms :compression => "zlib@openssh.com"
205
+
206
+ transport.expect do |t, buffer|
207
+ assert_kexinit(buffer, :compression_client => "zlib@openssh.com,none,zlib", :compression_server => "zlib@openssh.com,none,zlib")
208
+ install_mock_key_exchange(buffer)
209
+ end
210
+
211
+ install_mock_algorithm_lookups
212
+ algorithms.accept_kexinit(kexinit)
213
+
214
+ assert_equal :delayed, transport.client_options[:compression]
215
+ assert_equal :delayed, transport.server_options[:compression]
216
+ end
217
+
218
+ private
219
+
220
+ def install_mock_key_exchange(buffer, options={})
221
+ kex = options[:kex] || Net::SSH::Transport::Kex::DiffieHellmanGroupExchangeSHA1
222
+
223
+ Net::SSH::Transport::Kex::MAP.each do |name, klass|
224
+ next if klass == kex
225
+ klass.expects(:new).never
226
+ end
227
+
228
+ kex.expects(:new).
229
+ with(algorithms, transport,
230
+ :client_version_string => Net::SSH::Transport::ServerVersion::PROTO_VERSION,
231
+ :server_version_string => transport.server_version.version,
232
+ :server_algorithm_packet => kexinit.to_s,
233
+ :client_algorithm_packet => buffer.to_s,
234
+ :need_bytes => 20,
235
+ :logger => nil).
236
+ returns(stub("kex", :exchange_keys => { :shared_secret => shared_secret, :session_id => session_id, :hashing_algorithm => hashing_algorithm }))
237
+ end
238
+
239
+ def install_mock_algorithm_lookups(options={})
240
+ params = { :shared => shared_secret.to_ssh, :hash => session_id, :digester => hashing_algorithm }
241
+ Net::SSH::Transport::CipherFactory.expects(:get).
242
+ with(options[:client_cipher] || "aes128-cbc", params.merge(:iv => key("A"), :key => key("C"), :encrypt => true)).
243
+ returns(:client_cipher)
244
+
245
+ Net::SSH::Transport::CipherFactory.expects(:get).
246
+ with(options[:server_cipher] || "aes128-cbc", params.merge(:iv => key("B"), :key => key("D"), :decrypt => true)).
247
+ returns(:server_cipher)
248
+
249
+ Net::SSH::Transport::HMAC.expects(:get).with(options[:client_hmac] || "hmac-sha1", key("E"), params).returns(:client_hmac)
250
+ Net::SSH::Transport::HMAC.expects(:get).with(options[:server_hmac] || "hmac-sha1", key("F"), params).returns(:server_hmac)
251
+ end
252
+
253
+ def shared_secret
254
+ @shared_secret ||= OpenSSL::BN.new("1234567890", 10)
255
+ end
256
+
257
+ def session_id
258
+ @session_id ||= "this is the session id"
259
+ end
260
+
261
+ def hashing_algorithm
262
+ OpenSSL::Digest::SHA1
263
+ end
264
+
265
+ def key(salt)
266
+ hashing_algorithm.digest(shared_secret.to_ssh + session_id + salt + session_id)
267
+ end
268
+
269
+ def cipher(type, options={})
270
+ Net::SSH::Transport::CipherFactory.get(type, options)
271
+ end
272
+
273
+ def kexinit(options={})
274
+ @kexinit ||= P(:byte, KEXINIT,
275
+ :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF),
276
+ :string, options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha256",
277
+ :string, options[:host_key] || "ssh-rsa,ssh-dss",
278
+ :string, options[:encryption_client] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
279
+ :string, options[:encryption_server] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
280
+ :string, options[:hmac_client] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96",
281
+ :string, options[:hmac_server] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96",
282
+ :string, options[:compmression_client] || "none,zlib@openssh.com,zlib",
283
+ :string, options[:compmression_server] || "none,zlib@openssh.com,zlib",
284
+ :string, options[:language_client] || "",
285
+ :string, options[:langauge_server] || "",
286
+ :bool, options[:first_kex_follows])
287
+ end
288
+
289
+ def assert_kexinit(buffer, options={})
290
+ assert_equal KEXINIT, buffer.type
291
+ assert_equal 16, buffer.read(16).length
292
+ if defined?(OpenSSL::PKey::EC)
293
+ assert_equal options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521", buffer.read_string
294
+ assert_equal options[:host_key] || "ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521", buffer.read_string
295
+ else
296
+ assert_equal options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256", buffer.read_string
297
+ assert_equal options[:host_key] || "ssh-rsa,ssh-dss", buffer.read_string
298
+ end
299
+ 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,arcfour,aes128-ctr,aes192-ctr,aes256-ctr,camellia128-cbc,camellia192-cbc,camellia256-cbc,camellia128-cbc@openssh.org,camellia192-cbc@openssh.org,camellia256-cbc@openssh.org,camellia128-ctr,camellia192-ctr,camellia256-ctr,camellia128-ctr@openssh.org,camellia192-ctr@openssh.org,camellia256-ctr@openssh.org,cast128-ctr,blowfish-ctr,3des-ctr", buffer.read_string
300
+ 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,arcfour,aes128-ctr,aes192-ctr,aes256-ctr,camellia128-cbc,camellia192-cbc,camellia256-cbc,camellia128-cbc@openssh.org,camellia192-cbc@openssh.org,camellia256-cbc@openssh.org,camellia128-ctr,camellia192-ctr,camellia256-ctr,camellia128-ctr@openssh.org,camellia192-ctr@openssh.org,camellia256-ctr@openssh.org,cast128-ctr,blowfish-ctr,3des-ctr", buffer.read_string
301
+ assert_equal options[:hmac_client] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-96,hmac-sha2-512-96,none", buffer.read_string
302
+ assert_equal options[:hmac_server] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-96,hmac-sha2-512-96,none", buffer.read_string
303
+ assert_equal options[:compression_client] || "none,zlib@openssh.com,zlib", buffer.read_string
304
+ assert_equal options[:compression_server] || "none,zlib@openssh.com,zlib", buffer.read_string
305
+ assert_equal options[:language_client] || "", buffer.read_string
306
+ assert_equal options[:language_server] || "", buffer.read_string
307
+ assert_equal options[:first_kex_follows] || false, buffer.read_bool
308
+ end
309
+
310
+ def assert_exchange_results
311
+ assert algorithms.initialized?
312
+ assert !algorithms.pending?
313
+ assert !transport.client_options[:compression]
314
+ assert !transport.server_options[:compression]
315
+ assert_equal :client_cipher, transport.client_options[:cipher]
316
+ assert_equal :server_cipher, transport.server_options[:cipher]
317
+ assert_equal :client_hmac, transport.client_options[:hmac]
318
+ assert_equal :server_hmac, transport.server_options[:hmac]
319
+ end
320
+
321
+ def algorithms(options={})
322
+ @algorithms ||= Net::SSH::Transport::Algorithms.new(transport, options)
323
+ end
324
+
325
+ def transport
326
+ @transport ||= MockTransport.new
327
+ end
328
+ end
329
+
330
+ end
@@ -0,0 +1,441 @@
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_aes128_cbc
39
+ assert_equal [16,16], factory.get_lengths("aes128-cbc")
40
+ end
41
+
42
+ def test_lengths_for_aes192_cbc
43
+ assert_equal [24,16], factory.get_lengths("aes192-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
+ def test_lengths_for_arcfour
51
+ assert_equal [16,8], factory.get_lengths("arcfour")
52
+ end
53
+
54
+ def test_lengths_for_arcfour128
55
+ assert_equal [16,8], factory.get_lengths("arcfour128")
56
+ end
57
+
58
+ def test_lengths_for_arcfour256
59
+ assert_equal [32,8], factory.get_lengths("arcfour256")
60
+ end
61
+
62
+ def test_lengths_for_arcfour512
63
+ assert_equal [64,8], factory.get_lengths("arcfour512")
64
+ end
65
+
66
+ if_supported?("camellia128-cbc@openssh.org") do
67
+ def test_lengths_for_camellia128_cbc_openssh_org
68
+ assert_equal [16,16], factory.get_lengths("camellia128-cbc@openssh.org")
69
+ end
70
+ end
71
+
72
+ if_supported?("camellia192-cbc@openssh.org") do
73
+ def test_lengths_for_camellia192_cbc_openssh_org
74
+ assert_equal [24,16], factory.get_lengths("camellia192-cbc@openssh.org")
75
+ end
76
+ end
77
+
78
+ if_supported?("camellia256-cbc@openssh.org") do
79
+ def test_lengths_for_camellia256_cbc_openssh_org
80
+ assert_equal [32,16], factory.get_lengths("camellia256-cbc@openssh.org")
81
+ end
82
+ end
83
+
84
+ def test_lengths_for_3des_ctr
85
+ assert_equal [24,8], factory.get_lengths("3des-ctr")
86
+ end
87
+
88
+ def test_lengths_for_aes128_ctr
89
+ assert_equal [16,16], factory.get_lengths("aes128-ctr")
90
+ end
91
+
92
+ def test_lengths_for_aes192_ctr
93
+ assert_equal [24,16], factory.get_lengths("aes192-ctr")
94
+ end
95
+
96
+ def test_lengths_for_aes256_ctr
97
+ assert_equal [32,16], factory.get_lengths("aes256-ctr")
98
+ end
99
+
100
+ def test_lengths_for_blowfish_ctr
101
+ assert_equal [16,8], factory.get_lengths("blowfish-ctr")
102
+ end
103
+
104
+ def test_lengths_for_cast128_ctr
105
+ assert_equal [16,8], factory.get_lengths("cast128-ctr")
106
+ end
107
+
108
+ if_supported?("camellia128-ctr@openssh.org") do
109
+ def test_lengths_for_camellia128_ctr_openssh_org
110
+ assert_equal [16,16], factory.get_lengths("camellia128-ctr@openssh.org")
111
+ end
112
+ end
113
+
114
+ if_supported?("camellia192-ctr@openssh.org") do
115
+ def test_lengths_for_camellia192_ctr_openssh_org
116
+ assert_equal [24,16], factory.get_lengths("camellia192-ctr@openssh.org")
117
+ end
118
+ end
119
+
120
+ if_supported?("camellia256-ctr@openssh.org") do
121
+ def test_lengths_for_camellia256_ctr_openssh_org
122
+ assert_equal [32,16], factory.get_lengths("camellia256-ctr@openssh.org")
123
+ end
124
+ end
125
+
126
+ BLOWFISH_CBC = "\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"
127
+
128
+ def test_blowfish_cbc_for_encryption
129
+ assert_equal BLOWFISH_CBC, encrypt("blowfish-cbc")
130
+ end
131
+
132
+ def test_blowfish_cbc_for_decryption
133
+ assert_equal TEXT, decrypt("blowfish-cbc", BLOWFISH_CBC)
134
+ end
135
+
136
+ if_supported?("idea-cbc") do
137
+ IDEA_CBC = "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"
138
+
139
+ def test_idea_cbc_for_encryption
140
+ assert_equal IDEA_CBC, encrypt("idea-cbc")
141
+ end
142
+
143
+ def test_idea_cbc_for_decryption
144
+ assert_equal TEXT, decrypt("idea-cbc", IDEA_CBC)
145
+ end
146
+ end
147
+
148
+ 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"
149
+
150
+ def test_rijndael_cbc_for_encryption
151
+ assert_equal RIJNDAEL, encrypt("rijndael-cbc@lysator.liu.se")
152
+ end
153
+
154
+ def test_rijndael_cbc_for_decryption
155
+ assert_equal TEXT, decrypt("rijndael-cbc@lysator.liu.se", RIJNDAEL)
156
+ end
157
+
158
+ CAST128_CBC = "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"
159
+
160
+ def test_cast128_cbc_for_encryption
161
+ assert_equal CAST128_CBC, encrypt("cast128-cbc")
162
+ end
163
+
164
+ def test_cast128_cbc_for_decryption
165
+ assert_equal TEXT, decrypt("cast128-cbc", CAST128_CBC)
166
+ end
167
+
168
+ TRIPLE_DES_CBC = "\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"
169
+
170
+ def test_3des_cbc_for_encryption
171
+ assert_equal TRIPLE_DES_CBC, encrypt("3des-cbc")
172
+ end
173
+
174
+ def test_3des_cbc_for_decryption
175
+ assert_equal TEXT, decrypt("3des-cbc", TRIPLE_DES_CBC)
176
+ end
177
+
178
+ AES128_CBC = "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"
179
+
180
+ def test_aes128_cbc_for_encryption
181
+ assert_equal AES128_CBC, encrypt("aes128-cbc")
182
+ end
183
+
184
+ def test_aes128_cbc_for_decryption
185
+ assert_equal TEXT, decrypt("aes128-cbc", AES128_CBC)
186
+ end
187
+
188
+ AES192_CBC = "\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"
189
+
190
+ def test_aes192_cbc_for_encryption
191
+ assert_equal AES192_CBC, encrypt("aes192-cbc")
192
+ end
193
+
194
+ def test_aes192_cbc_for_decryption
195
+ assert_equal TEXT, decrypt("aes192-cbc", AES192_CBC)
196
+ end
197
+
198
+ AES256_CBC = "$\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"
199
+
200
+ def test_aes256_cbc_for_encryption
201
+ assert_equal AES256_CBC, encrypt("aes256-cbc")
202
+ end
203
+
204
+ def test_aes256_cbc_for_decryption
205
+ assert_equal TEXT, decrypt("aes256-cbc", AES256_CBC)
206
+ end
207
+
208
+ ARCFOUR = "\xC1.\x1AdH\xD0+%\xF1CrG\x1C\xCC\xF6\xACho\xB0\x95\\\xBC\x02P\xF9\xAF\n\xBB<\x13\xF3\xCF\xEB\n\b(iO\xFB'\t^?\xA6\xE5a\xE2\x17\f\x97\xCAs\x9E\xFC\xF2\x88\xC93\v\x84\xCA\x82\x0E\x1D\x11\xEA\xE1\x82\x8E\xB3*\xC5\xFB\x8Cmgs\xB0\xFA\xF5\x9C\\\xE2\xB0\x95\x1F>LT"
209
+
210
+ def test_arcfour_for_encryption
211
+ assert_equal ARCFOUR, encrypt("arcfour")
212
+ end
213
+
214
+ def test_arcfour_for_decryption
215
+ assert_equal TEXT, decrypt("arcfour", ARCFOUR)
216
+ end
217
+
218
+ ARCFOUR128 = "\n\x90\xED*\xD4\xBE\xCBg5\xA5\a\xEC]\x97\xB7L\x06)6\x12FL\x90@\xF4Sqxqh\r\x11\x1Aq \xC8\xE6v\xC6\x12\xD9<A\xDAZ\xFE\x7F\x88\x19f.\x06\xA7\xFE:\xFF\x93\x9B\x8D\xA0\\\x9E\xCA\x03\x15\xE1\xE2\f\xC0\b\xA2C\xE1\xBD\xB6\x13D\xD1\xB4'g\x89\xDC\xEB\f\x19Z)U"
219
+
220
+ def test_arcfour128_for_encryption
221
+ assert_equal ARCFOUR128, encrypt("arcfour128")
222
+ end
223
+
224
+ def test_arcfour128_for_decryption
225
+ assert_equal TEXT, decrypt("arcfour128", ARCFOUR128)
226
+ end
227
+
228
+ ARCFOUR256 = "|g\xCCw\xF5\xC1y\xEB\xF0\v\xF7\x83\x14\x03\xC8\xAB\xE8\xC2\xFCY\xDC,\xB8\xD4dVa\x8B\x18%\xA4S\x00\xE0at\x86\xE8\xA6W\xAB\xD2\x9D\xA8\xDE[g\aZy.\xFB\xFC\x82c\x04h\f\xBFYq\xB7U\x80\x0EG\x91\x88\xDF\xA3\xA2\xFA(\xEC\xDB\xA4\xE7\xFE)\x12u\xAF\x0EZ\xA0\xBA\x97\n\xFC"
229
+
230
+ def test_arcfour256_for_encryption
231
+ assert_equal ARCFOUR256, encrypt("arcfour256")
232
+ end
233
+
234
+ def test_arcfour256_for_decryption
235
+ assert_equal TEXT, decrypt("arcfour256", ARCFOUR256)
236
+ end
237
+
238
+ ARCFOUR512 = "|8\"v\xE7\xE3\b\xA8\x19\x9Aa\xB6Vv\x00\x11\x8A$C\xB6xE\xEF\xF1j\x90\xA8\xFA\x10\xE4\xA1b8\xF6\x04\xF2+\xC0\xD1(8\xEBT]\xB0\xF3/\xD9\xE0@\x83\a\x93\x9D\xCA\x04RXS\xB7A\x0Fj\x94\bE\xEB\x84j\xB4\xDF\nU\xF7\x83o\n\xE8\xF9\x01{jH\xEE\xCDQym\x9E"
239
+
240
+ def test_arcfour512_for_encryption
241
+ assert_equal ARCFOUR512, encrypt("arcfour512")
242
+ end
243
+
244
+ def test_arcfour512_for_decryption
245
+ assert_equal TEXT, decrypt("arcfour512", ARCFOUR512)
246
+ end
247
+
248
+ if_supported?("camellia128-cbc@openssh.org") do
249
+ CAMELLIA128_CBC = "\a\b\x83+\xF1\xC5m\a\xE1\xD3\x06\xD2NA\xC3l@\\*M\xFD\x96\xAE\xA8\xB4\xA9\xACm\"8\x8E\xEE<\xC3O[\rK\xFAgu}\xCD\xAC\xF4\x04o\xDB\x94-\xB8\"\xDC\xE7{y\xA9 \x8F=y\x85\x82v\xC8\xCA\x8A\xE9\xE3:\xC4,u=a/\xC0\x05\xDA\xDAk8g\xCB\xD9\xA8\xE6\xFE\xCE_\x8E\x97\xF0\xAC\xB6\xCE"
250
+ def test_camellia128_cbc_for_encryption
251
+ assert_equal CAMELLIA128_CBC, encrypt("camellia128-cbc@openssh.org")
252
+ end
253
+ def test_camellia128_cbc_for_decryption
254
+ assert_equal TEXT, decrypt("camellia128-cbc@openssh.org", CAMELLIA128_CBC)
255
+ end
256
+ end
257
+
258
+ if_supported?("camellia192-cbc@openssh.org") do
259
+ CAMELLIA192_CBC = "\x82\xB2\x03\x90\xFA\f2\xA0\xE3\xFA\xF2B\xAB\xDBX\xD5\x04z\xD4G\x19\xB8\xAB\v\x85\x84\xCD:.\xBA\x9Dd\xD5(\xEB.\n\xAA]\xCB\xF3\x0F4\x8Bd\xF8m\xC9!\xE2\xA1=\xEBY\xA6\x83\x86\n\x13\e6\v\x06\xBBNJg\xF2-\x14',[\xC1\xB1.\x85\xF3\xC6\xBF\x1Ff\xCE\x87'\x9C\xB2\xC8!\xF3|\xE2\xD2\x9E\x96\xA1"
260
+ def test_camellia192_cbc_for_encryption
261
+ assert_equal CAMELLIA192_CBC, encrypt("camellia192-cbc@openssh.org")
262
+ end
263
+ def test_camellia192_cbc_for_decryption
264
+ assert_equal TEXT, decrypt("camellia192-cbc@openssh.org", CAMELLIA192_CBC)
265
+ end
266
+ end
267
+
268
+ if_supported?("camellia256-cbc@openssh.org") do
269
+ CAMELLIA256_CBC = ",\x80J/\xF5\x8F\xFE4\xF0@\n[2\xFF4\xB6\xA4\xD0\xF8\xF5*\x17I\xF3\xA2\x1F$L\xC6\xA1\x06\xDC\x84f\x1C\x10&\x1C\xC4/R\x859|i\x85ZP\xC8\x94\xED\xE8-\n@ w\x92\xF7\xD4\xAB\xF0\x85c\xC1\x0F\x1E#\xEB\xE5W\x87N!\xC7'/\xE3E8$\x1D\x9B:\xC9\xAF_\x05\xAC%\xD7\x945\xBBDK"
270
+ def test_camellia256_cbc_for_encryption
271
+ assert_equal CAMELLIA256_CBC, encrypt("camellia256-cbc@openssh.org")
272
+ end
273
+ def test_camellia256_cbc_for_decryption
274
+ assert_equal TEXT, decrypt("camellia256-cbc@openssh.org", CAMELLIA256_CBC)
275
+ end
276
+ end
277
+
278
+ BLOWFISH_CTR = "\xF5\xA6\x1E{\x8F(\x85G\xFAh\xDB\x19\xDC\xDF\xA2\x9A\x99\xDD5\xFF\xEE\x8BE\xE6\xB5\x92\x82\xE80\x91\x11`\xEF\x10\xED\xE9\xD3\vG\x0E\xAF\xB2K\t\xA4\xA6\x05\xD1\x17\x0Fl\r@E\x8DJ\e\xE63\x04\xB5\x05\x99Y\xCC\xFBb\x8FK+\x8C1v\xE4N\b?B\x06Rz\xA6\xB6N/b\xCE}\x83\x8DY\xD7\x92qU\x0F"
279
+
280
+ def test_blowfish_ctr_for_encryption
281
+ assert_equal BLOWFISH_CTR, encrypt("blowfish-ctr")
282
+ end
283
+
284
+ def test_blowfish_ctr_for_decryption
285
+ assert_equal TEXT, decrypt("blowfish-ctr", BLOWFISH_CTR)
286
+ end
287
+
288
+ CAST128_CTR = "\xB5\xBB\xC3h\x80\x90`{\xD7I\x03\xE9\x80\xC4\xC4U\xE3@\xF1\xE9\xEFX\xDB6\xEE,\x8E\xC2\xE8\x89\x17\xBArf\x81\r\x96\xDC\xB1_'\x83hs\t7\xB8@\x17\xAA\xD9;\xE8\x8E\x94\xBD\xFF\xA4K\xA4\xFA\x8F-\xCD\bO\xD9I`\xE5\xC9H\x99\x14\xC5K\xC8\xEF\xEA#\x1D\xE5\x13O\xE1^P\xDC\x1C^qm\v|c@"
289
+
290
+ def test_cast128_ctr_for_encryption
291
+ assert_equal CAST128_CTR, encrypt("cast128-ctr")
292
+ end
293
+
294
+ def test_cast128_ctr_for_decryption
295
+ assert_equal TEXT, decrypt("cast128-ctr", CAST128_CTR)
296
+ end
297
+
298
+ TRIPLE_DES_CTR = "\x90\xCD\b\xD2\xF1\x15:\x98\xF4sJ\xF0\xC9\xAA\xC5\xE3\xB4\xCFq\x93\xBAB\xF9v\xE1\xE7\x8B<\xBC\x97R\xDF?kK~Nw\xF3\x92`\x90]\xD9\xEF\x16\xC85V\x03C\xE9\x14\xF0\x86\xEB\x19\x85\x82\xF6\x16gz\x9B`\xB1\xCE\x80&?\xC8\xBD\xBC+\x91/)\xA5x\xBB\xCF\x06\x15#\e\xB3\xBD\x9B\x1F\xA7\xE2\xC7\xA3\xFC\x06\xC8"
299
+
300
+ def test_3des_ctr_for_encryption
301
+ if defined?(JRUBY_VERSION)
302
+ # on JRuby, this test fails due to JRUBY-6558
303
+ puts "Skipping 3des-ctr tests for JRuby"
304
+ else
305
+ assert_equal TRIPLE_DES_CTR, encrypt("3des-ctr")
306
+ end
307
+ end
308
+
309
+ def test_3des_ctr_for_decryption
310
+ if defined?(JRUBY_VERSION)
311
+ # on JRuby, this test fails due to JRUBY-6558
312
+ puts "Skipping 3des-ctr tests for JRuby"
313
+ else
314
+ assert_equal TEXT, decrypt("3des-ctr", TRIPLE_DES_CTR)
315
+ end
316
+ end
317
+
318
+ AES128_CTR = "\x9D\xC7]R\x89\x01\xC4\x14\x00\xE7\xCEc`\x80\v\xC7\xF7\xBD\xD5#d\f\xC9\xB0\xDE\xA6\x8Aq\x10p\x8F\xBC\xFF\x8B\xB4\xC5\xB3\xF7,\xF7eO\x06Q]\x0F\x05\x86\xEC\xA6\xC8\x12\xE9\xC4\x9D0\xD3\x9AL\x192\xAA\xDFu\x0E\xECz\x7F~g\xCA\xEA\xBA\x80,\x83V\x10\xF6/\x04\xD2\x8A\x94\x94\xA9T>~\xD2\r\xE6\x0E\xA0q\xEF"
319
+
320
+ def test_aes128_ctr_for_encryption
321
+ assert_equal AES128_CTR, encrypt("aes128-ctr")
322
+ end
323
+
324
+ def test_aes128_ctr_for_decryption
325
+ assert_equal TEXT, decrypt("aes128-ctr", AES128_CTR)
326
+ end
327
+
328
+ AES192_CTR = "\xE2\xE7\x1FJ\xE5\xB09\xE1\xB7/\xB3\x95\xF2S\xCE\x8C\x93\x14mFY\x88*\xCE\b\xA6\x87W\xD7\xEC/\xC9\xB6\x9Ba\a\x8E\x89-\xD7\xB2j\a\xB3\a\x92f\"\x96\x8D\xBF\x01\t\xB8Y\xF3\x92\x01\xCC7\xB6w\xF9\"=u:\xA1\xD5*\n\x9E\xC7p\xDC\x11\a\x1C\x88y\xE8\x87`\xA6[fF\x9B\xACv\xA6\xDA1|#F"
329
+
330
+ def test_aes192_ctr_for_encryption
331
+ assert_equal AES192_CTR, encrypt("aes192-ctr")
332
+ end
333
+
334
+ def test_aes192_ctr_for_decryption
335
+ assert_equal TEXT, decrypt("aes192-ctr", AES192_CTR)
336
+ end
337
+
338
+ AES256_CTR = "2\xB8\xE6\xC9\x95\xB4\x05\xD2\xC7+\x7F\x88\xEB\xD4\xA0\b\"\xBF\x9E\x85t\x19,\e\x90\x11\x04b\xC7\xEE$\xDE\xE6\xC5@G\xFEm\xE1u\x9B\au\xAF\xB5\xB8\x857\x87\x139u\xAC\x1A\xAB\fh\x8FiW~\xB8:\xA4\xA0#~\xC4\x89\xBA5#:\xFC\xC8\xE3\x9B\xF0A2\x87\x980\xD1\xE3\xBC'\xBE\x1E\n\x1A*B\x06\xF3\xCC"
339
+
340
+ def test_aes256_ctr_for_encryption
341
+ assert_equal AES256_CTR, encrypt("aes256-ctr")
342
+ end
343
+
344
+ def test_aes256_ctr_for_decryption
345
+ assert_equal TEXT, decrypt("aes256-ctr", AES256_CTR)
346
+ end
347
+
348
+ CAMELLIA128_CTR = "$\xCDQ\x86\xFD;Eq\x04\xFD\xEF\xC9\x18\xBA\\ZA\xD1\xA6Z\xC7V\xDE\xCDT\xBB\xC9\xB0BW\x9BOb}O\xCANy\xEA\xBB\xC5\x126\xE3\xDF\xB8]|j\x1D\xAE\"i\x8A\xCB\xE06\x01\xC4\xDA\xF6:\xA7\xB2v\xB0\xAE\xA5m\x16\xDB\xEBR\xCC\xB4\xA3\x93\x11;\xF1\x00\xDFS6\xF8\xD0_\b\nl\xA2\x95\x8E\xF2\xB0\xC1"
349
+ if_supported?("camellia128-ctr@openssh.org") do
350
+ def test_camellia128_ctr_openssh_org_for_encryption
351
+ assert_equal CAMELLIA128_CTR, encrypt("camellia128-ctr@openssh.org")
352
+ end
353
+ def test_camellia128_ctr_openssh_org_for_decryption
354
+ assert_equal TEXT, decrypt("camellia128-ctr@openssh.org", CAMELLIA128_CTR)
355
+ end
356
+ end
357
+ if_supported?("camellia128-ctr") do
358
+ def test_camellia128_ctr_for_encryption
359
+ assert_equal CAMELLIA128_CTR, encrypt("camellia128-ctr")
360
+ end
361
+ def test_camellia128_ctr_for_decryption
362
+ assert_equal TEXT, decrypt("camellia128-ctr", CAMELLIA128_CTR)
363
+ end
364
+ end
365
+
366
+ CAMELLIA192_CTR = "\xB1O;\xA5\xB9 \xD6\x7Fw\ajz\xAF12\x1C\xF0^\xB2\x13\xA7s\xCB\x1A(3Yw\x8B\"7\xD7}\xC4\xAA\xF7\xDB\xF2\xEEi\x02\xD0\x94BK\xD9l\xBC\xBEbrk\x87\x14h\xE1'\xD2\xE4\x8C\x8D\x87\xCE\xBF\x89\xA9\x9E\xC4\f\xB8\x87(\xFE?\xD9\xEF\xBA5\xD8\xA1\rI\xD6s9\x10\xA9l\xB8S\x93}*\x9A\xB0="
367
+ if_supported?("camellia192-ctr@openssh.org") do
368
+ def test_camellia192_ctr_openssh_org_for_encryption
369
+ assert_equal CAMELLIA192_CTR, encrypt("camellia192-ctr@openssh.org")
370
+ end
371
+ def test_camellia192_ctr_openssh_org_for_decryption
372
+ assert_equal TEXT, decrypt("camellia192-ctr@openssh.org", CAMELLIA192_CTR)
373
+ end
374
+ end
375
+ if_supported?("camellia192-ctr") do
376
+ def test_camellia192_ctr_for_encryption
377
+ assert_equal CAMELLIA192_CTR, encrypt("camellia192-ctr")
378
+ end
379
+ def test_camellia192_ctr_for_decryption
380
+ assert_equal TEXT, decrypt("camellia192-ctr", CAMELLIA192_CTR)
381
+ end
382
+ end
383
+
384
+ CAMELLIA256_CTR = "`\x8F#Nqr^m\xB2/i\xF9}\x1E\xD1\xE7X\x99\xAF\x1E\xBA\v\xF3\x8E\xCA\xECZ\xCB\x8A\xC96FW\xB3\x84 bwzRM,P\xC1r\xEFHNr%\xB9\a\xD6\xE6\xE7O\b\xC8?\x98d\x9F\xD3v\x10#\xA6\x87\xB2\x85\x059\xF0-\xF9\xBC\x00V\xB2?\xAE\x1E{\e\xF1\xA9zJ\xC9=1\xB3t73\xEB"
385
+ if_supported?("camellia256-ctr@openssh.org") do
386
+ def test_camellia256_ctr_openssh_org_for_encryption
387
+ assert_equal CAMELLIA256_CTR, encrypt("camellia256-ctr@openssh.org")
388
+ end
389
+ def test_camellia256_ctr_openssh_org_for_decryption
390
+ assert_equal TEXT, decrypt("camellia256-ctr@openssh.org", CAMELLIA256_CTR)
391
+ end
392
+ end
393
+ if_supported?("camellia256-ctr") do
394
+ def test_camellia256_ctr_for_encryption
395
+ assert_equal CAMELLIA256_CTR, encrypt("camellia256-ctr")
396
+ end
397
+ def test_camellia256_ctr_for_decryption
398
+ assert_equal TEXT, decrypt("camellia256-ctr", CAMELLIA256_CTR)
399
+ end
400
+ end
401
+
402
+ def test_none_for_encryption
403
+ assert_equal TEXT, encrypt("none").strip
404
+ end
405
+
406
+ def test_none_for_decryption
407
+ assert_equal TEXT, decrypt("none", TEXT)
408
+ end
409
+
410
+ private
411
+
412
+ TEXT = "But soft! What light through yonder window breaks? It is the east, and Juliet is the sun!"
413
+
414
+ OPTIONS = { :iv => "ABC",
415
+ :key => "abc",
416
+ :digester => OpenSSL::Digest::MD5,
417
+ :shared => "1234567890123456780",
418
+ :hash => '!@#$%#$^%$&^&%#$@$'
419
+ }
420
+
421
+ def factory
422
+ Net::SSH::Transport::CipherFactory
423
+ end
424
+
425
+ def encrypt(type)
426
+ cipher = factory.get(type, OPTIONS.merge(:encrypt => true))
427
+ padding = TEXT.length % cipher.block_size
428
+ result = cipher.update(TEXT.dup)
429
+ result << cipher.update(" " * (cipher.block_size - padding)) if padding > 0
430
+ result << cipher.final
431
+ end
432
+
433
+ def decrypt(type, data)
434
+ cipher = factory.get(type, OPTIONS.merge(:decrypt => true))
435
+ result = cipher.update(data.dup)
436
+ result << cipher.final
437
+ result.strip
438
+ end
439
+ end
440
+
441
+ end