net-ssh 3.2.0 → 7.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/config/rubocop_linter_action.yml +4 -0
  6. data/.github/workflows/ci-with-docker.yml +44 -0
  7. data/.github/workflows/ci.yml +93 -0
  8. data/.github/workflows/rubocop.yml +16 -0
  9. data/.gitignore +13 -0
  10. data/.rubocop.yml +22 -0
  11. data/.rubocop_todo.yml +1081 -0
  12. data/CHANGES.txt +237 -7
  13. data/DEVELOPMENT.md +23 -0
  14. data/Dockerfile +27 -0
  15. data/Dockerfile.openssl3 +17 -0
  16. data/Gemfile +13 -0
  17. data/Gemfile.noed25519 +12 -0
  18. data/Gemfile.norbnacl +12 -0
  19. data/ISSUE_TEMPLATE.md +30 -0
  20. data/Manifest +4 -5
  21. data/README.md +298 -0
  22. data/Rakefile +125 -74
  23. data/SECURITY.md +4 -0
  24. data/appveyor.yml +58 -0
  25. data/docker-compose.yml +23 -0
  26. data/lib/net/ssh/authentication/agent.rb +279 -18
  27. data/lib/net/ssh/authentication/certificate.rb +183 -0
  28. data/lib/net/ssh/authentication/constants.rb +17 -15
  29. data/lib/net/ssh/authentication/ed25519.rb +186 -0
  30. data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  31. data/lib/net/ssh/authentication/key_manager.rb +86 -39
  32. data/lib/net/ssh/authentication/methods/abstract.rb +67 -48
  33. data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
  34. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +13 -13
  35. data/lib/net/ssh/authentication/methods/none.rb +16 -19
  36. data/lib/net/ssh/authentication/methods/password.rb +27 -17
  37. data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
  38. data/lib/net/ssh/authentication/pageant.rb +471 -367
  39. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  40. data/lib/net/ssh/authentication/session.rb +131 -121
  41. data/lib/net/ssh/buffer.rb +399 -300
  42. data/lib/net/ssh/buffered_io.rb +154 -150
  43. data/lib/net/ssh/config.rb +308 -185
  44. data/lib/net/ssh/connection/channel.rb +635 -613
  45. data/lib/net/ssh/connection/constants.rb +29 -29
  46. data/lib/net/ssh/connection/event_loop.rb +123 -0
  47. data/lib/net/ssh/connection/keepalive.rb +55 -51
  48. data/lib/net/ssh/connection/session.rb +620 -551
  49. data/lib/net/ssh/connection/term.rb +125 -123
  50. data/lib/net/ssh/errors.rb +101 -99
  51. data/lib/net/ssh/key_factory.rb +197 -105
  52. data/lib/net/ssh/known_hosts.rb +214 -127
  53. data/lib/net/ssh/loggable.rb +50 -49
  54. data/lib/net/ssh/packet.rb +83 -79
  55. data/lib/net/ssh/prompt.rb +50 -81
  56. data/lib/net/ssh/proxy/command.rb +105 -90
  57. data/lib/net/ssh/proxy/errors.rb +12 -10
  58. data/lib/net/ssh/proxy/http.rb +82 -79
  59. data/lib/net/ssh/proxy/https.rb +50 -0
  60. data/lib/net/ssh/proxy/jump.rb +54 -0
  61. data/lib/net/ssh/proxy/socks4.rb +2 -6
  62. data/lib/net/ssh/proxy/socks5.rb +14 -17
  63. data/lib/net/ssh/service/forward.rb +370 -317
  64. data/lib/net/ssh/test/channel.rb +145 -136
  65. data/lib/net/ssh/test/extensions.rb +131 -110
  66. data/lib/net/ssh/test/kex.rb +34 -32
  67. data/lib/net/ssh/test/local_packet.rb +46 -44
  68. data/lib/net/ssh/test/packet.rb +89 -70
  69. data/lib/net/ssh/test/remote_packet.rb +32 -30
  70. data/lib/net/ssh/test/script.rb +156 -142
  71. data/lib/net/ssh/test/socket.rb +49 -48
  72. data/lib/net/ssh/test.rb +82 -77
  73. data/lib/net/ssh/transport/algorithms.rb +462 -359
  74. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  75. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  76. data/lib/net/ssh/transport/cipher_factory.rb +122 -99
  77. data/lib/net/ssh/transport/constants.rb +32 -24
  78. data/lib/net/ssh/transport/ctr.rb +42 -22
  79. data/lib/net/ssh/transport/hmac/abstract.rb +81 -63
  80. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  81. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  82. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  83. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  84. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  85. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  86. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  87. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  88. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  89. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  90. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  91. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  92. data/lib/net/ssh/transport/hmac.rb +14 -12
  93. data/lib/net/ssh/transport/identity_cipher.rb +54 -44
  94. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  95. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  96. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  97. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  98. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  99. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  100. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +119 -213
  101. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -61
  102. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  103. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  104. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  105. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  106. data/lib/net/ssh/transport/kex.rb +15 -12
  107. data/lib/net/ssh/transport/key_expander.rb +24 -20
  108. data/lib/net/ssh/transport/openssl.rb +161 -124
  109. data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  110. data/lib/net/ssh/transport/packet_stream.rb +246 -185
  111. data/lib/net/ssh/transport/server_version.rb +55 -56
  112. data/lib/net/ssh/transport/session.rb +306 -255
  113. data/lib/net/ssh/transport/state.rb +178 -176
  114. data/lib/net/ssh/verifiers/accept_new.rb +33 -0
  115. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  116. data/lib/net/ssh/verifiers/always.rb +58 -0
  117. data/lib/net/ssh/verifiers/never.rb +19 -0
  118. data/lib/net/ssh/version.rb +55 -53
  119. data/lib/net/ssh.rb +111 -47
  120. data/net-ssh-public_cert.pem +18 -18
  121. data/net-ssh.gemspec +38 -205
  122. data/support/ssh_tunnel_bug.rb +5 -5
  123. data.tar.gz.sig +0 -0
  124. metadata +173 -118
  125. metadata.gz.sig +0 -0
  126. data/.travis.yml +0 -18
  127. data/README.rdoc +0 -182
  128. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  129. data/lib/net/ssh/authentication/agent/socket.rb +0 -178
  130. data/lib/net/ssh/ruby_compat.rb +0 -46
  131. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  132. data/lib/net/ssh/verifiers/null.rb +0 -12
  133. data/lib/net/ssh/verifiers/secure.rb +0 -52
  134. data/lib/net/ssh/verifiers/strict.rb +0 -24
  135. data/setup.rb +0 -1585
  136. data/support/arcfour_check.rb +0 -20
  137. data/test/README.txt +0 -18
  138. data/test/authentication/methods/common.rb +0 -28
  139. data/test/authentication/methods/test_abstract.rb +0 -51
  140. data/test/authentication/methods/test_hostbased.rb +0 -114
  141. data/test/authentication/methods/test_keyboard_interactive.rb +0 -121
  142. data/test/authentication/methods/test_none.rb +0 -41
  143. data/test/authentication/methods/test_password.rb +0 -95
  144. data/test/authentication/methods/test_publickey.rb +0 -148
  145. data/test/authentication/test_agent.rb +0 -232
  146. data/test/authentication/test_key_manager.rb +0 -240
  147. data/test/authentication/test_session.rb +0 -107
  148. data/test/common.rb +0 -125
  149. data/test/configs/auth_off +0 -5
  150. data/test/configs/auth_on +0 -4
  151. data/test/configs/empty +0 -0
  152. data/test/configs/eqsign +0 -3
  153. data/test/configs/exact_match +0 -8
  154. data/test/configs/host_plus +0 -10
  155. data/test/configs/multihost +0 -4
  156. data/test/configs/negative_match +0 -6
  157. data/test/configs/nohost +0 -19
  158. data/test/configs/numeric_host +0 -4
  159. data/test/configs/proxy_remote_user +0 -2
  160. data/test/configs/send_env +0 -2
  161. data/test/configs/substitutes +0 -8
  162. data/test/configs/wild_cards +0 -14
  163. data/test/connection/test_channel.rb +0 -487
  164. data/test/connection/test_session.rb +0 -564
  165. data/test/integration/README.txt +0 -17
  166. data/test/integration/Vagrantfile +0 -12
  167. data/test/integration/common.rb +0 -63
  168. data/test/integration/playbook.yml +0 -56
  169. data/test/integration/test_forward.rb +0 -637
  170. data/test/integration/test_id_rsa_keys.rb +0 -96
  171. data/test/integration/test_proxy.rb +0 -93
  172. data/test/known_hosts/github +0 -1
  173. data/test/known_hosts/github_hash +0 -1
  174. data/test/manual/test_pageant.rb +0 -37
  175. data/test/start/test_connection.rb +0 -53
  176. data/test/start/test_options.rb +0 -57
  177. data/test/start/test_transport.rb +0 -28
  178. data/test/start/test_user_nil.rb +0 -27
  179. data/test/test_all.rb +0 -12
  180. data/test/test_buffer.rb +0 -433
  181. data/test/test_buffered_io.rb +0 -63
  182. data/test/test_config.rb +0 -268
  183. data/test/test_key_factory.rb +0 -191
  184. data/test/test_known_hosts.rb +0 -66
  185. data/test/transport/hmac/test_md5.rb +0 -41
  186. data/test/transport/hmac/test_md5_96.rb +0 -27
  187. data/test/transport/hmac/test_none.rb +0 -34
  188. data/test/transport/hmac/test_ripemd160.rb +0 -36
  189. data/test/transport/hmac/test_sha1.rb +0 -36
  190. data/test/transport/hmac/test_sha1_96.rb +0 -27
  191. data/test/transport/hmac/test_sha2_256.rb +0 -37
  192. data/test/transport/hmac/test_sha2_256_96.rb +0 -27
  193. data/test/transport/hmac/test_sha2_512.rb +0 -37
  194. data/test/transport/hmac/test_sha2_512_96.rb +0 -27
  195. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
  196. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -150
  197. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -96
  198. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -19
  199. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
  200. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
  201. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
  202. data/test/transport/test_algorithms.rb +0 -328
  203. data/test/transport/test_cipher_factory.rb +0 -443
  204. data/test/transport/test_hmac.rb +0 -34
  205. data/test/transport/test_identity_cipher.rb +0 -40
  206. data/test/transport/test_packet_stream.rb +0 -1762
  207. data/test/transport/test_server_version.rb +0 -74
  208. data/test/transport/test_session.rb +0 -331
  209. data/test/transport/test_state.rb +0 -181
  210. data/test/verifiers/test_secure.rb +0 -40
@@ -1,38 +0,0 @@
1
- require 'openssl'
2
-
3
- unless defined?(OpenSSL::PKey::EC)
4
- puts "Skipping tests for ecdh-sha2-nistp521 key exchange"
5
- else
6
- require 'transport/kex/test_ecdh_sha2_nistp256'
7
- module Transport; module Kex
8
- class TestEcdhSHA2NistP521 < TestEcdhSHA2NistP256
9
-
10
- def setup
11
- @ecdh = @algorithms = @connection = @server_key =
12
- @packet_data = @shared_secret = nil
13
- end
14
-
15
- def test_exchange_keys_should_return_expected_results_when_successful
16
- result = exchange!
17
- assert_equal session_id, result[:session_id]
18
- assert_equal server_host_key.to_blob, result[:server_key].to_blob
19
- assert_equal shared_secret, result[:shared_secret]
20
- assert_equal digester, result[:hashing_algorithm]
21
- end
22
-
23
- private
24
-
25
- def digester
26
- OpenSSL::Digest::SHA512
27
- end
28
-
29
- def subject
30
- Net::SSH::Transport::Kex::EcdhSHA2NistP521
31
- end
32
-
33
- def ecparam
34
- "secp521r1"
35
- end
36
- end
37
- end; end
38
- end
@@ -1,328 +0,0 @@
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 ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com)+ec_host_keys, algorithms[:host_key]
21
- assert_equal %w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256)+ec_kex, 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 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]
23
- if defined?(OpenSSL::Digest::SHA256)
24
- 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]
25
- else
26
- assert_equal %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 hmac-ripemd160 hmac-ripemd160@openssh.com none umac-128-etm@openssh.com), algorithms[:hmac] end
27
- assert_equal %w(none zlib@openssh.com zlib), algorithms[:compression]
28
- assert_equal %w(), algorithms[:language]
29
- end
30
-
31
- def test_constructor_should_set_client_and_server_prefs_identically
32
- %w(encryption hmac compression language).each do |key|
33
- assert_equal algorithms[key.to_sym], algorithms[:"#{key}_client"], key
34
- assert_equal algorithms[key.to_sym], algorithms[:"#{key}_server"], key
35
- end
36
- end
37
-
38
- def test_constructor_with_preferred_host_key_type_should_put_preferred_host_key_type_first
39
- assert_equal %w(ssh-dss ssh-rsa ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com)+ec_host_keys, algorithms(:host_key => "ssh-dss", :append_all_supported_algorithms => true)[:host_key]
40
- end
41
-
42
- def test_constructor_with_known_hosts_reporting_known_host_key_should_use_that_host_key_type
43
- Net::SSH::KnownHosts.expects(:search_for).with("net.ssh.test,127.0.0.1", {}).returns([stub("key", :ssh_type => "ssh-dss")])
44
- assert_equal %w(ssh-dss ssh-rsa ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com )+ec_host_keys, algorithms[:host_key]
45
- end
46
-
47
- def ec_host_keys
48
- if defined?(OpenSSL::PKey::EC)
49
- %w(ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521)
50
- else
51
- []
52
- end
53
- end
54
-
55
- def test_constructor_with_unrecognized_host_key_type_should_return_whats_supported
56
- assert_equal %w(ssh-rsa ssh-dss ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com )+ec_host_keys, algorithms(:host_key => "bogus ssh-rsa",:append_all_supported_algorithms => true)[:host_key]
57
- end
58
-
59
- def ec_kex
60
- if defined?(OpenSSL::PKey::EC)
61
- %w(ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521)
62
- else
63
- []
64
- end
65
- end
66
-
67
- def test_constructor_with_preferred_kex_should_put_preferred_kex_first
68
- assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256)+ec_kex, algorithms(:kex => "diffie-hellman-group1-sha1", :append_all_supported_algorithms => true)[:kex]
69
- end
70
-
71
- def test_constructor_with_unrecognized_kex_should_not_raise_exception
72
- assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256)+ec_kex, algorithms(
73
- :kex => %w(bogus diffie-hellman-group1-sha1),:append_all_supported_algorithms => true)[:kex]
74
- end
75
-
76
- def test_constructor_with_preferred_encryption_should_put_preferred_encryption_first
77
- 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",
78
- :append_all_supported_algorithms => true)[: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), :append_all_supported_algorithms => true)[:encryption]
83
- end
84
-
85
- def test_constructor_with_unrecognized_encryption_should_keep_whats_supported
86
- 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 => %w(bogus aes256-cbc), :append_all_supported_algorithms => true)[:encryption]
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", :append_all_supported_algorithms => true)[: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), :append_all_supported_algorithms => true)[:hmac]
95
- end
96
-
97
- def test_constructor_with_unrecognized_hmac_should_ignore_those
98
- 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),
99
- algorithms(:hmac => "hmac-md5-96", :append_all_supported_algorithms => true)[:hmac]
100
- end
101
-
102
- def test_constructor_with_preferred_compression_should_put_preferred_compression_first
103
- assert_equal %w(zlib none zlib@openssh.com), algorithms(:compression => "zlib", :append_all_supported_algorithms => true)[:compression]
104
- end
105
-
106
- def test_constructor_with_multiple_preferred_compression_should_put_all_preferred_compression_first
107
- assert_equal %w(zlib@openssh.com zlib none), algorithms(:compression => %w(zlib@openssh.com zlib),
108
- :append_all_supported_algorithms => true)[:compression]
109
- end
110
-
111
- def test_constructor_with_general_preferred_compression_should_put_none_last
112
- assert_equal %w(zlib@openssh.com zlib none), algorithms(
113
- :compression => true, :append_all_supported_algorithms => true)[:compression]
114
- end
115
-
116
- def test_constructor_with_unrecognized_compression_should_return_whats_supported
117
- assert_equal %w(none zlib zlib@openssh.com), algorithms(:compression => %w(bogus none zlib), :append_all_supported_algorithms => true)[:compression]
118
- end
119
-
120
- def test_initial_state_should_be_neither_pending_nor_initialized
121
- assert !algorithms.pending?
122
- assert !algorithms.initialized?
123
- end
124
-
125
- def test_key_exchange_when_initiated_by_server
126
- transport.expect do |t, buffer|
127
- assert_kexinit(buffer)
128
- install_mock_key_exchange(buffer)
129
- end
130
-
131
- install_mock_algorithm_lookups
132
- algorithms.accept_kexinit(kexinit)
133
-
134
- assert_exchange_results
135
- end
136
-
137
- def test_key_exchange_when_initiated_by_client
138
- state = nil
139
- transport.expect do |t, buffer|
140
- assert_kexinit(buffer)
141
- state = :sent_kexinit
142
- install_mock_key_exchange(buffer)
143
- end
144
-
145
- algorithms.rekey!
146
- assert_equal state, :sent_kexinit
147
- assert algorithms.pending?
148
-
149
- install_mock_algorithm_lookups
150
- algorithms.accept_kexinit(kexinit)
151
-
152
- assert_exchange_results
153
- end
154
-
155
- def test_key_exchange_when_server_does_not_support_preferred_kex_should_fallback_to_secondary
156
- kexinit :kex => "diffie-hellman-group1-sha1"
157
- transport.expect do |t,buffer|
158
- assert_kexinit(buffer)
159
- install_mock_key_exchange(buffer, :kex => Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1)
160
- end
161
- algorithms.accept_kexinit(kexinit)
162
- end
163
-
164
- def test_key_exchange_when_server_does_not_support_any_preferred_kex_should_raise_error
165
- kexinit :kex => "something-obscure"
166
- transport.expect { |t,buffer| assert_kexinit(buffer) }
167
- assert_raises(Net::SSH::Exception) { algorithms.accept_kexinit(kexinit) }
168
- end
169
-
170
- def test_allow_when_not_pending_should_be_true_for_all_packets
171
- (0..255).each do |type|
172
- packet = stub("packet", :type => type)
173
- assert algorithms.allow?(packet), type.to_s
174
- end
175
- end
176
-
177
- def test_allow_when_pending_should_be_true_only_for_packets_valid_during_key_exchange
178
- transport.expect!
179
- algorithms.rekey!
180
- assert algorithms.pending?
181
-
182
- (0..255).each do |type|
183
- packet = stub("packet", :type => type)
184
- case type
185
- when 1..4, 6..19, 21..49 then assert(algorithms.allow?(packet), "#{type} should be allowed during key exchange")
186
- else assert(!algorithms.allow?(packet), "#{type} should not be allowed during key exchange")
187
- end
188
- end
189
- end
190
-
191
- def test_exchange_with_zlib_compression_enabled_sets_compression_to_standard
192
- algorithms :compression => "zlib", :append_all_supported_algorithms => true
193
-
194
- transport.expect do |t, buffer|
195
- assert_kexinit(buffer, :compression_client => "zlib,none,zlib@openssh.com", :compression_server => "zlib,none,zlib@openssh.com")
196
- install_mock_key_exchange(buffer)
197
- end
198
-
199
- install_mock_algorithm_lookups
200
- algorithms.accept_kexinit(kexinit)
201
-
202
- assert_equal :standard, transport.client_options[:compression]
203
- assert_equal :standard, transport.server_options[:compression]
204
- end
205
-
206
- def test_exchange_with_zlib_at_openssh_dot_com_compression_enabled_sets_compression_to_delayed
207
- algorithms :compression => "zlib@openssh.com", :append_all_supported_algorithms => true
208
-
209
- transport.expect do |t, buffer|
210
- assert_kexinit(buffer, :compression_client => "zlib@openssh.com,none,zlib", :compression_server => "zlib@openssh.com,none,zlib")
211
- install_mock_key_exchange(buffer)
212
- end
213
-
214
- install_mock_algorithm_lookups
215
- algorithms.accept_kexinit(kexinit)
216
-
217
- assert_equal :delayed, transport.client_options[:compression]
218
- assert_equal :delayed, transport.server_options[:compression]
219
- end
220
-
221
- private
222
-
223
- def install_mock_key_exchange(buffer, options={})
224
- kex = options[:kex] || Net::SSH::Transport::Kex::DiffieHellmanGroupExchangeSHA1
225
-
226
- Net::SSH::Transport::Kex::MAP.each do |name, klass|
227
- next if klass == kex
228
- klass.expects(:new).never
229
- end
230
-
231
- kex.expects(:new).
232
- with(algorithms, transport,
233
- :client_version_string => Net::SSH::Transport::ServerVersion::PROTO_VERSION,
234
- :server_version_string => transport.server_version.version,
235
- :server_algorithm_packet => kexinit.to_s,
236
- :client_algorithm_packet => buffer.to_s,
237
- :need_bytes => 20,
238
- :logger => nil).
239
- returns(stub("kex", :exchange_keys => { :shared_secret => shared_secret, :session_id => session_id, :hashing_algorithm => hashing_algorithm }))
240
- end
241
-
242
- def install_mock_algorithm_lookups(options={})
243
- params = { :shared => shared_secret.to_ssh, :hash => session_id, :digester => hashing_algorithm }
244
- Net::SSH::Transport::CipherFactory.expects(:get).
245
- with(options[:client_cipher] || "aes128-cbc", params.merge(:iv => key("A"), :key => key("C"), :encrypt => true)).
246
- returns(:client_cipher)
247
-
248
- Net::SSH::Transport::CipherFactory.expects(:get).
249
- with(options[:server_cipher] || "aes128-cbc", params.merge(:iv => key("B"), :key => key("D"), :decrypt => true)).
250
- returns(:server_cipher)
251
-
252
- Net::SSH::Transport::HMAC.expects(:get).with(options[:client_hmac] || "hmac-sha1", key("E"), params).returns(:client_hmac)
253
- Net::SSH::Transport::HMAC.expects(:get).with(options[:server_hmac] || "hmac-sha1", key("F"), params).returns(:server_hmac)
254
- end
255
-
256
- def shared_secret
257
- @shared_secret ||= OpenSSL::BN.new("1234567890", 10)
258
- end
259
-
260
- def session_id
261
- @session_id ||= "this is the session id"
262
- end
263
-
264
- def hashing_algorithm
265
- OpenSSL::Digest::SHA1
266
- end
267
-
268
- def key(salt)
269
- hashing_algorithm.digest(shared_secret.to_ssh + session_id + salt + session_id)
270
- end
271
-
272
- def cipher(type, options={})
273
- Net::SSH::Transport::CipherFactory.get(type, options)
274
- end
275
-
276
- def kexinit(options={})
277
- @kexinit ||= P(:byte, KEXINIT,
278
- :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF),
279
- :string, options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha256",
280
- :string, options[:host_key] || "ssh-rsa,ssh-dss",
281
- :string, options[:encryption_client] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
282
- :string, options[:encryption_server] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
283
- :string, options[:hmac_client] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96",
284
- :string, options[:hmac_server] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96",
285
- :string, options[:compression_client] || "none,zlib@openssh.com,zlib",
286
- :string, options[:compression_server] || "none,zlib@openssh.com,zlib",
287
- :string, options[:language_client] || "",
288
- :string, options[:langauge_server] || "",
289
- :bool, options[:first_kex_follows])
290
- end
291
-
292
- def assert_kexinit(buffer, options={})
293
- assert_equal KEXINIT, buffer.type
294
- assert_equal 16, buffer.read(16).length
295
- assert_equal options[:kex] || (%w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256)+ec_kex).join(','), buffer.read_string
296
- assert_equal options[:host_key] || (%w(ssh-rsa ssh-dss ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com)+ec_host_keys).join(','), buffer.read_string
297
- 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
298
- 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
299
- 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
300
- 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
301
- assert_equal options[:compression_client] || "none,zlib@openssh.com,zlib", buffer.read_string
302
- assert_equal options[:compression_server] || "none,zlib@openssh.com,zlib", buffer.read_string
303
- assert_equal options[:language_client] || "", buffer.read_string
304
- assert_equal options[:language_server] || "", buffer.read_string
305
- assert_equal options[:first_kex_follows] || false, buffer.read_bool
306
- end
307
-
308
- def assert_exchange_results
309
- assert algorithms.initialized?
310
- assert !algorithms.pending?
311
- assert !transport.client_options[:compression]
312
- assert !transport.server_options[:compression]
313
- assert_equal :client_cipher, transport.client_options[:cipher]
314
- assert_equal :server_cipher, transport.server_options[:cipher]
315
- assert_equal :client_hmac, transport.client_options[:hmac]
316
- assert_equal :server_hmac, transport.server_options[:hmac]
317
- end
318
-
319
- def algorithms(options={})
320
- @algorithms ||= Net::SSH::Transport::Algorithms.new(transport, options)
321
- end
322
-
323
- def transport
324
- @transport ||= MockTransport.new
325
- end
326
- end
327
-
328
- end