sonixlabs-net-ssh 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. data/CHANGELOG.rdoc +262 -0
  2. data/Manifest +121 -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 +179 -0
  9. data/lib/net/ssh/authentication/constants.rb +18 -0
  10. data/lib/net/ssh/authentication/key_manager.rb +253 -0
  11. data/lib/net/ssh/authentication/methods/abstract.rb +60 -0
  12. data/lib/net/ssh/authentication/methods/hostbased.rb +75 -0
  13. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +70 -0
  14. data/lib/net/ssh/authentication/methods/password.rb +43 -0
  15. data/lib/net/ssh/authentication/methods/publickey.rb +96 -0
  16. data/lib/net/ssh/authentication/pageant.rb +264 -0
  17. data/lib/net/ssh/authentication/session.rb +146 -0
  18. data/lib/net/ssh/buffer.rb +340 -0
  19. data/lib/net/ssh/buffered_io.rb +198 -0
  20. data/lib/net/ssh/config.rb +207 -0
  21. data/lib/net/ssh/connection/channel.rb +630 -0
  22. data/lib/net/ssh/connection/constants.rb +33 -0
  23. data/lib/net/ssh/connection/session.rb +597 -0
  24. data/lib/net/ssh/connection/term.rb +178 -0
  25. data/lib/net/ssh/errors.rb +88 -0
  26. data/lib/net/ssh/key_factory.rb +102 -0
  27. data/lib/net/ssh/known_hosts.rb +129 -0
  28. data/lib/net/ssh/loggable.rb +61 -0
  29. data/lib/net/ssh/packet.rb +102 -0
  30. data/lib/net/ssh/prompt.rb +93 -0
  31. data/lib/net/ssh/proxy/command.rb +75 -0
  32. data/lib/net/ssh/proxy/errors.rb +14 -0
  33. data/lib/net/ssh/proxy/http.rb +94 -0
  34. data/lib/net/ssh/proxy/socks4.rb +70 -0
  35. data/lib/net/ssh/proxy/socks5.rb +142 -0
  36. data/lib/net/ssh/ruby_compat.rb +43 -0
  37. data/lib/net/ssh/service/forward.rb +298 -0
  38. data/lib/net/ssh/test.rb +89 -0
  39. data/lib/net/ssh/test/channel.rb +129 -0
  40. data/lib/net/ssh/test/extensions.rb +152 -0
  41. data/lib/net/ssh/test/kex.rb +44 -0
  42. data/lib/net/ssh/test/local_packet.rb +51 -0
  43. data/lib/net/ssh/test/packet.rb +81 -0
  44. data/lib/net/ssh/test/remote_packet.rb +38 -0
  45. data/lib/net/ssh/test/script.rb +157 -0
  46. data/lib/net/ssh/test/socket.rb +64 -0
  47. data/lib/net/ssh/transport/algorithms.rb +386 -0
  48. data/lib/net/ssh/transport/cipher_factory.rb +79 -0
  49. data/lib/net/ssh/transport/constants.rb +30 -0
  50. data/lib/net/ssh/transport/hmac.rb +42 -0
  51. data/lib/net/ssh/transport/hmac/abstract.rb +79 -0
  52. data/lib/net/ssh/transport/hmac/md5.rb +12 -0
  53. data/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  54. data/lib/net/ssh/transport/hmac/none.rb +15 -0
  55. data/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  56. data/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  57. data/lib/net/ssh/transport/hmac/sha2_256.rb +15 -0
  58. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +13 -0
  59. data/lib/net/ssh/transport/hmac/sha2_512.rb +14 -0
  60. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +13 -0
  61. data/lib/net/ssh/transport/identity_cipher.rb +55 -0
  62. data/lib/net/ssh/transport/kex.rb +17 -0
  63. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +208 -0
  64. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +80 -0
  65. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +15 -0
  66. data/lib/net/ssh/transport/key_expander.rb +26 -0
  67. data/lib/net/ssh/transport/openssl.rb +127 -0
  68. data/lib/net/ssh/transport/packet_stream.rb +235 -0
  69. data/lib/net/ssh/transport/server_version.rb +71 -0
  70. data/lib/net/ssh/transport/session.rb +278 -0
  71. data/lib/net/ssh/transport/state.rb +206 -0
  72. data/lib/net/ssh/verifiers/lenient.rb +30 -0
  73. data/lib/net/ssh/verifiers/null.rb +12 -0
  74. data/lib/net/ssh/verifiers/strict.rb +53 -0
  75. data/lib/net/ssh/version.rb +62 -0
  76. data/lib/sonixlabs-net-ssh.rb +1 -0
  77. data/net-ssh.gemspec +145 -0
  78. data/setup.rb +1585 -0
  79. data/support/arcfour_check.rb +20 -0
  80. data/support/ssh_tunnel_bug.rb +65 -0
  81. data/test/authentication/methods/common.rb +28 -0
  82. data/test/authentication/methods/test_abstract.rb +51 -0
  83. data/test/authentication/methods/test_hostbased.rb +114 -0
  84. data/test/authentication/methods/test_keyboard_interactive.rb +100 -0
  85. data/test/authentication/methods/test_password.rb +52 -0
  86. data/test/authentication/methods/test_publickey.rb +148 -0
  87. data/test/authentication/test_agent.rb +205 -0
  88. data/test/authentication/test_key_manager.rb +171 -0
  89. data/test/authentication/test_session.rb +106 -0
  90. data/test/common.rb +107 -0
  91. data/test/configs/eqsign +3 -0
  92. data/test/configs/exact_match +8 -0
  93. data/test/configs/host_plus +10 -0
  94. data/test/configs/multihost +4 -0
  95. data/test/configs/wild_cards +14 -0
  96. data/test/connection/test_channel.rb +467 -0
  97. data/test/connection/test_session.rb +488 -0
  98. data/test/test_all.rb +9 -0
  99. data/test/test_buffer.rb +336 -0
  100. data/test/test_buffered_io.rb +63 -0
  101. data/test/test_config.rb +120 -0
  102. data/test/test_key_factory.rb +79 -0
  103. data/test/transport/hmac/test_md5.rb +39 -0
  104. data/test/transport/hmac/test_md5_96.rb +25 -0
  105. data/test/transport/hmac/test_none.rb +34 -0
  106. data/test/transport/hmac/test_sha1.rb +34 -0
  107. data/test/transport/hmac/test_sha1_96.rb +25 -0
  108. data/test/transport/hmac/test_sha2_256.rb +35 -0
  109. data/test/transport/hmac/test_sha2_256_96.rb +25 -0
  110. data/test/transport/hmac/test_sha2_512.rb +35 -0
  111. data/test/transport/hmac/test_sha2_512_96.rb +25 -0
  112. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  113. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  114. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +33 -0
  115. data/test/transport/test_algorithms.rb +308 -0
  116. data/test/transport/test_cipher_factory.rb +213 -0
  117. data/test/transport/test_hmac.rb +34 -0
  118. data/test/transport/test_identity_cipher.rb +40 -0
  119. data/test/transport/test_packet_stream.rb +736 -0
  120. data/test/transport/test_server_version.rb +78 -0
  121. data/test/transport/test_session.rb +315 -0
  122. data/test/transport/test_state.rb +179 -0
  123. metadata +178 -0
@@ -0,0 +1,79 @@
1
+ require 'common'
2
+ require 'net/ssh/key_factory'
3
+
4
+ class TestKeyFactory < Test::Unit::TestCase
5
+ def setup
6
+ @key_file = File.expand_path("/key-file")
7
+ end
8
+
9
+ def test_load_unencrypted_private_RSA_key_should_return_key
10
+ File.expects(:read).with(@key_file).returns(rsa_key.export)
11
+ assert_equal rsa_key.to_der, Net::SSH::KeyFactory.load_private_key(@key_file).to_der
12
+ end
13
+
14
+ def test_load_unencrypted_private_DSA_key_should_return_key
15
+ File.expects(:read).with(@key_file).returns(dsa_key.export)
16
+ assert_equal dsa_key.to_der, Net::SSH::KeyFactory.load_private_key(@key_file).to_der
17
+ end
18
+
19
+ def test_load_encrypted_private_RSA_key_should_prompt_for_password_and_return_key
20
+ File.expects(:read).with(@key_file).returns(encrypted(rsa_key, "password"))
21
+ Net::SSH::KeyFactory.expects(:prompt).with("Enter passphrase for #{@key_file}:", false).returns("password")
22
+ assert_equal rsa_key.to_der, Net::SSH::KeyFactory.load_private_key(@key_file).to_der
23
+ end
24
+
25
+ def test_load_encrypted_private_RSA_key_with_password_should_not_prompt_and_return_key
26
+ File.expects(:read).with(@key_file).returns(encrypted(rsa_key, "password"))
27
+ assert_equal rsa_key.to_der, Net::SSH::KeyFactory.load_private_key(@key_file, "password").to_der
28
+ end
29
+
30
+ def test_load_encrypted_private_DSA_key_should_prompt_for_password_and_return_key
31
+ File.expects(:read).with(@key_file).returns(encrypted(dsa_key, "password"))
32
+ Net::SSH::KeyFactory.expects(:prompt).with("Enter passphrase for #{@key_file}:", false).returns("password")
33
+ assert_equal dsa_key.to_der, Net::SSH::KeyFactory.load_private_key(@key_file).to_der
34
+ end
35
+
36
+ def test_load_encrypted_private_DSA_key_with_password_should_not_prompt_and_return_key
37
+ File.expects(:read).with(@key_file).returns(encrypted(dsa_key, "password"))
38
+ assert_equal dsa_key.to_der, Net::SSH::KeyFactory.load_private_key(@key_file, "password").to_der
39
+ end
40
+
41
+ def test_load_encrypted_private_key_should_give_three_tries_for_the_password_and_then_raise_exception
42
+ File.expects(:read).with(@key_file).returns(encrypted(rsa_key, "password"))
43
+ Net::SSH::KeyFactory.expects(:prompt).times(3).with("Enter passphrase for #{@key_file}:", false).returns("passwod","passphrase","passwd")
44
+ assert_raises(OpenSSL::PKey::RSAError) { Net::SSH::KeyFactory.load_private_key(@key_file) }
45
+ end
46
+
47
+ def test_load_encrypted_private_key_should_raise_exception_without_asking_passphrase
48
+ File.expects(:read).with(@key_file).returns(encrypted(rsa_key, "password"))
49
+ Net::SSH::KeyFactory.expects(:prompt).never
50
+ assert_raises(OpenSSL::PKey::RSAError) { Net::SSH::KeyFactory.load_private_key(@key_file, nil, false) }
51
+ end
52
+
53
+ def test_load_public_rsa_key_should_return_key
54
+ File.expects(:read).with(@key_file).returns(public(rsa_key))
55
+ assert_equal rsa_key.to_blob, Net::SSH::KeyFactory.load_public_key(@key_file).to_blob
56
+ end
57
+
58
+ private
59
+
60
+ def rsa_key
61
+ # 512 bits
62
+ @rsa_key ||= OpenSSL::PKey::RSA.new("0\202\001;\002\001\000\002A\000\235\236\374N\e@2E\321\3757\003\354c\276N\f\003\3479Ko\005\317\0027\a\255=\345!\306\220\340\211;\027u\331\260\362\2063x\332\301y4\353\v%\032\214v\312\304\212\271GJ\353\2701\031\002\003\001\000\001\002@\022Y\306*\031\306\031\224Cde\231QV3{\306\256U\2477\377\017\000\020\323\363R\332\027\351\034\224OU\020\227H|pUS\n\263+%\304\341\321\273/\271\e\004L\250\273\020&,\t\304By\002!\000\311c\246%a\002\305\277\262R\266\244\250\025V_\351]\264\016\265\341\355\305\223\347Z$8\205#\023\002!\000\310\\\367|\243I\363\350\020\307\246\302\365\ed\212L\273\2158M\223w\a\367 C\t\224A4\243\002!\000\262]+}\327\231\331\002\2331^\312\036\204'g\363\f&\271\020\245\365-\024}\306\374e\202\2459\002 }\231\341\276\3551\277\307{5\\\361\233\353G\024wS\237\fk}\004\302&\205\277\340rb\211\327\002!\000\223\307\025I:\215_\260\370\252\3757\256Y&X\364\354\342\215\350\203E8\227|\f\237M\375D|")
63
+ end
64
+
65
+ def dsa_key
66
+ # 512 bits
67
+ @dsa_key ||= OpenSSL::PKey::DSA.new("0\201\367\002\001\000\002A\000\203\316/\037u\272&J\265\003l3\315d\324h\372{\t8\252#\331_\026\006\035\270\266\255\343\353Z\302\276\335\336\306\220\375\202L\244\244J\206>\346\b\315\211\302L\246x\247u\a\376\366\345\302\016#\002\025\000\244\274\302\221Og\275/\302+\356\346\360\024\373wI\2573\361\002@\027\215\270r*\f\213\350C\245\021:\350 \006\\\376\345\022`\210b\262\3643\023XLKS\320\370\002\276\347A\nU\204\276\324\256`=\026\240\330\306J\316V\213\024\e\030\215\355\006\037q\337\356ln\002@\017\257\034\f\260\333'S\271#\237\230E\321\312\027\021\226\331\251Vj\220\305\316\036\v\266+\000\230\270\177B\003?t\a\305]e\344\261\334\023\253\323\251\223M\2175)a(\004\"lI8\312\303\307\a\002\024_\aznW\345\343\203V\326\246ua\203\376\201o\350\302\002")
68
+ end
69
+
70
+ def encrypted(key, password)
71
+ key.export(OpenSSL::Cipher::Cipher.new("des-ede3-cbc"), password)
72
+ end
73
+
74
+ def public(key)
75
+ result = "#{key.ssh_type} "
76
+ result << [Net::SSH::Buffer.from(:key, key).to_s].pack("m*").strip.tr("\n\r\t ", "")
77
+ result << " joe@host.test"
78
+ end
79
+ end
@@ -0,0 +1,39 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/hmac/md5'
3
+
4
+ module Transport; module HMAC
5
+
6
+ class TestMD5 < Test::Unit::TestCase
7
+ def test_expected_digest_class
8
+ assert_equal OpenSSL::Digest::MD5, subject.digest_class
9
+ assert_equal OpenSSL::Digest::MD5, subject.new.digest_class
10
+ end
11
+
12
+ def test_expected_key_length
13
+ assert_equal 16, subject.key_length
14
+ assert_equal 16, subject.new.key_length
15
+ end
16
+
17
+ def test_expected_mac_length
18
+ assert_equal 16, subject.mac_length
19
+ assert_equal 16, subject.new.mac_length
20
+ end
21
+
22
+ def test_expected_digest
23
+ hmac = subject.new("1234567890123456")
24
+ assert_equal "\275\345\006\307y~Oi\035<.\341\031\250<\257", hmac.digest("hello world")
25
+ end
26
+
27
+ def test_key_should_be_truncated_to_required_length
28
+ hmac = subject.new("12345678901234567890")
29
+ assert_equal "1234567890123456", hmac.key
30
+ end
31
+
32
+ private
33
+
34
+ def subject
35
+ Net::SSH::Transport::HMAC::MD5
36
+ end
37
+ end
38
+
39
+ end; end
@@ -0,0 +1,25 @@
1
+ require 'common'
2
+ require 'transport/hmac/test_md5'
3
+ require 'net/ssh/transport/hmac/md5_96'
4
+
5
+ module Transport; module HMAC
6
+
7
+ class TestMD5_96 < TestMD5
8
+ def test_expected_mac_length
9
+ assert_equal 12, subject.mac_length
10
+ assert_equal 12, subject.new.mac_length
11
+ end
12
+
13
+ def test_expected_digest
14
+ hmac = subject.new("1234567890123456")
15
+ assert_equal "\275\345\006\307y~Oi\035<.\341", hmac.digest("hello world")
16
+ end
17
+
18
+ private
19
+
20
+ def subject
21
+ Net::SSH::Transport::HMAC::MD5_96
22
+ end
23
+ end
24
+
25
+ end; end
@@ -0,0 +1,34 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/hmac/none'
3
+
4
+ module Transport; module HMAC
5
+
6
+ class TestNone < Test::Unit::TestCase
7
+ def test_expected_digest_class
8
+ assert_equal nil, subject.digest_class
9
+ assert_equal nil, subject.new.digest_class
10
+ end
11
+
12
+ def test_expected_key_length
13
+ assert_equal 0, subject.key_length
14
+ assert_equal 0, subject.new.key_length
15
+ end
16
+
17
+ def test_expected_mac_length
18
+ assert_equal 0, subject.mac_length
19
+ assert_equal 0, subject.new.mac_length
20
+ end
21
+
22
+ def test_expected_digest
23
+ hmac = subject.new("1234567890123456")
24
+ assert_equal "", hmac.digest("hello world")
25
+ end
26
+
27
+ private
28
+
29
+ def subject
30
+ Net::SSH::Transport::HMAC::None
31
+ end
32
+ end
33
+
34
+ end; end
@@ -0,0 +1,34 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/hmac/sha1'
3
+
4
+ module Transport; module HMAC
5
+
6
+ class TestSHA1 < Test::Unit::TestCase
7
+ def test_expected_digest_class
8
+ assert_equal OpenSSL::Digest::SHA1, subject.digest_class
9
+ assert_equal OpenSSL::Digest::SHA1, subject.new.digest_class
10
+ end
11
+
12
+ def test_expected_key_length
13
+ assert_equal 20, subject.key_length
14
+ assert_equal 20, subject.new.key_length
15
+ end
16
+
17
+ def test_expected_mac_length
18
+ assert_equal 20, subject.mac_length
19
+ assert_equal 20, subject.new.mac_length
20
+ end
21
+
22
+ def test_expected_digest
23
+ hmac = subject.new("1234567890123456")
24
+ assert_equal "\000\004W\202\204+&\335\311\251P\266\250\214\276\206;\022U\365", hmac.digest("hello world")
25
+ end
26
+
27
+ private
28
+
29
+ def subject
30
+ Net::SSH::Transport::HMAC::SHA1
31
+ end
32
+ end
33
+
34
+ end; end
@@ -0,0 +1,25 @@
1
+ require 'common'
2
+ require 'transport/hmac/test_sha1'
3
+ require 'net/ssh/transport/hmac/sha1_96'
4
+
5
+ module Transport; module HMAC
6
+
7
+ class TestSHA1_96 < TestSHA1
8
+ def test_expected_mac_length
9
+ assert_equal 12, subject.mac_length
10
+ assert_equal 12, subject.new.mac_length
11
+ end
12
+
13
+ def test_expected_digest
14
+ hmac = subject.new("1234567890123456")
15
+ assert_equal "\000\004W\202\204+&\335\311\251P\266", hmac.digest("hello world")
16
+ end
17
+
18
+ private
19
+
20
+ def subject
21
+ Net::SSH::Transport::HMAC::SHA1_96
22
+ end
23
+ end
24
+
25
+ end; end
@@ -0,0 +1,35 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/hmac/sha2_256'
3
+
4
+ module Transport; module HMAC
5
+
6
+ class TestSHA2_256 < Test::Unit::TestCase
7
+ def test_expected_digest_class
8
+ assert_equal OpenSSL::Digest::SHA256, subject.digest_class
9
+ assert_equal OpenSSL::Digest::SHA256, subject.new.digest_class
10
+ end
11
+
12
+ def test_expected_key_length
13
+ assert_equal 32, subject.key_length
14
+ assert_equal 32, subject.new.key_length
15
+ end
16
+
17
+ def test_expected_mac_length
18
+ assert_equal 32, subject.mac_length
19
+ assert_equal 32, subject.new.mac_length
20
+ end
21
+
22
+ def test_expected_digest
23
+ hmac = subject.new("1234567890123456")
24
+ assert_equal "\x16^>\x9FhO}\xB1>(\xBAF\xFBW\xB8\xF2\xFA\x824+\xC0\x94\x95\xC2\r\xE6\x88/\xEF\t\xF5%", hmac.digest("hello world")
25
+
26
+ end
27
+
28
+ private
29
+
30
+ def subject
31
+ Net::SSH::Transport::HMAC::SHA2_256
32
+ end
33
+ end
34
+
35
+ end; end
@@ -0,0 +1,25 @@
1
+ require 'common'
2
+ require 'transport/hmac/test_sha2_256'
3
+ require 'net/ssh/transport/hmac/sha2_256_96'
4
+
5
+ module Transport; module HMAC
6
+
7
+ class TestSHA2_256_96 < TestSHA2_256
8
+ def test_expected_mac_length
9
+ assert_equal 12, subject.mac_length
10
+ assert_equal 12, subject.new.mac_length
11
+ end
12
+
13
+ def test_expected_digest
14
+ hmac = subject.new("1234567890123456")
15
+ assert_equal "\x16^>\x9FhO}\xB1>(\xBAF", hmac.digest("hello world")
16
+ end
17
+
18
+ private
19
+
20
+ def subject
21
+ Net::SSH::Transport::HMAC::SHA2_256_96
22
+ end
23
+ end
24
+
25
+ end; end
@@ -0,0 +1,35 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/hmac/sha2_512'
3
+
4
+ module Transport; module HMAC
5
+
6
+ class TestSHA2_512 < Test::Unit::TestCase
7
+ def test_expected_digest_class
8
+ assert_equal OpenSSL::Digest::SHA512, subject.digest_class
9
+ assert_equal OpenSSL::Digest::SHA512, subject.new.digest_class
10
+ end
11
+
12
+ def test_expected_key_length
13
+ assert_equal 64, subject.key_length
14
+ assert_equal 64, subject.new.key_length
15
+ end
16
+
17
+ def test_expected_mac_length
18
+ assert_equal 64, subject.mac_length
19
+ assert_equal 64, subject.new.mac_length
20
+ end
21
+
22
+ def test_expected_digest
23
+ hmac = subject.new("1234567890123456")
24
+ assert_equal "^\xB6\"\xED\x8B\xC4\xDE\xD4\xCF\xD0\r\x18\xA0<\xF4\xB5\x01Efz\xA80i\xFC\x18\xC1\x9A+\xDD\xFE<\xA2\xFDE1Ac\xF4\xADU\r\xFB^0\x90= \x837z\xCC\xD5p4a4\x83\xC6\x04m\xAA\xC1\xC0m", hmac.digest("hello world")
25
+
26
+ end
27
+
28
+ private
29
+
30
+ def subject
31
+ Net::SSH::Transport::HMAC::SHA2_512
32
+ end
33
+ end
34
+
35
+ end; end
@@ -0,0 +1,25 @@
1
+ require 'common'
2
+ require 'transport/hmac/test_sha2_512'
3
+ require 'net/ssh/transport/hmac/sha2_512_96'
4
+
5
+ module Transport; module HMAC
6
+
7
+ class TestSHA2_512_96 < TestSHA2_512
8
+ def test_expected_mac_length
9
+ assert_equal 12, subject.mac_length
10
+ assert_equal 12, subject.new.mac_length
11
+ end
12
+
13
+ def test_expected_digest
14
+ hmac = subject.new("1234567890123456")
15
+ assert_equal "^\xB6\"\xED\x8B\xC4\xDE\xD4\xCF\xD0\r\x18", hmac.digest("hello world")
16
+ end
17
+
18
+ private
19
+
20
+ def subject
21
+ Net::SSH::Transport::HMAC::SHA2_512_96
22
+ end
23
+ end
24
+
25
+ end; end
@@ -0,0 +1,146 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
3
+ require 'ostruct'
4
+
5
+ module Transport; module Kex
6
+
7
+ class TestDiffieHellmanGroup1SHA1 < Test::Unit::TestCase
8
+ include Net::SSH::Transport::Constants
9
+
10
+ def setup
11
+ @dh_options = @dh = @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_key.to_blob, result[:server_key].to_blob
19
+ assert_equal shared_secret, result[:shared_secret]
20
+ assert_equal OpenSSL::Digest::SHA1, result[:hashing_algorithm]
21
+ end
22
+
23
+ def test_exchange_keys_with_unverifiable_host_should_raise_exception
24
+ connection.verifier { false }
25
+ assert_raises(Net::SSH::Exception) { exchange! }
26
+ end
27
+
28
+ def test_exchange_keys_with_signature_key_type_mismatch_should_raise_exception
29
+ assert_raises(Net::SSH::Exception) { exchange! :key_type => "ssh-dss" }
30
+ end
31
+
32
+ def test_exchange_keys_with_host_key_type_mismatch_should_raise_exception
33
+ algorithms :host_key => "ssh-dss"
34
+ assert_raises(Net::SSH::Exception) { exchange! :key_type => "ssh-dss" }
35
+ end
36
+
37
+ def test_exchange_keys_when_server_signature_could_not_be_verified_should_raise_exception
38
+ @signature = "1234567890"
39
+ assert_raises(Net::SSH::Exception) { exchange! }
40
+ end
41
+
42
+ def test_exchange_keys_should_pass_expected_parameters_to_host_key_verifier
43
+ verified = false
44
+ connection.verifier do |data|
45
+ verified = true
46
+ assert_equal server_key.to_blob, data[:key].to_blob
47
+
48
+ blob = b(:key, data[:key]).to_s
49
+ fingerprint = OpenSSL::Digest::MD5.hexdigest(blob).scan(/../).join(":")
50
+
51
+ assert_equal blob, data[:key_blob]
52
+ assert_equal fingerprint, data[:fingerprint]
53
+ assert_equal connection, data[:session]
54
+
55
+ true
56
+ end
57
+
58
+ assert_nothing_raised { exchange! }
59
+ assert verified
60
+ end
61
+
62
+ private
63
+
64
+ def exchange!(options={})
65
+ connection.expect do |t, buffer|
66
+ assert_equal KEXDH_INIT, buffer.type
67
+ assert_equal dh.dh.pub_key, buffer.read_bignum
68
+ t.return(KEXDH_REPLY, :string, b(:key, server_key), :bignum, server_dh_pubkey, :string, b(:string, options[:key_type] || "ssh-rsa", :string, signature))
69
+ connection.expect do |t2, buffer2|
70
+ assert_equal NEWKEYS, buffer2.type
71
+ t2.return(NEWKEYS)
72
+ end
73
+ end
74
+
75
+ dh.exchange_keys
76
+ end
77
+
78
+ def dh_options(options={})
79
+ @dh_options = options
80
+ end
81
+
82
+ def dh
83
+ @dh ||= subject.new(algorithms, connection, packet_data.merge(:need_bytes => 20).merge(@dh_options || {}))
84
+ end
85
+
86
+ def algorithms(options={})
87
+ @algorithms ||= OpenStruct.new(:host_key => options[:host_key] || "ssh-rsa")
88
+ end
89
+
90
+ def connection
91
+ @connection ||= MockTransport.new
92
+ end
93
+
94
+ def subject
95
+ Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1
96
+ end
97
+
98
+ # 512 bits is the smallest possible key that will work with this, so
99
+ # we use it for speed reasons
100
+ def server_key(bits=512)
101
+ @server_key ||= OpenSSL::PKey::RSA.new(bits)
102
+ end
103
+
104
+ def packet_data
105
+ @packet_data ||= { :client_version_string => "client version string",
106
+ :server_version_string => "server version string",
107
+ :server_algorithm_packet => "server algorithm packet",
108
+ :client_algorithm_packet => "client algorithm packet" }
109
+ end
110
+
111
+ def server_dh_pubkey
112
+ @server_dh_pubkey ||= bn(1234567890)
113
+ end
114
+
115
+ def shared_secret
116
+ @shared_secret ||= OpenSSL::BN.new(dh.dh.compute_key(server_dh_pubkey), 2)
117
+ end
118
+
119
+ def session_id
120
+ @session_id ||= begin
121
+ buffer = Net::SSH::Buffer.from(:string, packet_data[:client_version_string],
122
+ :string, packet_data[:server_version_string],
123
+ :string, packet_data[:client_algorithm_packet],
124
+ :string, packet_data[:server_algorithm_packet],
125
+ :string, Net::SSH::Buffer.from(:key, server_key),
126
+ :bignum, dh.dh.pub_key,
127
+ :bignum, server_dh_pubkey,
128
+ :bignum, shared_secret)
129
+ OpenSSL::Digest::SHA1.digest(buffer.to_s)
130
+ end
131
+ end
132
+
133
+ def signature
134
+ @signature ||= server_key.ssh_do_sign(session_id)
135
+ end
136
+
137
+ def bn(number, base=10)
138
+ OpenSSL::BN.new(number.to_s, base)
139
+ end
140
+
141
+ def b(*args)
142
+ Net::SSH::Buffer.from(*args)
143
+ end
144
+ end
145
+
146
+ end; end