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,5 +0,0 @@
1
- HostBasedAuthentication no
2
- PasswordAuthentication no
3
- PubKeyAuthentication no
4
- ChallengeResponseAuthentication no
5
- KbdInteractiveAuthentication no
data/test/configs/auth_on DELETED
@@ -1,4 +0,0 @@
1
- HostBasedAuthentication yes
2
- PasswordAuthentication yes
3
- PubKeyAuthentication yes
4
- ChallengeResponseAuthentication yes
data/test/configs/empty DELETED
File without changes
data/test/configs/eqsign DELETED
@@ -1,3 +0,0 @@
1
- Host=test.test
2
- Port =1234
3
- Compression yes
@@ -1,8 +0,0 @@
1
- Host other.host
2
- Compression no
3
- Port 1231
4
-
5
- Host test.host
6
- Compression yes
7
- ForwardAgent yes
8
- Port 1234
@@ -1,10 +0,0 @@
1
- # Jump through hosts with one SSH call
2
- # via <http://glandium.org/blog/?p=308>
3
- Host *+*
4
- ProxyCommand ssh $(echo %h | sed 's/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') PATH=.:\$PATH nc -w1 $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /')
5
-
6
- Host office-offsite
7
- HostName work-gateway+office-workstation
8
-
9
- Host test.host
10
- Compression yes
@@ -1,4 +0,0 @@
1
- Host other.host test.host
2
- Compression yes
3
- Port 1980
4
- RekeyLimit 2G
@@ -1,6 +0,0 @@
1
- Host test.* !test.host
2
- Port 1234
3
- Compression no
4
-
5
- Host test.host
6
- Port 9876
data/test/configs/nohost DELETED
@@ -1,19 +0,0 @@
1
-
2
- IdentityFile ~/.ssh/id_dsa
3
- IdentityFile ~/.ssh/id_rsa
4
- Port 1980
5
-
6
- Host test.host
7
- Port 1985
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
@@ -1,4 +0,0 @@
1
- Host 1234
2
- Compression yes
3
- Port 1980
4
- RekeyLimit 2G
@@ -1,2 +0,0 @@
1
- Host behind-proxy
2
- ProxyCommand ssh %r@proxy -W %h:%p
@@ -1,2 +0,0 @@
1
- Host 1234
2
- SendEnv GIT_* LANG LC_*
@@ -1,8 +0,0 @@
1
- Host test
2
- HostName %h.sufix
3
-
4
- Host 1234
5
- HostName prefix.%h.sufix
6
-
7
- Host *
8
- HostName %h
@@ -1,14 +0,0 @@
1
- Host test.*
2
- Port 1234
3
- Compression no
4
-
5
- Host tes?.host
6
- Port 4321
7
- ForwardAgent yes
8
-
9
- Host *.hos?
10
- IdentityFile ~/.ssh/id_dsa
11
- Compression yes
12
-
13
- Host k*.host
14
- RekeyLimit 1G
@@ -1,487 +0,0 @@
1
- require 'common'
2
- require 'net/ssh/connection/channel'
3
-
4
- module Connection
5
-
6
- class TestChannel < Test::Unit::TestCase
7
- include Net::SSH::Connection::Constants
8
-
9
- def teardown
10
- connection.test!
11
- end
12
-
13
- def test_constructor_should_set_defaults
14
- assert_equal 0x8000, channel.local_maximum_packet_size
15
- assert_equal 0x20000, channel.local_maximum_window_size
16
- assert channel.pending_requests.empty?
17
- end
18
-
19
- def test_channel_properties
20
- channel[:hello] = "some value"
21
- assert_equal "some value", channel[:hello]
22
- end
23
-
24
- def test_exec_should_be_syntactic_sugar_for_a_channel_request
25
- channel.expects(:send_channel_request).with("exec", :string, "ls").yields
26
- found_block = false
27
- channel.exec("ls") { found_block = true }
28
- assert found_block, "expected block to be passed to send_channel_request"
29
- end
30
-
31
- def test_subsystem_should_be_syntactic_sugar_for_a_channel_request
32
- channel.expects(:send_channel_request).with("subsystem", :string, "sftp").yields
33
- found_block = false
34
- channel.subsystem("sftp") { found_block = true }
35
- assert found_block, "expected block to be passed to send_channel_request"
36
- end
37
-
38
- def test_request_pty_with_invalid_option_should_raise_error
39
- assert_raises(ArgumentError) do
40
- channel.request_pty(:bogus => "thing")
41
- end
42
- end
43
-
44
- def test_request_pty_without_options_should_use_defaults
45
- channel.expects(:send_channel_request).with("pty-req", :string, "xterm",
46
- :long, 80, :long, 24, :long, 640, :long, 480, :string, "\0").yields
47
- found_block = false
48
- channel.request_pty { found_block = true }
49
- assert found_block, "expected block to be passed to send_channel_request"
50
- end
51
-
52
- def test_request_pty_with_options_should_honor_options
53
- channel.expects(:send_channel_request).with("pty-req", :string, "vanilla",
54
- :long, 60, :long, 15, :long, 400, :long, 200, :string, "\5\0\0\0\1\0")
55
- channel.request_pty :term => "vanilla", :chars_wide => 60, :chars_high => 15,
56
- :pixels_wide => 400, :pixels_high => 200, :modes => { 5 => 1 }
57
- end
58
-
59
- def test_send_data_should_append_to_channels_output_buffer
60
- channel.send_data("hello")
61
- assert_equal "hello", channel.output.to_s
62
- channel.send_data("world")
63
- assert_equal "helloworld", channel.output.to_s
64
- end
65
-
66
- def test_close_before_channel_has_been_confirmed_should_set_closing
67
- assert !channel.closing?
68
- channel.close
69
- assert channel.closing?
70
- end
71
-
72
- def test_close_should_set_closing_and_send_message
73
- channel.do_open_confirmation(0, 100, 100)
74
- assert !channel.closing?
75
-
76
- connection.expect { |t,packet| assert_equal CHANNEL_CLOSE, packet.type }
77
- connection.expects(:cleanup_channel).with(channel)
78
- channel.close
79
-
80
- channel.process
81
-
82
- assert channel.closing?
83
- end
84
-
85
- def test_close_while_closing_should_do_nothing
86
- test_close_should_set_closing_and_send_message
87
- assert_nothing_raised { channel.close }
88
- end
89
-
90
- def test_process_when_process_callback_is_not_set_should_just_enqueue_data
91
- channel.expects(:enqueue_pending_output)
92
- channel.process
93
- end
94
-
95
- def test_process_when_process_callback_is_set_should_yield_self_before_enqueuing_data
96
- channel.expects(:enqueue_pending_output).never
97
- channel.on_process { |ch| ch.expects(:enqueue_pending_output).once }
98
- channel.process
99
- end
100
-
101
- def test_enqueue_pending_output_should_have_no_effect_if_channel_has_not_been_confirmed
102
- channel.send_data("hello")
103
- assert_nothing_raised { channel.enqueue_pending_output }
104
- end
105
-
106
- def test_enqueue_pending_output_should_have_no_effect_if_there_is_no_output
107
- channel.do_open_confirmation(0, 100, 100)
108
- assert_nothing_raised { channel.enqueue_pending_output }
109
- end
110
-
111
- def test_enqueue_pending_output_should_not_enqueue_more_than_output_length
112
- channel.do_open_confirmation(0, 100, 100)
113
- channel.send_data("hello world")
114
-
115
- connection.expect do |t,packet|
116
- assert_equal CHANNEL_DATA, packet.type
117
- assert_equal 0, packet[:local_id]
118
- assert_equal 11, packet[:data].length
119
- end
120
-
121
- channel.enqueue_pending_output
122
- end
123
-
124
- def test_enqueue_pending_output_should_not_enqueue_more_than_max_packet_length_at_once
125
- channel.do_open_confirmation(0, 100, 8)
126
- channel.send_data("hello world")
127
-
128
- connection.expect do |t,packet|
129
- assert_equal CHANNEL_DATA, packet.type
130
- assert_equal 0, packet[:local_id]
131
- assert_equal "hello wo", packet[:data]
132
-
133
- t.expect do |t2,packet2|
134
- assert_equal CHANNEL_DATA, packet2.type
135
- assert_equal 0, packet2[:local_id]
136
- assert_equal "rld", packet2[:data]
137
- end
138
- end
139
-
140
- channel.enqueue_pending_output
141
- end
142
-
143
- def test_enqueue_pending_output_should_not_enqueue_more_than_max_window_size
144
- channel.do_open_confirmation(0, 8, 100)
145
- channel.send_data("hello world")
146
-
147
- connection.expect do |t,packet|
148
- assert_equal CHANNEL_DATA, packet.type
149
- assert_equal 0, packet[:local_id]
150
- assert_equal "hello wo", packet[:data]
151
- end
152
-
153
- channel.enqueue_pending_output
154
- end
155
-
156
- def test_on_data_with_block_should_set_callback
157
- flag = false
158
- channel.on_data { flag = !flag }
159
- channel.do_data("")
160
- assert(flag, "callback should have been invoked")
161
- channel.on_data
162
- channel.do_data("")
163
- assert(flag, "callback should have been removed")
164
- end
165
-
166
- def test_on_extended_data_with_block_should_set_callback
167
- flag = false
168
- channel.on_extended_data { flag = !flag }
169
- channel.do_extended_data(0, "")
170
- assert(flag, "callback should have been invoked")
171
- channel.on_extended_data
172
- channel.do_extended_data(0, "")
173
- assert(flag, "callback should have been removed")
174
- end
175
-
176
- def test_on_process_with_block_should_set_callback
177
- flag = false
178
- channel.on_process { flag = !flag }
179
- channel.process
180
- assert(flag, "callback should have been invoked")
181
- channel.on_process
182
- channel.process
183
- assert(flag, "callback should have been removed")
184
- end
185
-
186
- def test_on_close_with_block_should_set_callback
187
- flag = false
188
- channel.on_close { flag = !flag }
189
- channel.do_close
190
- assert(flag, "callback should have been invoked")
191
- channel.on_close
192
- channel.do_close
193
- assert(flag, "callback should have been removed")
194
- end
195
-
196
- def test_on_eof_with_block_should_set_callback
197
- flag = false
198
- channel.on_eof { flag = !flag }
199
- channel.do_eof
200
- assert(flag, "callback should have been invoked")
201
- channel.on_eof
202
- channel.do_eof
203
- assert(flag, "callback should have been removed")
204
- end
205
-
206
- def test_do_request_for_unhandled_request_should_do_nothing_if_not_wants_reply
207
- channel.do_open_confirmation(0, 100, 100)
208
- assert_nothing_raised { channel.do_request "exit-status", false, nil }
209
- end
210
-
211
- def test_do_request_for_unhandled_request_should_send_CHANNEL_FAILURE_if_wants_reply
212
- channel.do_open_confirmation(0, 100, 100)
213
- connection.expect { |t,packet| assert_equal CHANNEL_FAILURE, packet.type }
214
- channel.do_request "keepalive@openssh.com", true, nil
215
- end
216
-
217
- def test_do_request_for_handled_request_should_invoke_callback_and_do_nothing_if_returns_true_and_not_wants_reply
218
- channel.do_open_confirmation(0, 100, 100)
219
- flag = false
220
- channel.on_request("exit-status") { flag = true; true }
221
- assert_nothing_raised { channel.do_request "exit-status", false, nil }
222
- assert flag, "callback should have been invoked"
223
- end
224
-
225
- def test_do_request_for_handled_request_should_invoke_callback_and_do_nothing_if_fails_and_not_wants_reply
226
- channel.do_open_confirmation(0, 100, 100)
227
- flag = false
228
- channel.on_request("exit-status") { flag = true; raise Net::SSH::ChannelRequestFailed }
229
- assert_nothing_raised { channel.do_request "exit-status", false, nil }
230
- assert flag, "callback should have been invoked"
231
- end
232
-
233
- def test_do_request_for_handled_request_should_invoke_callback_and_send_CHANNEL_SUCCESS_if_returns_true_and_wants_reply
234
- channel.do_open_confirmation(0, 100, 100)
235
- flag = false
236
- channel.on_request("exit-status") { flag = true; true }
237
- connection.expect { |t,p| assert_equal CHANNEL_SUCCESS, p.type }
238
- assert_nothing_raised { channel.do_request "exit-status", true, nil }
239
- assert flag, "callback should have been invoked"
240
- end
241
-
242
- def test_do_request_for_handled_request_should_invoke_callback_and_send_CHANNEL_FAILURE_if_returns_false_and_wants_reply
243
- channel.do_open_confirmation(0, 100, 100)
244
- flag = false
245
- channel.on_request("exit-status") { flag = true; raise Net::SSH::ChannelRequestFailed }
246
- connection.expect { |t,p| assert_equal CHANNEL_FAILURE, p.type }
247
- assert_nothing_raised { channel.do_request "exit-status", true, nil }
248
- assert flag, "callback should have been invoked"
249
- end
250
-
251
- def test_send_channel_request_without_callback_should_not_want_reply
252
- channel.do_open_confirmation(0, 100, 100)
253
- connection.expect do |t,p|
254
- assert_equal CHANNEL_REQUEST, p.type
255
- assert_equal 0, p[:local_id]
256
- assert_equal "exec", p[:request]
257
- assert_equal false, p[:want_reply]
258
- assert_equal "ls", p[:request_data].read_string
259
- end
260
- channel.send_channel_request("exec", :string, "ls")
261
- assert channel.pending_requests.empty?
262
- end
263
-
264
- def test_send_channel_request_should_wait_for_remote_id
265
- channel.expects(:remote_id).times(1).returns(nil)
266
- msg = nil
267
- begin
268
- channel.send_channel_request("exec", :string, "ls")
269
- rescue RuntimeError => e
270
- msg = e.message
271
- end
272
- assert_equal "Channel open not yet confirmed, please call send_channel_request(or exec) from block of open_channel", msg
273
- assert channel.pending_requests.empty?
274
- end
275
-
276
- def test_send_channel_request_with_callback_should_want_reply
277
- channel.do_open_confirmation(0, 100, 100)
278
- connection.expect do |t,p|
279
- assert_equal CHANNEL_REQUEST, p.type
280
- assert_equal 0, p[:local_id]
281
- assert_equal "exec", p[:request]
282
- assert_equal true, p[:want_reply]
283
- assert_equal "ls", p[:request_data].read_string
284
- end
285
- callback = Proc.new {}
286
- channel.send_channel_request("exec", :string, "ls", &callback)
287
- assert_equal [callback], channel.pending_requests
288
- end
289
-
290
- def test_do_open_confirmation_should_set_remote_parameters
291
- channel.do_open_confirmation(1, 2, 3)
292
- assert_equal 1, channel.remote_id
293
- assert_equal 2, channel.remote_window_size
294
- assert_equal 2, channel.remote_maximum_window_size
295
- assert_equal 3, channel.remote_maximum_packet_size
296
- end
297
-
298
- def test_do_open_confirmation_should_call_open_confirmation_callback
299
- flag = false
300
- channel { flag = true }
301
- assert !flag, "callback should not have been invoked yet"
302
- channel.do_open_confirmation(1,2,3)
303
- assert flag, "callback should have been invoked"
304
- end
305
-
306
- def test_do_open_confirmation_with_session_channel_should_invoke_agent_forwarding_if_agent_forwarding_requested
307
- connection :forward_agent => true
308
- forward = mock("forward")
309
- forward.expects(:agent).with(channel)
310
- connection.expects(:forward).returns(forward)
311
- channel.do_open_confirmation(1,2,3)
312
- end
313
-
314
- def test_do_open_confirmation_with_non_session_channel_should_not_invoke_agent_forwarding_even_if_agent_forwarding_requested
315
- connection :forward_agent => true
316
- channel :type => "direct-tcpip"
317
- connection.expects(:forward).never
318
- channel.do_open_confirmation(1,2,3)
319
- end
320
-
321
- def test_do_window_adjust_should_adjust_remote_window_size_by_the_given_amount
322
- channel.do_open_confirmation(0, 1000, 1000)
323
- assert_equal 1000, channel.remote_window_size
324
- assert_equal 1000, channel.remote_maximum_window_size
325
- channel.do_window_adjust(500)
326
- assert_equal 1500, channel.remote_window_size
327
- assert_equal 1500, channel.remote_maximum_window_size
328
- end
329
-
330
- def test_do_data_should_update_local_window_size
331
- assert_equal 0x20000, channel.local_maximum_window_size
332
- assert_equal 0x20000, channel.local_window_size
333
- channel.do_data("here is some data")
334
- assert_equal 0x20000, channel.local_maximum_window_size
335
- assert_equal 0x1FFEF, channel.local_window_size
336
- end
337
-
338
- def test_do_extended_data_should_update_local_window_size
339
- assert_equal 0x20000, channel.local_maximum_window_size
340
- assert_equal 0x20000, channel.local_window_size
341
- channel.do_extended_data(1, "here is some data")
342
- assert_equal 0x20000, channel.local_maximum_window_size
343
- assert_equal 0x1FFEF, channel.local_window_size
344
- end
345
-
346
- def test_do_data_when_local_window_size_drops_below_threshold_should_trigger_WINDOW_ADJUST_message
347
- channel.do_open_confirmation(0, 1000, 1000)
348
- assert_equal 0x20000, channel.local_maximum_window_size
349
- assert_equal 0x20000, channel.local_window_size
350
-
351
- connection.expect do |t,p|
352
- assert_equal CHANNEL_WINDOW_ADJUST, p.type
353
- assert_equal 0, p[:local_id]
354
- assert_equal 0x20000, p[:extra_bytes]
355
- end
356
-
357
- channel.do_data("." * 0x10001)
358
- assert_equal 0x40000, channel.local_maximum_window_size
359
- assert_equal 0x2FFFF, channel.local_window_size
360
- end
361
-
362
- def test_do_failure_should_grab_next_pending_request_and_call_it
363
- result = nil
364
- channel.pending_requests << Proc.new { |*args| result = args }
365
- channel.do_failure
366
- assert_equal [channel, false], result
367
- assert channel.pending_requests.empty?
368
- end
369
-
370
- def test_do_success_should_grab_next_pending_request_and_call_it
371
- result = nil
372
- channel.pending_requests << Proc.new { |*args| result = args }
373
- channel.do_success
374
- assert_equal [channel, true], result
375
- assert channel.pending_requests.empty?
376
- end
377
-
378
- def test_active_should_be_true_when_channel_appears_in_channel_list
379
- connection.channels[channel.local_id] = channel
380
- assert channel.active?
381
- end
382
-
383
- def test_active_should_be_false_when_channel_is_not_in_channel_list
384
- assert !channel.active?
385
- end
386
-
387
- def test_wait_should_block_while_channel_is_active?
388
- channel.expects(:active?).times(3).returns(true,true,false)
389
- channel.wait
390
- end
391
-
392
- def test_wait_until_open_confirmed_should_block_while_remote_id_nil
393
- channel.expects(:remote_id).times(3).returns(nil,nil,3)
394
- channel.send(:wait_until_open_confirmed)
395
- end
396
-
397
- def test_eof_bang_should_send_eof_to_server
398
- channel.do_open_confirmation(0, 1000, 1000)
399
- connection.expect { |t,p| assert_equal CHANNEL_EOF, p.type }
400
- channel.eof!
401
- channel.process
402
- end
403
-
404
- def test_eof_bang_should_not_send_eof_if_eof_was_already_declared
405
- channel.do_open_confirmation(0, 1000, 1000)
406
- connection.expect { |t,p| assert_equal CHANNEL_EOF, p.type }
407
- channel.eof!
408
- assert_nothing_raised { channel.eof! }
409
- channel.process
410
- end
411
-
412
- def test_eof_q_should_return_true_if_eof_declared
413
- channel.do_open_confirmation(0, 1000, 1000)
414
- connection.expect { |t,p| assert_equal CHANNEL_EOF, p.type }
415
-
416
- assert !channel.eof?
417
- channel.eof!
418
- assert channel.eof?
419
- channel.process
420
- end
421
-
422
- def test_send_data_should_raise_exception_if_eof_declared
423
- channel.do_open_confirmation(0, 1000, 1000)
424
- connection.expect { |t,p| assert_equal CHANNEL_EOF, p.type }
425
- channel.eof!
426
- channel.process
427
- assert_raises(EOFError) { channel.send_data("die! die! die!") }
428
- end
429
-
430
- def test_data_should_precede_eof
431
- channel.do_open_confirmation(0, 1000, 1000)
432
- connection.expect do |t,p|
433
- assert_equal CHANNEL_DATA, p.type
434
- connection.expect { |t,p| assert_equal CHANNEL_EOF, p.type }
435
- end
436
- channel.send_data "foo"
437
- channel.eof!
438
- channel.process
439
- end
440
-
441
- private
442
-
443
- class MockConnection
444
- attr_reader :logger
445
- attr_reader :options
446
- attr_reader :channels
447
-
448
- def initialize(options={})
449
- @expectation = nil
450
- @options = options
451
- @channels = {}
452
- end
453
-
454
- def expect(&block)
455
- @expectation = block
456
- end
457
-
458
- def send_message(msg)
459
- raise "#{msg.to_s.inspect} recieved but no message was expected" unless @expectation
460
- packet = Net::SSH::Packet.new(msg.to_s)
461
- callback, @expectation = @expectation, nil
462
- callback.call(self, packet)
463
- end
464
-
465
- alias loop_forever loop
466
- def loop(&block)
467
- loop_forever { break unless block.call }
468
- end
469
-
470
- def test!
471
- raise "expected a packet but none were sent" if @expectation
472
- end
473
- end
474
-
475
- def connection(options={})
476
- @connection ||= MockConnection.new(options)
477
- end
478
-
479
- def channel(options={}, &block)
480
- @channel ||= Net::SSH::Connection::Channel.new(connection(options),
481
- options[:type] || "session",
482
- options[:local_id] || 0,
483
- &block)
484
- end
485
- end
486
-
487
- end