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,146 @@
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
+ require 'base64'
18
+ require 'openssl'
19
+ require 'net/ssh/util/buffer'
20
+
21
+ module OpenSSL
22
+
23
+ # This class is originally defined in the OpenSSL module. As needed, methods
24
+ # have been added to it by the Net::SSH module for convenience in dealing with
25
+ # SSH functionality.
26
+ class BN
27
+
28
+ # Converts a BN object to a string. The format used is that which is
29
+ # required by the SSH2 protocol.
30
+ def to_ssh
31
+ if zero?
32
+ return [ 0 ].pack( "N" )
33
+ else
34
+ buf = to_s( 2 )
35
+ if buf[0][7] == 1
36
+ return [ buf.length+1, 0, buf ].pack( "NCA*" )
37
+ else
38
+ return [ buf.length, buf ].pack( "NA*" )
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ module PKey
46
+
47
+ # This class is originally defined in the OpenSSL module. As needed, methods
48
+ # have been added to it by the Net::SSH module for convenience in dealing
49
+ # with SSH functionality.
50
+ class DH
51
+
52
+ # Determines whether the pub_key for this key is valid. (This algorithm
53
+ # lifted more-or-less directly from OpenSSH, dh.c, dh_pub_is_valid.)
54
+ def valid?
55
+ return false if pub_key < 0
56
+ bits_set = 0
57
+ pub_key.num_bits.times { |i| bits_set += 1 if pub_key.bit_set? i }
58
+ return ( bits_set > 1 && pub_key < p )
59
+ end
60
+
61
+ end
62
+
63
+ # This class is originally defined in the OpenSSL module. As needed, methods
64
+ # have been added to it by the Net::SSH module for convenience in dealing
65
+ # with SSH functionality.
66
+ class RSA
67
+
68
+ # Returns "ssh-rsa", which is the description of this key type used by the
69
+ # SSH2 protocol.
70
+ def ssh_type
71
+ "ssh-rsa"
72
+ end
73
+
74
+ # Converts the key to a blob, according to the SSH2 protocol.
75
+ def to_blob
76
+ buffer = Net::SSH::Util::WriterBuffer.new
77
+ buffer.write_bignum( e )
78
+ buffer.write_bignum( n )
79
+ return buffer.to_s
80
+ end
81
+
82
+ # Verifies the given signature matches the given data.
83
+ def ssh_do_verify( sig, data )
84
+ verify( OpenSSL::Digest::SHA1.new, sig, data )
85
+ end
86
+
87
+ # Returns the signature for the given data.
88
+ def ssh_do_sign( data )
89
+ sign( OpenSSL::Digest::SHA1.new, data )
90
+ end
91
+ end
92
+
93
+ # This class is originally defined in the OpenSSL module. As needed, methods
94
+ # have been added to it by the Net::SSH module for convenience in dealing
95
+ # with SSH functionality.
96
+ class DSA
97
+
98
+ # Returns "ssh-dss", which is the description of this key type used by the
99
+ # SSH2 protocol.
100
+ def ssh_type
101
+ "ssh-dss"
102
+ end
103
+
104
+ # Converts the key to a blob, according to the SSH2 protocol.
105
+ def to_blob
106
+ buffer = Net::SSH::Util::WriterBuffer.new
107
+ buffer.write_bignum( p )
108
+ buffer.write_bignum( q )
109
+ buffer.write_bignum( g )
110
+ buffer.write_bignum( pub_key )
111
+ return buffer.to_s
112
+ end
113
+
114
+ # Verifies the given signature matches the given data.
115
+ def ssh_do_verify( sig, data )
116
+ sig_r = sig[0,20].unpack("H*")[0].to_i(16)
117
+ sig_s = sig[20,20].unpack("H*")[0].to_i(16)
118
+ a1sig = OpenSSL::ASN1::Sequence([
119
+ OpenSSL::ASN1::Integer(sig_r),
120
+ OpenSSL::ASN1::Integer(sig_s)
121
+ ])
122
+ return verify(OpenSSL::Digest::DSS1.new, a1sig.to_der, data)
123
+ end
124
+
125
+ # Sigs the given data.
126
+ def ssh_do_sign( data )
127
+ sig = sign( OpenSSL::Digest::DSS1.new, data)
128
+ a1sig = OpenSSL::ASN1.decode( sig )
129
+
130
+ sig_r = a1sig.value[0].value.to_s(2)
131
+ sig_s = a1sig.value[1].value.to_s(2)
132
+
133
+ if sig_r.length > 20 || sig_s.length > 20
134
+ raise OpenSSL::PKey::DSAError, "bad sig size"
135
+ end
136
+
137
+ sig_r = "\0" * ( 20 - sig_r.length ) + sig_r if sig_r.length < 20
138
+ sig_s = "\0" * ( 20 - sig_s.length ) + sig_s if sig_s.length < 20
139
+
140
+ return sig_r + sig_s
141
+ end
142
+ end
143
+
144
+ end
145
+
146
+ end
@@ -0,0 +1,73 @@
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
+ unless defined?( HAS_TERMIOS )
18
+ begin
19
+ require 'termios'
20
+ HAS_TERMIOS = true
21
+ rescue LoadError
22
+ HAS_TERMIOS = false
23
+ end
24
+ end
25
+
26
+ module Net
27
+ module SSH
28
+ module Util
29
+
30
+ # A simple class for prompting a user for input.
31
+ class Prompter
32
+
33
+ # Displays the prompt and then waits for the user to enter a response.
34
+ # If the 'termios' library is available, the user's input will not be
35
+ # echoed to the terminal. The user's response will be returned, with
36
+ # any trailing newline chomped.
37
+ def password( prompt=nil )
38
+ if $stdin.tty?
39
+ echo false
40
+ print prompt if prompt
41
+ end
42
+
43
+ $stdin.gets.chomp
44
+ ensure
45
+ if $stdin.tty?
46
+ echo true
47
+ puts
48
+ end
49
+ end
50
+
51
+ if HAS_TERMIOS
52
+ def echo( enable )
53
+ term = Termios::getattr( $stdin )
54
+
55
+ if enable
56
+ term.c_lflag |= ( Termios::ECHO | Termios::ICANON )
57
+ else
58
+ term.c_lflag &= ~Termios::ECHO
59
+ end
60
+
61
+ Termios::setattr( $stdin, Termios::TCSANOW, term )
62
+ end
63
+ else
64
+ def echo( enable )
65
+ end
66
+ end
67
+ private :echo
68
+
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,29 @@
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
+ module Net
18
+ module SSH
19
+ module Version
20
+
21
+ MAJOR = 0
22
+ MINOR = 5
23
+ TINY = 0
24
+
25
+ STRING = [ MAJOR, MINOR, TINY ].join( "." )
26
+
27
+ end
28
+ end
29
+ end
data/test/ALL-TESTS.rb ADDED
@@ -0,0 +1,21 @@
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
+ $run_integration_tests = ARGV.include?( "-i" )
20
+
21
+ Dir["**/tc_*.rb"].each { |f| load f }
@@ -0,0 +1,136 @@
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 'test/unit'
20
+ require 'net/ssh/connection/channel'
21
+ require 'net/ssh/util/buffer'
22
+
23
+ class TC_Channel < Test::Unit::TestCase
24
+
25
+ class Buffers
26
+ def writer
27
+ Net::SSH::Util::WriterBuffer.new
28
+ end
29
+ end
30
+
31
+ class Log
32
+ def debug?
33
+ false
34
+ end
35
+ end
36
+
37
+ class Connection
38
+ attr_reader :buffers
39
+ attr_reader :events
40
+
41
+ def initialize( buffers )
42
+ @events = []
43
+ @buffers = buffers
44
+ end
45
+
46
+ def send_message( msg )
47
+ @events << msg.to_s
48
+ end
49
+
50
+ def allocate_channel_id
51
+ events << :allocate_channel_id
52
+ 1234
53
+ end
54
+
55
+ def remove_channel( channel )
56
+ events << :remove_channel
57
+ end
58
+ end
59
+
60
+ def setup
61
+ @connection = Connection.new( Buffers.new )
62
+ end
63
+
64
+ def test_open_no_data
65
+ channel = Net::SSH::Connection::Channel.open( @connection, Log.new,
66
+ Buffers.new, "test" )
67
+ assert_equal [ :allocate_channel_id,
68
+ "\132\0\0\0\4test\0\0\4\xd2\x7f\xff\xff\xff\x7f\xff\xff\xff" ],
69
+ @connection.events
70
+ assert_equal "test", channel.type
71
+ end
72
+
73
+ def test_open_with_data
74
+ channel = Net::SSH::Connection::Channel.open( @connection, Log.new,
75
+ Buffers.new, "test", "some data" )
76
+ assert_equal [ :allocate_channel_id,
77
+ "\132\0\0\0\4test\0\0\4\xd2\x7f\xff\xff\xff\x7f\xff\xff\xffsome data" ],
78
+ @connection.events
79
+ assert_equal "test", channel.type
80
+ end
81
+
82
+ def test_do_confirm_open
83
+ confirmed = nil
84
+ channel = Net::SSH::Connection::Channel.open( @connection, Log.new,
85
+ Buffers.new, "test" )
86
+ channel.on_confirm_open { |a| confirmed = a }
87
+ channel.do_confirm_open 1, 2, 3
88
+ assert_same channel, confirmed
89
+ assert_equal 1, channel.remote_id
90
+ assert_equal 2, channel.window_size
91
+ assert_equal 3, channel.maximum_packet_size
92
+ end
93
+
94
+ def create_channel
95
+ Net::SSH::Connection::Channel.create( @connection, Log.new, Buffers.new,
96
+ "test", 1, 2, 3 )
97
+ end
98
+
99
+ def test_create
100
+ channel = create_channel
101
+ assert_equal "test", channel.type
102
+ assert_equal [ :allocate_channel_id ], @connection.events
103
+ assert_equal 1234, channel.local_id
104
+ assert_equal 1, channel.remote_id
105
+ assert_equal 2, channel.window_size
106
+ assert_equal 3, channel.maximum_packet_size
107
+ end
108
+
109
+ def test_new
110
+ assert_raise( NoMethodError ) do
111
+ Net::SSH::Connection::Channel.new( @connection, "test" )
112
+ end
113
+ end
114
+
115
+ def self.test_callback( name, do_args=[], expect=do_args )
116
+ define_method( "test_#{name}".to_sym ) do
117
+ channel = create_channel
118
+
119
+ result = nil
120
+ channel.send( "on_#{name}".to_sym ) { |*a| result = a }
121
+ channel.send( "do_#{name}".to_sym, *do_args )
122
+
123
+ assert_equal [ channel, *expect ], result
124
+ end
125
+ end
126
+
127
+ test_callback :confirm_open, [ 1, 2, 3 ], []
128
+ test_callback :confirm_failed, [ 100, "b", "c" ]
129
+ test_callback :window_adjust, [ 14 ]
130
+ test_callback :data, [ "blah" ]
131
+ test_callback :extended_data, [ 1, "blah" ]
132
+ test_callback :eof
133
+ test_callback :request, [ true, "blah" ]
134
+ test_callback :success
135
+ test_callback :failure
136
+ end
@@ -0,0 +1,287 @@
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 'test/unit'
20
+ require 'net/ssh/connection/driver'
21
+ require 'net/ssh/errors'
22
+ require 'net/ssh/util/buffer'
23
+
24
+ class TC_Driver < Test::Unit::TestCase
25
+
26
+ class Buffers
27
+ def writer
28
+ Net::SSH::Util::WriterBuffer.new
29
+ end
30
+ end
31
+
32
+ class Log
33
+ attr_reader :messages
34
+
35
+ def initialize
36
+ @messages = []
37
+ end
38
+
39
+ def debug?
40
+ true
41
+ end
42
+
43
+ def debug( msg )
44
+ @messages << msg
45
+ end
46
+ end
47
+
48
+ class Session
49
+ attr_reader :events
50
+ attr_reader :script
51
+
52
+ def initialize
53
+ @events = []
54
+ @script = []
55
+ end
56
+
57
+ def send_message( msg )
58
+ @events << msg.to_s
59
+ end
60
+
61
+ def wait_for_message
62
+ @script.shift
63
+ end
64
+ end
65
+
66
+ class Channel
67
+ attr_reader :local_id
68
+ attr_reader :remote_id
69
+ attr_reader :data
70
+ attr_reader :window_size
71
+ attr_reader :packet_size
72
+ attr_reader :type
73
+ attr_reader :block
74
+ attr_reader :events
75
+
76
+ def self.open( type, data )
77
+ new( type, data, nil, nil, nil )
78
+ end
79
+
80
+ def self.create( type, remote_id, window_size, packet_size )
81
+ new( type, nil, remote_id, window_size, packet_size )
82
+ end
83
+
84
+ def initialize( type, data, remote_id, winsize, packsize )
85
+ @type = type
86
+ @data = data
87
+ @remote_id = remote_id
88
+ @window_size = winsize
89
+ @packet_size = packsize
90
+ @local_id = 1
91
+ @events = []
92
+ end
93
+
94
+ def close( value )
95
+ @events << [ :close, value ]
96
+ end
97
+
98
+ def on_confirm_open( &block )
99
+ @block = block
100
+ end
101
+
102
+ def self.event( name )
103
+ define_method( "do_#{name}".to_sym ) do |*args|
104
+ @events << [ name, *args ]
105
+ end
106
+ end
107
+
108
+ event :confirm_failed
109
+ event :confirm_open
110
+ event :window_adjust
111
+ event :data
112
+ event :extended_data
113
+ event :eof
114
+ event :request
115
+ event :success
116
+ event :failure
117
+ end
118
+
119
+ def reader( text )
120
+ Net::SSH::Util::ReaderBuffer.new( text )
121
+ end
122
+
123
+ def setup
124
+ @session = Session.new
125
+ @log = Log.new
126
+ @driver = Net::SSH::Connection::Driver.new( @session, @log,
127
+ Buffers.new,
128
+ :open => proc { |t,d| Channel.open(t,d) },
129
+ :create => proc { |t,r,w,p| Channel.create(t,r,w,p) } )
130
+ end
131
+
132
+ def test_open_channel
133
+ channel = @driver.open_channel( "test", "data" ) { |a| a }
134
+ assert_equal "hello", channel.block.call( "hello" )
135
+ assert_equal "test", channel.type
136
+ assert_equal "data", channel.data
137
+ assert_equal [ channel ], @driver.channels
138
+ end
139
+
140
+ def test_remove_channel
141
+ channel = @driver.open_channel( "test", "data" ) { |a| a }
142
+ assert_equal [channel], @driver.channels
143
+ @driver.remove_channel( channel )
144
+ assert_equal [], @driver.channels
145
+ end
146
+
147
+ def test_allocate_channel_id
148
+ assert_equal 1, @driver.allocate_channel_id
149
+ 10.times { @driver.allocate_channel_id }
150
+ assert_equal 12, @driver.allocate_channel_id
151
+ end
152
+
153
+ def test_global_request
154
+ @driver.global_request "test", "foobar"
155
+ assert_equal [ "\120\0\0\0\4test\1foobar" ], @session.events
156
+ end
157
+
158
+ def test_request_success
159
+ @driver.global_request( "test", "foobar" ) do |a,b|
160
+ assert a
161
+ assert_equal "response", b
162
+ end
163
+
164
+ @driver.do_request_success "response"
165
+ end
166
+
167
+ def test_request_failure
168
+ @driver.global_request( "test", "foobar" ) do |a,b|
169
+ assert !a
170
+ assert_equal "response", b
171
+ end
172
+
173
+ @driver.do_request_failure "response"
174
+ end
175
+
176
+ def test_channel_open_no_handler
177
+ assert_raise( Net::SSH::Exception ) do
178
+ @driver.do_channel_open(
179
+ reader( "\0\0\0\4test\0\0\0\4\0\0\0\0\0\0\0\1" ) )
180
+ end
181
+ end
182
+
183
+ def test_channel_open_with_handler
184
+ @driver.add_channel_open_handler( "test" ) do |conn,chan,resp|
185
+ assert_equal @driver, conn
186
+ assert_equal "test", chan.type
187
+ assert_equal 4, chan.remote_id
188
+ assert_equal 0, chan.window_size
189
+ assert_equal 1, chan.packet_size
190
+ assert_equal "hello world", resp.read
191
+ end
192
+
193
+ @driver.do_channel_open(
194
+ reader( "\0\0\0\4test\0\0\0\4\0\0\0\0\0\0\0\1hello world" ) )
195
+
196
+ assert_equal 1, @driver.channels.length
197
+ assert_equal [ "\133\0\0\0\4\0\0\0\1\x7f\xff\xff\xff\x7f\xff\xff\xff" ],
198
+ @session.events
199
+ end
200
+
201
+ def test_channel_open_failure
202
+ channel = @driver.open_channel( "test", "data" )
203
+ assert_equal 1, @driver.channels.length
204
+ @driver.do_channel_open_failure(
205
+ reader( "\0\0\0\1\0\0\0\2\0\0\0\4test\0\0\0\2en" ) )
206
+ assert_equal 0, @driver.channels.length
207
+ assert_equal [ [ :confirm_failed, 2, "test", "en" ] ], channel.events
208
+ end
209
+
210
+ def test_channel_open_confirmation
211
+ channel = @driver.open_channel( "test", "data" )
212
+ @driver.do_channel_open_confirmation(
213
+ reader( "\0\0\0\1\0\0\0\2\0\0\0\3\0\0\0\4" ) )
214
+ assert_equal 1, @driver.channels.length
215
+ assert_equal [ [ :confirm_open, 2, 3, 4 ] ], channel.events
216
+ end
217
+
218
+ def test_channel_window_adjust
219
+ channel = @driver.open_channel( "test", "data" )
220
+ @driver.do_channel_window_adjust( reader( "\0\0\0\1\0\0\0\12" ) )
221
+ assert_equal 1, @driver.channels.length
222
+ assert_equal [ [ :window_adjust, 10 ] ], channel.events
223
+ end
224
+
225
+ def test_channel_data
226
+ channel = @driver.open_channel( "test", "data" )
227
+ @driver.do_channel_data( reader( "\0\0\0\1\0\0\0\4test" ) )
228
+ assert_equal 1, @driver.channels.length
229
+ assert_equal [ [ :data, "test" ] ], channel.events
230
+ end
231
+
232
+ def test_channel_extended_data
233
+ channel = @driver.open_channel( "test", "data" )
234
+ @driver.do_channel_extended_data( reader( "\0\0\0\1\0\0\0\2\0\0\0\4test" ) )
235
+ assert_equal 1, @driver.channels.length
236
+ assert_equal [ [ :extended_data, 2, "test" ] ], channel.events
237
+ end
238
+
239
+ def test_channel_eof
240
+ channel = @driver.open_channel( "test", "data" )
241
+ @driver.do_channel_eof( reader( "\0\0\0\1" ) )
242
+ assert_equal 1, @driver.channels.length
243
+ assert_equal [ [ :eof ] ], channel.events
244
+ end
245
+
246
+ def test_channel_close
247
+ channel = @driver.open_channel( "test", "data" )
248
+ @driver.do_channel_close( reader( "\0\0\0\1" ) )
249
+ assert_equal 1, @driver.channels.length
250
+ assert_equal [ [ :close, false ] ], channel.events
251
+ end
252
+
253
+ def test_channel_request
254
+ channel = @driver.open_channel( "test", "data" )
255
+ @driver.do_channel_request( reader( "\0\0\0\1\0\0\0\4test\1foobarbaz" ) )
256
+ assert_equal 1, @driver.channels.length
257
+ assert_equal [ [ :request, "test", true, reader("foobarbaz") ] ],
258
+ channel.events
259
+ end
260
+
261
+ def test_channel_success
262
+ channel = @driver.open_channel( "test", "data" )
263
+ @driver.do_channel_success( reader( "\0\0\0\1" ) )
264
+ assert_equal 1, @driver.channels.length
265
+ assert_equal [ [ :success ] ], channel.events
266
+ end
267
+
268
+ def test_channel_failure
269
+ channel = @driver.open_channel( "test", "data" )
270
+ @driver.do_channel_failure( reader( "\0\0\0\1" ) )
271
+ assert_equal 1, @driver.channels.length
272
+ assert_equal [ [ :failure ] ], channel.events
273
+ end
274
+
275
+ ProcessItem = Struct.new( :name, :script, :events )
276
+ def self.i( name, script, events )
277
+ ProcessItem.new( name, script, events )
278
+ end
279
+
280
+ def test_process_bad
281
+ @session.script << [ 0, reader("") ]
282
+ assert_raise( Net::SSH::Exception ) do
283
+ @driver.process
284
+ end
285
+ end
286
+
287
+ end