net-ssh 0.5.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 (179) hide show
  1. data/doc/LICENSE-BSD +27 -0
  2. data/doc/LICENSE-GPL +280 -0
  3. data/doc/LICENSE-RUBY +56 -0
  4. data/doc/README +13 -0
  5. data/doc/manual-html/chapter-1.html +333 -0
  6. data/doc/manual-html/chapter-2.html +455 -0
  7. data/doc/manual-html/chapter-3.html +413 -0
  8. data/doc/manual-html/chapter-4.html +353 -0
  9. data/doc/manual-html/chapter-5.html +393 -0
  10. data/doc/manual-html/chapter-6.html +296 -0
  11. data/doc/manual-html/index.html +217 -0
  12. data/doc/manual-html/manual.css +192 -0
  13. data/doc/manual/chapter.erb +18 -0
  14. data/doc/manual/example.erb +18 -0
  15. data/doc/manual/index.erb +29 -0
  16. data/doc/manual/manual.css +192 -0
  17. data/doc/manual/manual.rb +240 -0
  18. data/doc/manual/manual.yml +67 -0
  19. data/doc/manual/page.erb +87 -0
  20. data/doc/manual/parts/channels_callbacks.txt +32 -0
  21. data/doc/manual/parts/channels_loop.txt +14 -0
  22. data/doc/manual/parts/channels_open.txt +20 -0
  23. data/doc/manual/parts/channels_operations.txt +15 -0
  24. data/doc/manual/parts/channels_types.txt +3 -0
  25. data/doc/manual/parts/channels_what_are.txt +7 -0
  26. data/doc/manual/parts/exec_channels.txt +28 -0
  27. data/doc/manual/parts/exec_open.txt +51 -0
  28. data/doc/manual/parts/exec_popen3.txt +35 -0
  29. data/doc/manual/parts/forward_direct.txt +37 -0
  30. data/doc/manual/parts/forward_handlers.txt +16 -0
  31. data/doc/manual/parts/forward_intro.txt +18 -0
  32. data/doc/manual/parts/forward_local.txt +18 -0
  33. data/doc/manual/parts/forward_remote.txt +14 -0
  34. data/doc/manual/parts/intro_author.txt +1 -0
  35. data/doc/manual/parts/intro_getting.txt +39 -0
  36. data/doc/manual/parts/intro_license.txt +6 -0
  37. data/doc/manual/parts/intro_support.txt +7 -0
  38. data/doc/manual/parts/intro_what_is.txt +7 -0
  39. data/doc/manual/parts/intro_what_is_not.txt +3 -0
  40. data/doc/manual/parts/proxy_http.txt +52 -0
  41. data/doc/manual/parts/proxy_intro.txt +1 -0
  42. data/doc/manual/parts/proxy_socks.txt +23 -0
  43. data/doc/manual/parts/session_key.txt +66 -0
  44. data/doc/manual/parts/session_options.txt +42 -0
  45. data/doc/manual/parts/session_session.txt +14 -0
  46. data/doc/manual/parts/session_start.txt +49 -0
  47. data/doc/manual/tutorial.erb +30 -0
  48. data/examples/channel-demo.rb +81 -0
  49. data/examples/port-forward.rb +51 -0
  50. data/examples/process-demo.rb +91 -0
  51. data/examples/remote-net-port-forward.rb +45 -0
  52. data/examples/remote-port-forward.rb +80 -0
  53. data/examples/tail-demo.rb +49 -0
  54. data/lib/net/ssh.rb +52 -0
  55. data/lib/net/ssh/connection/channel.rb +411 -0
  56. data/lib/net/ssh/connection/constants.rb +47 -0
  57. data/lib/net/ssh/connection/driver.rb +343 -0
  58. data/lib/net/ssh/connection/services.rb +72 -0
  59. data/lib/net/ssh/connection/term.rb +90 -0
  60. data/lib/net/ssh/errors.rb +27 -0
  61. data/lib/net/ssh/proxy/errors.rb +34 -0
  62. data/lib/net/ssh/proxy/http.rb +126 -0
  63. data/lib/net/ssh/proxy/socks4.rb +83 -0
  64. data/lib/net/ssh/proxy/socks5.rb +160 -0
  65. data/lib/net/ssh/service/forward/driver.rb +319 -0
  66. data/lib/net/ssh/service/forward/local-network-handler.rb +74 -0
  67. data/lib/net/ssh/service/forward/remote-network-handler.rb +81 -0
  68. data/lib/net/ssh/service/forward/services.rb +76 -0
  69. data/lib/net/ssh/service/process/driver.rb +153 -0
  70. data/lib/net/ssh/service/process/open.rb +193 -0
  71. data/lib/net/ssh/service/process/popen3.rb +160 -0
  72. data/lib/net/ssh/service/process/services.rb +66 -0
  73. data/lib/net/ssh/service/services.rb +44 -0
  74. data/lib/net/ssh/session.rb +242 -0
  75. data/lib/net/ssh/transport/algorithm-negotiator.rb +267 -0
  76. data/lib/net/ssh/transport/compress/compressor.rb +53 -0
  77. data/lib/net/ssh/transport/compress/decompressor.rb +53 -0
  78. data/lib/net/ssh/transport/compress/none-compressor.rb +39 -0
  79. data/lib/net/ssh/transport/compress/none-decompressor.rb +39 -0
  80. data/lib/net/ssh/transport/compress/services.rb +68 -0
  81. data/lib/net/ssh/transport/compress/zlib-compressor.rb +60 -0
  82. data/lib/net/ssh/transport/compress/zlib-decompressor.rb +52 -0
  83. data/lib/net/ssh/transport/constants.rb +66 -0
  84. data/lib/net/ssh/transport/errors.rb +47 -0
  85. data/lib/net/ssh/transport/identity-cipher.rb +61 -0
  86. data/lib/net/ssh/transport/kex/dh-gex.rb +106 -0
  87. data/lib/net/ssh/transport/kex/dh.rb +231 -0
  88. data/lib/net/ssh/transport/kex/services.rb +60 -0
  89. data/lib/net/ssh/transport/ossl/buffer-factory.rb +52 -0
  90. data/lib/net/ssh/transport/ossl/buffer.rb +87 -0
  91. data/lib/net/ssh/transport/ossl/cipher-factory.rb +98 -0
  92. data/lib/net/ssh/transport/ossl/digest-factory.rb +51 -0
  93. data/lib/net/ssh/transport/ossl/hmac-factory.rb +71 -0
  94. data/lib/net/ssh/transport/ossl/hmac/hmac.rb +62 -0
  95. data/lib/net/ssh/transport/ossl/hmac/md5-96.rb +44 -0
  96. data/lib/net/ssh/transport/ossl/hmac/md5.rb +46 -0
  97. data/lib/net/ssh/transport/ossl/hmac/none.rb +46 -0
  98. data/lib/net/ssh/transport/ossl/hmac/services.rb +68 -0
  99. data/lib/net/ssh/transport/ossl/hmac/sha1-96.rb +44 -0
  100. data/lib/net/ssh/transport/ossl/hmac/sha1.rb +45 -0
  101. data/lib/net/ssh/transport/ossl/key-factory.rb +113 -0
  102. data/lib/net/ssh/transport/ossl/services.rb +149 -0
  103. data/lib/net/ssh/transport/packet-stream.rb +210 -0
  104. data/lib/net/ssh/transport/services.rb +146 -0
  105. data/lib/net/ssh/transport/session.rb +296 -0
  106. data/lib/net/ssh/transport/version-negotiator.rb +73 -0
  107. data/lib/net/ssh/userauth/agent.rb +218 -0
  108. data/lib/net/ssh/userauth/constants.rb +35 -0
  109. data/lib/net/ssh/userauth/driver.rb +176 -0
  110. data/lib/net/ssh/userauth/methods/hostbased.rb +119 -0
  111. data/lib/net/ssh/userauth/methods/password.rb +70 -0
  112. data/lib/net/ssh/userauth/methods/publickey.rb +137 -0
  113. data/lib/net/ssh/userauth/methods/services.rb +63 -0
  114. data/lib/net/ssh/userauth/services.rb +126 -0
  115. data/lib/net/ssh/userauth/userkeys.rb +258 -0
  116. data/lib/net/ssh/util/buffer.rb +274 -0
  117. data/lib/net/ssh/util/openssl.rb +146 -0
  118. data/lib/net/ssh/util/prompter.rb +73 -0
  119. data/lib/net/ssh/version.rb +29 -0
  120. data/test/ALL-TESTS.rb +21 -0
  121. data/test/connection/tc_channel.rb +136 -0
  122. data/test/connection/tc_driver.rb +287 -0
  123. data/test/connection/tc_integration.rb +85 -0
  124. data/test/proxy/tc_http.rb +209 -0
  125. data/test/proxy/tc_socks4.rb +148 -0
  126. data/test/proxy/tc_socks5.rb +214 -0
  127. data/test/service/forward/tc_driver.rb +289 -0
  128. data/test/service/forward/tc_local_network_handler.rb +123 -0
  129. data/test/service/forward/tc_remote_network_handler.rb +108 -0
  130. data/test/service/process/tc_driver.rb +79 -0
  131. data/test/service/process/tc_integration.rb +117 -0
  132. data/test/service/process/tc_open.rb +179 -0
  133. data/test/service/process/tc_popen3.rb +164 -0
  134. data/test/tc_integration.rb +79 -0
  135. data/test/transport/compress/tc_none_compress.rb +41 -0
  136. data/test/transport/compress/tc_none_decompress.rb +45 -0
  137. data/test/transport/compress/tc_zlib_compress.rb +61 -0
  138. data/test/transport/compress/tc_zlib_decompress.rb +48 -0
  139. data/test/transport/kex/tc_dh.rb +304 -0
  140. data/test/transport/kex/tc_dh_gex.rb +70 -0
  141. data/test/transport/ossl/fixtures/dsa-encrypted +15 -0
  142. data/test/transport/ossl/fixtures/dsa-encrypted-bad +15 -0
  143. data/test/transport/ossl/fixtures/dsa-unencrypted +12 -0
  144. data/test/transport/ossl/fixtures/dsa-unencrypted-bad +12 -0
  145. data/test/transport/ossl/fixtures/dsa-unencrypted.pub +1 -0
  146. data/test/transport/ossl/fixtures/not-a-private-key +4 -0
  147. data/test/transport/ossl/fixtures/not-supported +2 -0
  148. data/test/transport/ossl/fixtures/rsa-encrypted +18 -0
  149. data/test/transport/ossl/fixtures/rsa-encrypted-bad +18 -0
  150. data/test/transport/ossl/fixtures/rsa-unencrypted +15 -0
  151. data/test/transport/ossl/fixtures/rsa-unencrypted-bad +15 -0
  152. data/test/transport/ossl/fixtures/rsa-unencrypted.pub +1 -0
  153. data/test/transport/ossl/hmac/tc_hmac.rb +58 -0
  154. data/test/transport/ossl/hmac/tc_md5.rb +50 -0
  155. data/test/transport/ossl/hmac/tc_md5_96.rb +50 -0
  156. data/test/transport/ossl/hmac/tc_none.rb +50 -0
  157. data/test/transport/ossl/hmac/tc_sha1.rb +50 -0
  158. data/test/transport/ossl/hmac/tc_sha1_96.rb +50 -0
  159. data/test/transport/ossl/tc_buffer.rb +97 -0
  160. data/test/transport/ossl/tc_buffer_factory.rb +67 -0
  161. data/test/transport/ossl/tc_cipher_factory.rb +84 -0
  162. data/test/transport/ossl/tc_digest_factory.rb +39 -0
  163. data/test/transport/ossl/tc_hmac_factory.rb +72 -0
  164. data/test/transport/ossl/tc_key_factory.rb +199 -0
  165. data/test/transport/tc_algorithm_negotiator.rb +169 -0
  166. data/test/transport/tc_identity_cipher.rb +52 -0
  167. data/test/transport/tc_integration.rb +110 -0
  168. data/test/transport/tc_packet_stream.rb +183 -0
  169. data/test/transport/tc_session.rb +283 -0
  170. data/test/transport/tc_version_negotiator.rb +86 -0
  171. data/test/userauth/methods/tc_hostbased.rb +136 -0
  172. data/test/userauth/methods/tc_password.rb +89 -0
  173. data/test/userauth/methods/tc_publickey.rb +167 -0
  174. data/test/userauth/tc_agent.rb +223 -0
  175. data/test/userauth/tc_driver.rb +190 -0
  176. data/test/userauth/tc_integration.rb +81 -0
  177. data/test/userauth/tc_userkeys.rb +265 -0
  178. data/test/util/tc_buffer.rb +217 -0
  179. metadata +256 -0
@@ -0,0 +1,79 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../lib"
18
+
19
+ if $run_integration_tests || __FILE__ == $0
20
+
21
+ require 'net/ssh/session'
22
+ require 'test/unit'
23
+
24
+ class TC_Integration < Test::Unit::TestCase
25
+
26
+ HOST = "test.host"
27
+ USER = "test"
28
+ PASSWORD = "test/unit"
29
+ SESS_OPTS = {
30
+ :registry_options => {
31
+ :logs => {
32
+ :device => STDOUT,
33
+ :default_level => :warn
34
+ }
35
+ }
36
+ }
37
+
38
+ def setup
39
+ @session = Net::SSH::Session.new( HOST, USER, PASSWORD, SESS_OPTS )
40
+ end
41
+
42
+ def teardown
43
+ @session.close
44
+ end
45
+
46
+ def test_no_auth
47
+ assert_raise( Net::SSH::AuthenticationFailed ) do
48
+ Net::SSH::Session.new( HOST, USER, PASSWORD+"K", SESS_OPTS )
49
+ end
50
+ end
51
+
52
+ def test_exec
53
+ exec_data = ""
54
+ @session.open_channel do |chan|
55
+ chan.on_data { |ch,data| exec_data << data }
56
+ chan.exec "echo $HOME"
57
+ end
58
+ @session.loop
59
+ assert_equal "/home/test\n", exec_data
60
+ end
61
+
62
+ def test_dialog
63
+ dialog = [ "2+2", "5*10+1", "quit" ]
64
+ results = []
65
+ @session.open_channel "session" do |chan|
66
+ chan.on_data do |ch,data|
67
+ results << data
68
+ chan.send_data dialog.shift + "\n"
69
+ end
70
+ chan.exec "bc"
71
+ chan.send_data dialog.shift + "\n"
72
+ end
73
+ @session.loop
74
+ assert_equal [ "4\n", "51\n" ], results
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,41 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../../lib"
18
+
19
+ require 'net/ssh/transport/compress/none-compressor'
20
+ require 'test/unit'
21
+
22
+ class TC_NoneCompressor < Test::Unit::TestCase
23
+
24
+ def setup
25
+ @compressor = Net::SSH::Transport::Compress::NoneCompressor.new
26
+ end
27
+
28
+ def test_new
29
+ assert_instance_of Net::SSH::Transport::Compress::NoneCompressor,
30
+ @compressor.new
31
+ end
32
+
33
+ def test_compress
34
+ expect = "To be, or not to be, that is the question"
35
+ assert_equal expect, @compressor.compress( "To be, or not to be, that is the question" )
36
+
37
+ expect = "But soft! What light through yonder window breaks?"
38
+ assert_equal expect, @compressor.compress( "But soft! What light through yonder window breaks?" )
39
+ end
40
+
41
+ end
@@ -0,0 +1,45 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../../lib"
18
+
19
+ require 'net/ssh/transport/compress/none-decompressor'
20
+ require 'test/unit'
21
+
22
+ class TC_NoneDecompressor < Test::Unit::TestCase
23
+
24
+ def setup
25
+ @decompressor = Net::SSH::Transport::Compress::NoneDecompressor.new
26
+ end
27
+
28
+ def test_new
29
+ assert_instance_of Net::SSH::Transport::Compress::NoneDecompressor,
30
+ @decompressor.new
31
+ end
32
+
33
+ def test_decompress
34
+ expect = "To be, or not to be, that is the question"
35
+
36
+ assert_equal expect, @decompressor.decompress(
37
+ "To be, or not to be, that is the question" )
38
+
39
+ expect = "But soft! What light through yonder window breaks?"
40
+
41
+ assert_equal expect, @decompressor.decompress(
42
+ "But soft! What light through yonder window breaks?" )
43
+ end
44
+
45
+ end
@@ -0,0 +1,61 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../../lib"
18
+
19
+ require 'net/ssh/transport/compress/zlib-compressor'
20
+ require 'test/unit'
21
+
22
+ class TC_ZLibCompressor < Test::Unit::TestCase
23
+
24
+ def setup
25
+ @compressor = Net::SSH::Transport::Compress::ZLibCompressor.new
26
+ end
27
+
28
+ def test_new
29
+ assert_instance_of Net::SSH::Transport::Compress::ZLibCompressor,
30
+ @compressor.new
31
+ end
32
+
33
+ def test_compress
34
+ expect = "x\234\n\311WHJ\325Q\310/R\310\313/Q(\201\360J2\022K" +
35
+ "\0242\213\201t\252BaijqIf~\036\000\000\000\377\377"
36
+
37
+ assert_equal expect, @compressor.compress( "To be, or not to be, that is the question" )
38
+
39
+ expect = "r*-Q(\316O+QT\010\a\311\346d\246g\000\325g\024\345\227\246g(T" +
40
+ "\346\347\245\244\026)\224g\346\245\344\227+$\025\245&f\027\333" +
41
+ "\003\000\000\000\377\377"
42
+
43
+ assert_equal expect, @compressor.compress( "But soft! What light through yonder window breaks?" )
44
+ end
45
+
46
+ def test_compress_options
47
+ @compressor.configure :level => 1
48
+
49
+ expect = "x\001\n\311WHJ\325Q\310/R\310\313/Q(\201\360J2\022K\0242\213" +
50
+ "\025J2R\025\nKS\213K2\363\363\000\000\000\000\377\377"
51
+
52
+ assert_equal expect, @compressor.compress( "To be, or not to be, that is the question" )
53
+
54
+ expect = "r*-Q(\316O+QT\010\a\311\346d\246g\000\325g\024\345\227\246g(T" +
55
+ "\346\347\245\244\026)\224g\346\245\344\227+$\025\245&f\027\333" +
56
+ "\003\000\000\000\377\377"
57
+
58
+ assert_equal expect, @compressor.compress( "But soft! What light through yonder window breaks?" )
59
+ end
60
+
61
+ end
@@ -0,0 +1,48 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../../lib"
18
+
19
+ require 'net/ssh/transport/compress/zlib-decompressor'
20
+ require 'test/unit'
21
+
22
+ class TC_ZLibDecompressor < Test::Unit::TestCase
23
+
24
+ def setup
25
+ @decompressor = Net::SSH::Transport::Compress::ZLibDecompressor.new
26
+ end
27
+
28
+ def test_new
29
+ assert_instance_of Net::SSH::Transport::Compress::ZLibDecompressor,
30
+ @decompressor.new
31
+ end
32
+
33
+ def test_decompress
34
+ expect = "To be, or not to be, that is the question"
35
+
36
+ assert_equal expect, @decompressor.decompress(
37
+ "x\234\n\311WHJ\325Q\310/R\310\313/Q(\201\360J2\022K" +
38
+ "\0242\213\201t\252BaijqIf~\036\000\000\000\377\377" )
39
+
40
+ expect = "But soft! What light through yonder window breaks?"
41
+
42
+ assert_equal expect, @decompressor.decompress(
43
+ "r*-Q(\316O+QT\010\a\311\346d\246g\000\325g\024\345\227\246g(T" +
44
+ "\346\347\245\244\026)\224g\346\245\344\227+$\025\245&f\027\333" +
45
+ "\003\000\000\000\377\377" )
46
+ end
47
+
48
+ end
@@ -0,0 +1,304 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../../lib"
18
+
19
+ require 'net/ssh/errors'
20
+ require 'net/ssh/transport/kex/dh'
21
+ require 'net/ssh/util/buffer'
22
+ require 'test/unit'
23
+ require 'ostruct'
24
+
25
+ class TC_KEX_DH < Test::Unit::TestCase
26
+
27
+ unless defined?( MockDH )
28
+ MockDH = Struct.new( :valid?, :p, :g, :priv_key, :pub_key )
29
+ class MockDH
30
+ def compute_key( num )
31
+ num
32
+ end
33
+
34
+ def generate_key!
35
+ self.pub_key = MockBN.new( priv_key )
36
+ end
37
+ end
38
+ end
39
+
40
+ class MockServerKey
41
+ attr_reader :result
42
+
43
+ def initialize( result )
44
+ @result = result
45
+ end
46
+
47
+ def ssh_do_verify( sig, hash )
48
+ @result
49
+ end
50
+
51
+ def ssh_type
52
+ "ssh-test"
53
+ end
54
+ end
55
+
56
+ class MockKeys
57
+ def get( type )
58
+ raise "not DH" unless type == "dh"
59
+ return MockDH.new( true )
60
+ end
61
+ end
62
+
63
+ class MockBN
64
+ attr_reader :value
65
+
66
+ def initialize( value )
67
+ @value = value
68
+ end
69
+
70
+ def to_i( *args )
71
+ @value.to_i( *args )
72
+ end
73
+
74
+ def to_ssh
75
+ "[#{@value}]"
76
+ end
77
+ end
78
+
79
+ class MockBNs
80
+ def new( value, base )
81
+ return value if value.is_a?( Numeric )
82
+ MockBN.new( value.to_i( base ) )
83
+ end
84
+
85
+ def rand( bits )
86
+ bits
87
+ end
88
+ end
89
+
90
+ class MockDigest
91
+ def self.digest( text )
92
+ text
93
+ end
94
+ end
95
+
96
+ class MockReaderBuffer < Net::SSH::Util::ReaderBuffer
97
+ def read_key
98
+ MockServerKey.new( read )
99
+ end
100
+
101
+ def read_bignum
102
+ MockBN.new( read_string )
103
+ end
104
+ end
105
+
106
+ class MockBuffers
107
+ def writer( text="" ); Net::SSH::Util::WriterBuffer.new( text ); end
108
+ def reader( text ); MockReaderBuffer.new( text ); end
109
+ end
110
+
111
+ class MockDigests
112
+ def get( type )
113
+ raise "not SHA1" unless type == "sha1"
114
+ return MockDigest
115
+ end
116
+ end
117
+
118
+ class MockSession
119
+ attr_reader :sent_buffer
120
+
121
+ def initialize( *script )
122
+ @script = script
123
+ end
124
+
125
+ def send_message( buffer )
126
+ @sent_buffer = buffer
127
+ end
128
+
129
+ def wait_for_message
130
+ [ @script.shift, @script.shift ]
131
+ end
132
+
133
+ def algorithms
134
+ OpenStruct.new( :host_key => "ssh-test" )
135
+ end
136
+ end
137
+
138
+ def setup
139
+ @kex = Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1.new(
140
+ MockBNs.new, MockDigests.new )
141
+ @kex.keys = MockKeys.new
142
+ @kex.buffers = MockBuffers.new
143
+
144
+ @init = Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1::KEXDH_INIT
145
+ @reply = Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1::KEXDH_REPLY
146
+ @session_id = "\0\0\0\1A\0\0\0\1B\0\0\0\1C\0\0\0\1D\0\0\0\1E[10][20][30]"
147
+
148
+ @exchange_keys_script = [
149
+ 31,
150
+ MockReaderBuffer.new( "\0\0\0\10key blob\0\0\0\0041001\0\0\0\27\0\0\0\10ssh-test\0\0\0\11signature" ),
151
+ 21,
152
+ nil
153
+ ]
154
+
155
+ @exchange_keys_session_id = "\0\0\0\1A\0\0\0\1B\0\0\0\1C\0\0\0\1D\0\0\0\10key blob[80][1001][9]"
156
+ end
157
+
158
+ def test_generate_key
159
+ dh = nil
160
+ assert_nothing_raised do
161
+ dh = @kex.generate_key( nil, { :need_bytes=>10 } )
162
+ end
163
+
164
+ expected_p =
165
+ 0xFFFFFFFF_FFFFFFFF_C90FDAA2_2168C234_C4C6628B_80DC1CD1_29024E08_8A67CC74_020BBEA6_3B139B22_514A0879_8E3404DD_EF9519B3_CD3A431B_302B0A6D_F25F1437_4FE1356D_6D51C245_E485B576_625E7EC6_F44C42E9_A637ED6B_0BFF5CB6_F406B7ED_EE386BFB_5A899FA5_AE9F2411_7C4B1FE6_49286651_ECE65381_FFFFFFFF_FFFFFFFF
166
+
167
+ assert_equal expected_p, dh.p.to_i
168
+ assert_equal 2, dh.g
169
+ assert_equal 80, dh.priv_key
170
+ end
171
+
172
+ def test_verify_server_key
173
+ key = OpenStruct.new( :ssh_type => "test" )
174
+ session = OpenStruct.new( :algorithms => OpenStruct.new( :host_key => "test" ) )
175
+ assert_nothing_raised { @kex.verify_server_key( key, session ) }
176
+
177
+ session = OpenStruct.new( :algorithms => OpenStruct.new( :host_key => "bogus" ) )
178
+ assert_raise( Net::SSH::Exception ) {
179
+ @kex.verify_server_key( key, session ) }
180
+ end
181
+
182
+ def test_send_kexinit
183
+ dh = MockDH.new
184
+ dh.pub_key = MockBN.new( 80 )
185
+ session = MockSession.new( @reply, :worked )
186
+
187
+ result = nil
188
+ assert_nothing_raised do
189
+ result = @kex.send_kexinit( dh, session )
190
+ end
191
+
192
+ assert_equal :worked, result
193
+ assert_equal "#{@init.chr}[80]", session.sent_buffer.to_s
194
+
195
+ session = MockSession.new( @reply+1, :worked )
196
+
197
+ assert_raise( Net::SSH::Exception ) do
198
+ @kex.send_kexinit( dh, session )
199
+ end
200
+ end
201
+
202
+ def test_parse_kex_reply
203
+ dh = MockDH.new
204
+
205
+ buffer = Net::SSH::Util::WriterBuffer.new
206
+ buffer.write_string "key blob"
207
+ buffer.write_string "1001"
208
+
209
+ sigbuf = Net::SSH::Util::WriterBuffer.new
210
+ sigbuf.write_string "ssh-test"
211
+ sigbuf.write_string "signature"
212
+ buffer.write_string sigbuf
213
+
214
+ buffer = MockReaderBuffer.new( buffer.content )
215
+
216
+ result = nil
217
+ assert_nothing_raised do
218
+ result = @kex.parse_kex_reply( dh, buffer, MockSession.new )
219
+ end
220
+
221
+ assert_equal "key blob", result[:key_blob]
222
+ assert_equal "key blob", result[:server_key].result
223
+ assert_equal "1001", result[:server_dh_pubkey].value
224
+ assert_equal 9, result[:shared_secret].to_i
225
+ assert_equal "signature", result[:server_sig]
226
+
227
+ buffer = Net::SSH::Util::WriterBuffer.new
228
+ buffer.write_string "key blob"
229
+ buffer.write_string "1001"
230
+
231
+ sigbuf = Net::SSH::Util::WriterBuffer.new
232
+ sigbuf.write_string "ssh-bogus"
233
+ sigbuf.write_string "signature"
234
+ buffer.write_string sigbuf
235
+
236
+ buffer = MockReaderBuffer.new( buffer.content )
237
+ assert_raise( Net::SSH::Exception ) do
238
+ @kex.parse_kex_reply( dh, buffer, MockSession.new )
239
+ end
240
+ end
241
+
242
+ def test_verify_signature
243
+ dh = MockDH.new
244
+ dh.p = MockBN.new( 2 )
245
+ dh.g = MockBN.new( 6 )
246
+ dh.pub_key = MockBN.new( 10 )
247
+
248
+ data = { :client_version_string => "A",
249
+ :server_version_string => "B",
250
+ :client_algorithm_packet => "C",
251
+ :server_algorithm_packet => "D" }
252
+ result = { :key_blob => "E",
253
+ :server_dh_pubkey => MockBN.new( 20 ),
254
+ :shared_secret => MockBN.new( 30 ),
255
+ :server_key => MockServerKey.new( true ) }
256
+
257
+ session_id = nil
258
+ assert_nothing_raised do
259
+ session_id = @kex.verify_signature( dh, data, result )
260
+ end
261
+
262
+ assert_equal @session_id, session_id
263
+
264
+ result[:server_key] = MockServerKey.new( false )
265
+ assert_raise( Net::SSH::Exception ) do
266
+ @kex.verify_signature( dh, data, result )
267
+ end
268
+ end
269
+
270
+ def test_confirm_newkeys
271
+ session = MockSession.new( 21, :worked )
272
+
273
+ assert_nothing_raised do
274
+ @kex.confirm_newkeys( session )
275
+ end
276
+
277
+ assert_equal 21.chr, session.sent_buffer.to_s
278
+
279
+ session = MockSession.new( 22, :worked )
280
+ assert_raise( Net::SSH::Exception ) do
281
+ @kex.confirm_newkeys( session )
282
+ end
283
+ end
284
+
285
+ def test_exchange_keys
286
+ session = MockSession.new( *@exchange_keys_script )
287
+ data = { :need_bytes => 10,
288
+ :client_version_string => "A",
289
+ :server_version_string => "B",
290
+ :client_algorithm_packet => "C",
291
+ :server_algorithm_packet => "D" }
292
+
293
+ result = nil
294
+ assert_nothing_raised do
295
+ result = @kex.exchange_keys( session, data )
296
+ end
297
+
298
+ assert_equal MockDigest, result.hashing_algorithm
299
+ assert_equal @exchange_keys_session_id, result.session_id
300
+ assert_equal "key blob", result.server_key.result
301
+ assert_equal 9, result.shared_secret.to_i
302
+ end
303
+
304
+ end