net-ssh-net-ssh 2.0.12

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 (105) hide show
  1. data/CHANGELOG.rdoc +137 -0
  2. data/Manifest +104 -0
  3. data/README.rdoc +110 -0
  4. data/Rakefile +79 -0
  5. data/THANKS.rdoc +16 -0
  6. data/lib/net/ssh.rb +215 -0
  7. data/lib/net/ssh/authentication/agent.rb +176 -0
  8. data/lib/net/ssh/authentication/constants.rb +18 -0
  9. data/lib/net/ssh/authentication/key_manager.rb +193 -0
  10. data/lib/net/ssh/authentication/methods/abstract.rb +60 -0
  11. data/lib/net/ssh/authentication/methods/hostbased.rb +71 -0
  12. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +66 -0
  13. data/lib/net/ssh/authentication/methods/password.rb +39 -0
  14. data/lib/net/ssh/authentication/methods/publickey.rb +92 -0
  15. data/lib/net/ssh/authentication/pageant.rb +183 -0
  16. data/lib/net/ssh/authentication/session.rb +134 -0
  17. data/lib/net/ssh/buffer.rb +340 -0
  18. data/lib/net/ssh/buffered_io.rb +149 -0
  19. data/lib/net/ssh/config.rb +181 -0
  20. data/lib/net/ssh/connection/channel.rb +625 -0
  21. data/lib/net/ssh/connection/constants.rb +33 -0
  22. data/lib/net/ssh/connection/session.rb +596 -0
  23. data/lib/net/ssh/connection/term.rb +178 -0
  24. data/lib/net/ssh/errors.rb +85 -0
  25. data/lib/net/ssh/key_factory.rb +102 -0
  26. data/lib/net/ssh/known_hosts.rb +129 -0
  27. data/lib/net/ssh/loggable.rb +61 -0
  28. data/lib/net/ssh/packet.rb +102 -0
  29. data/lib/net/ssh/prompt.rb +93 -0
  30. data/lib/net/ssh/proxy/errors.rb +14 -0
  31. data/lib/net/ssh/proxy/http.rb +94 -0
  32. data/lib/net/ssh/proxy/socks4.rb +70 -0
  33. data/lib/net/ssh/proxy/socks5.rb +129 -0
  34. data/lib/net/ssh/ruby_compat.rb +7 -0
  35. data/lib/net/ssh/service/forward.rb +267 -0
  36. data/lib/net/ssh/test.rb +89 -0
  37. data/lib/net/ssh/test/channel.rb +129 -0
  38. data/lib/net/ssh/test/extensions.rb +152 -0
  39. data/lib/net/ssh/test/kex.rb +44 -0
  40. data/lib/net/ssh/test/local_packet.rb +51 -0
  41. data/lib/net/ssh/test/packet.rb +81 -0
  42. data/lib/net/ssh/test/remote_packet.rb +38 -0
  43. data/lib/net/ssh/test/script.rb +157 -0
  44. data/lib/net/ssh/test/socket.rb +59 -0
  45. data/lib/net/ssh/transport/algorithms.rb +384 -0
  46. data/lib/net/ssh/transport/cipher_factory.rb +84 -0
  47. data/lib/net/ssh/transport/constants.rb +30 -0
  48. data/lib/net/ssh/transport/hmac.rb +31 -0
  49. data/lib/net/ssh/transport/hmac/abstract.rb +78 -0
  50. data/lib/net/ssh/transport/hmac/md5.rb +12 -0
  51. data/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  52. data/lib/net/ssh/transport/hmac/none.rb +15 -0
  53. data/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  54. data/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  55. data/lib/net/ssh/transport/identity_cipher.rb +55 -0
  56. data/lib/net/ssh/transport/kex.rb +13 -0
  57. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +208 -0
  58. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +77 -0
  59. data/lib/net/ssh/transport/openssl.rb +128 -0
  60. data/lib/net/ssh/transport/packet_stream.rb +230 -0
  61. data/lib/net/ssh/transport/server_version.rb +69 -0
  62. data/lib/net/ssh/transport/session.rb +276 -0
  63. data/lib/net/ssh/transport/state.rb +206 -0
  64. data/lib/net/ssh/verifiers/lenient.rb +30 -0
  65. data/lib/net/ssh/verifiers/null.rb +12 -0
  66. data/lib/net/ssh/verifiers/strict.rb +53 -0
  67. data/lib/net/ssh/version.rb +62 -0
  68. data/net-ssh.gemspec +128 -0
  69. data/setup.rb +1585 -0
  70. data/test/authentication/methods/common.rb +28 -0
  71. data/test/authentication/methods/test_abstract.rb +51 -0
  72. data/test/authentication/methods/test_hostbased.rb +114 -0
  73. data/test/authentication/methods/test_keyboard_interactive.rb +98 -0
  74. data/test/authentication/methods/test_password.rb +50 -0
  75. data/test/authentication/methods/test_publickey.rb +127 -0
  76. data/test/authentication/test_agent.rb +205 -0
  77. data/test/authentication/test_key_manager.rb +105 -0
  78. data/test/authentication/test_session.rb +93 -0
  79. data/test/common.rb +106 -0
  80. data/test/configs/eqsign +3 -0
  81. data/test/configs/exact_match +8 -0
  82. data/test/configs/wild_cards +14 -0
  83. data/test/connection/test_channel.rb +452 -0
  84. data/test/connection/test_session.rb +488 -0
  85. data/test/test_all.rb +6 -0
  86. data/test/test_buffer.rb +336 -0
  87. data/test/test_buffered_io.rb +63 -0
  88. data/test/test_config.rb +84 -0
  89. data/test/test_key_factory.rb +67 -0
  90. data/test/transport/hmac/test_md5.rb +39 -0
  91. data/test/transport/hmac/test_md5_96.rb +25 -0
  92. data/test/transport/hmac/test_none.rb +34 -0
  93. data/test/transport/hmac/test_sha1.rb +34 -0
  94. data/test/transport/hmac/test_sha1_96.rb +25 -0
  95. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  96. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  97. data/test/transport/test_algorithms.rb +302 -0
  98. data/test/transport/test_cipher_factory.rb +171 -0
  99. data/test/transport/test_hmac.rb +34 -0
  100. data/test/transport/test_identity_cipher.rb +40 -0
  101. data/test/transport/test_packet_stream.rb +435 -0
  102. data/test/transport/test_server_version.rb +68 -0
  103. data/test/transport/test_session.rb +315 -0
  104. data/test/transport/test_state.rb +173 -0
  105. metadata +162 -0
@@ -0,0 +1,68 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/server_version'
3
+
4
+ module Transport
5
+
6
+ class TestServerVersion < Test::Unit::TestCase
7
+
8
+ def test_1_99_server_version_should_be_acceptible
9
+ s = subject(socket(true, "SSH-1.99-Testing_1.0\r\n"))
10
+ assert s.header.empty?
11
+ assert_equal "SSH-1.99-Testing_1.0", s.version
12
+ end
13
+
14
+ def test_2_0_server_version_should_be_acceptible
15
+ s = subject(socket(true, "SSH-2.0-Testing_1.0\r\n"))
16
+ assert s.header.empty?
17
+ assert_equal "SSH-2.0-Testing_1.0", s.version
18
+ end
19
+
20
+ def test_trailing_whitespace_should_be_preserved
21
+ # some servers, like Mocana, send a version string with trailing
22
+ # spaces, which are significant when exchanging keys later.
23
+ s = subject(socket(true, "SSH-2.0-Testing_1.0 \r\n"))
24
+ assert_equal "SSH-2.0-Testing_1.0 ", s.version
25
+ end
26
+
27
+ def test_unacceptible_server_version_should_raise_exception
28
+ assert_raises(Net::SSH::Exception) { subject(socket(false, "SSH-1.4-Testing_1.0\r\n")) }
29
+ end
30
+
31
+ def test_header_lines_should_be_accumulated
32
+ s = subject(socket(true, "Welcome\r\nAnother line\r\nSSH-2.0-Testing_1.0\r\n"))
33
+ assert_equal "Welcome\r\nAnother line\r\n", s.header
34
+ assert_equal "SSH-2.0-Testing_1.0", s.version
35
+ end
36
+
37
+ def test_server_disconnect_should_raise_exception
38
+ assert_raises(Net::SSH::Disconnect) { subject(socket(false, "SSH-2.0-Aborting")) }
39
+ end
40
+
41
+ private
42
+
43
+ def socket(good, version_header)
44
+ socket = mock("socket")
45
+
46
+ data = version_header.split('')
47
+ recv_times = data.length
48
+ if data[-1] != "\n"
49
+ recv_times += 1
50
+ end
51
+ socket.expects(:recv).with(1).times(recv_times).returns(*data).then.returns(nil)
52
+
53
+ if good
54
+ socket.expects(:write).with("#{Net::SSH::Transport::ServerVersion::PROTO_VERSION}\r\n")
55
+ socket.expects(:flush)
56
+ else
57
+ socket.expects(:write).never
58
+ end
59
+
60
+ socket
61
+ end
62
+
63
+ def subject(socket)
64
+ Net::SSH::Transport::ServerVersion.new(socket, nil)
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,315 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/session'
3
+
4
+ # mocha adds #verify to Object, which throws off the host-key-verifier part of
5
+ # these tests.
6
+
7
+ # can't use .include? because ruby18 uses strings and ruby19 uses symbols :/
8
+ if Object.instance_methods.any? { |v| v.to_sym == :verify }
9
+ Object.send(:undef_method, :verify)
10
+ end
11
+
12
+ module Transport
13
+
14
+ class TestSession < Test::Unit::TestCase
15
+ include Net::SSH::Transport::Constants
16
+
17
+ def test_constructor_defaults
18
+ assert_equal "net.ssh.test", session.host
19
+ assert_equal 22, session.port
20
+ assert_instance_of Net::SSH::Verifiers::Lenient, session.host_key_verifier
21
+ end
22
+
23
+ def test_paranoid_true_uses_lenient_verifier
24
+ assert_instance_of Net::SSH::Verifiers::Lenient, session(:paranoid => true).host_key_verifier
25
+ end
26
+
27
+ def test_paranoid_very_uses_strict_verifier
28
+ assert_instance_of Net::SSH::Verifiers::Strict, session(:paranoid => :very).host_key_verifier
29
+ end
30
+
31
+ def test_paranoid_false_uses_null_verifier
32
+ assert_instance_of Net::SSH::Verifiers::Null, session(:paranoid => false).host_key_verifier
33
+ end
34
+
35
+ def test_unknown_paranoid_value_raises_exception_if_value_does_not_respond_to_verify
36
+ assert_raises(ArgumentError) { session(:paranoid => :bogus).host_key_verifier }
37
+ end
38
+
39
+ def test_paranoid_value_responding_to_verify_should_pass_muster
40
+ object = stub("thingy", :verify => true)
41
+ assert_equal object, session(:paranoid => object).host_key_verifier
42
+ end
43
+
44
+ def test_host_as_string_should_return_host_and_ip_when_port_is_default
45
+ session!
46
+ socket.stubs(:peer_ip).returns("1.2.3.4")
47
+ assert_equal "net.ssh.test,1.2.3.4", session.host_as_string
48
+ end
49
+
50
+ def test_host_as_string_should_return_host_and_ip_with_port_when_port_is_not_default
51
+ session(:port => 1234) # force session to be instantiated
52
+ socket.stubs(:peer_ip).returns("1.2.3.4")
53
+ assert_equal "[net.ssh.test]:1234,[1.2.3.4]:1234", session.host_as_string
54
+ end
55
+
56
+ def test_host_as_string_should_return_only_host_when_host_is_ip
57
+ session!(:host => "1.2.3.4")
58
+ socket.stubs(:peer_ip).returns("1.2.3.4")
59
+ assert_equal "1.2.3.4", session.host_as_string
60
+ end
61
+
62
+ def test_host_as_string_should_return_only_host_and_port_when_host_is_ip_and_port_is_not_default
63
+ session!(:host => "1.2.3.4", :port => 1234)
64
+ socket.stubs(:peer_ip).returns("1.2.3.4")
65
+ assert_equal "[1.2.3.4]:1234", session.host_as_string
66
+ end
67
+
68
+ def test_close_should_cleanup_and_close_socket
69
+ session!
70
+ socket.expects(:cleanup)
71
+ socket.expects(:close)
72
+ session.close
73
+ end
74
+
75
+ def test_service_request_should_return_buffer
76
+ assert_equal "\005\000\000\000\004sftp", session.service_request('sftp').to_s
77
+ end
78
+
79
+ def test_rekey_when_kex_is_pending_should_do_nothing
80
+ algorithms.stubs(:pending? => true)
81
+ algorithms.expects(:rekey!).never
82
+ session.rekey!
83
+ end
84
+
85
+ def test_rekey_when_no_kex_is_pending_should_initiate_rekey_and_block_until_it_completes
86
+ algorithms.stubs(:pending? => false)
87
+ algorithms.expects(:rekey!)
88
+ session.expects(:wait).yields
89
+ algorithms.expects(:initialized?).returns(true)
90
+ session.rekey!
91
+ end
92
+
93
+ def test_rekey_as_needed_when_kex_is_pending_should_do_nothing
94
+ session!
95
+ algorithms.stubs(:pending? => true)
96
+ socket.expects(:if_needs_rekey?).never
97
+ session.rekey_as_needed
98
+ end
99
+
100
+ def test_rekey_as_needed_when_no_kex_is_pending_and_no_rekey_is_needed_should_do_nothing
101
+ session!
102
+ algorithms.stubs(:pending? => false)
103
+ socket.stubs(:if_needs_rekey? => false)
104
+ session.expects(:rekey!).never
105
+ session.rekey_as_needed
106
+ end
107
+
108
+ def test_rekey_as_needed_when_no_kex_is_pending_and_rekey_is_needed_should_initiate_rekey_and_block
109
+ session!
110
+ algorithms.stubs(:pending? => false)
111
+ socket.expects(:if_needs_rekey?).yields
112
+ session.expects(:rekey!)
113
+ session.rekey_as_needed
114
+ end
115
+
116
+ def test_peer_should_return_hash_of_info_about_peer
117
+ session!
118
+ socket.stubs(:peer_ip => "1.2.3.4")
119
+ assert_equal({:ip => "1.2.3.4", :port => 22, :host => "net.ssh.test", :canonized => "net.ssh.test,1.2.3.4"}, session.peer)
120
+ end
121
+
122
+ def test_next_message_should_block_until_next_message_is_available
123
+ session.expects(:poll_message).with(:block)
124
+ session.next_message
125
+ end
126
+
127
+ def test_poll_message_should_query_next_packet_using_the_given_blocking_parameter
128
+ session!
129
+ socket.expects(:next_packet).with(:blocking_parameter).returns(nil)
130
+ session.poll_message(:blocking_parameter)
131
+ end
132
+
133
+ def test_poll_message_should_default_to_non_blocking
134
+ session!
135
+ socket.expects(:next_packet).with(:nonblock).returns(nil)
136
+ session.poll_message
137
+ end
138
+
139
+ def test_poll_message_should_silently_handle_disconnect_packets
140
+ session!
141
+ socket.expects(:next_packet).returns(P(:byte, DISCONNECT, :long, 1, :string, "testing", :string, ""))
142
+ assert_raises(Net::SSH::Disconnect) { session.poll_message }
143
+ end
144
+
145
+ def test_poll_message_should_silently_handle_ignore_packets
146
+ session!
147
+ socket.expects(:next_packet).times(2).returns(P(:byte, IGNORE, :string, "test"), nil)
148
+ assert_nil session.poll_message
149
+ end
150
+
151
+ def test_poll_message_should_silently_handle_unimplemented_packets
152
+ session!
153
+ socket.expects(:next_packet).times(2).returns(P(:byte, UNIMPLEMENTED, :long, 15), nil)
154
+ assert_nil session.poll_message
155
+ end
156
+
157
+ def test_poll_message_should_silently_handle_debug_packets_with_always_display
158
+ session!
159
+ socket.expects(:next_packet).times(2).returns(P(:byte, DEBUG, :bool, true, :string, "testing", :string, ""), nil)
160
+ assert_nil session.poll_message
161
+ end
162
+
163
+ def test_poll_message_should_silently_handle_debug_packets_without_always_display
164
+ session!
165
+ socket.expects(:next_packet).times(2).returns(P(:byte, DEBUG, :bool, false, :string, "testing", :string, ""), nil)
166
+ assert_nil session.poll_message
167
+ end
168
+
169
+ def test_poll_message_should_silently_handle_kexinit_packets
170
+ session!
171
+ packet = P(:byte, KEXINIT, :raw, "lasdfalksdjfa;slkdfja;slkfjsdfaklsjdfa;df")
172
+ socket.expects(:next_packet).times(2).returns(packet, nil)
173
+ algorithms.expects(:accept_kexinit).with(packet)
174
+ assert_nil session.poll_message
175
+ end
176
+
177
+ def test_poll_message_should_return_other_packets
178
+ session!
179
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
180
+ socket.expects(:next_packet).returns(packet)
181
+ assert_equal packet, session.poll_message
182
+ end
183
+
184
+ def test_poll_message_should_enqueue_packets_when_algorithm_disallows_packet
185
+ session!
186
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
187
+ algorithms.stubs(:allow?).with(packet).returns(false)
188
+ socket.expects(:next_packet).times(2).returns(packet, nil)
189
+ assert_nil session.poll_message
190
+ assert_equal [packet], session.queue
191
+ end
192
+
193
+ def test_poll_message_should_read_from_queue_when_next_in_queue_is_allowed_and_consume_queue_is_true
194
+ session!
195
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
196
+ session.push(packet)
197
+ socket.expects(:next_packet).never
198
+ assert_equal packet, session.poll_message
199
+ assert session.queue.empty?
200
+ end
201
+
202
+ def test_poll_message_should_not_read_from_queue_when_next_in_queue_is_not_allowed
203
+ session!
204
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
205
+ algorithms.stubs(:allow?).with(packet).returns(false)
206
+ session.push(packet)
207
+ socket.expects(:next_packet).returns(nil)
208
+ assert_nil session.poll_message
209
+ assert_equal [packet], session.queue
210
+ end
211
+
212
+ def test_poll_message_should_not_read_from_queue_when_consume_queue_is_false
213
+ session!
214
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
215
+ session.push(packet)
216
+ socket.expects(:next_packet).returns(nil)
217
+ assert_nil session.poll_message(:nonblock, false)
218
+ assert_equal [packet], session.queue
219
+ end
220
+
221
+ def test_wait_with_block_should_return_immediately_if_block_returns_truth
222
+ session.expects(:poll_message).never
223
+ session.wait { true }
224
+ end
225
+
226
+ def test_wait_should_not_consume_queue_on_reads
227
+ n = 0
228
+ session.expects(:poll_message).with(:nonblock, false).returns(nil)
229
+ session.wait { (n += 1) > 1 }
230
+ end
231
+
232
+ def test_wait_without_block_should_return_after_first_read
233
+ session.expects(:poll_message).returns(nil)
234
+ session.wait
235
+ end
236
+
237
+ def test_wait_should_enqueue_packets
238
+ session!
239
+
240
+ p1 = P(:byte, SERVICE_REQUEST, :string, "test")
241
+ p2 = P(:byte, SERVICE_ACCEPT, :string, "test")
242
+ socket.expects(:next_packet).times(2).returns(p1, p2)
243
+
244
+ n = 0
245
+ session.wait { (n += 1) > 2 }
246
+ assert_equal [p1, p2], session.queue
247
+ end
248
+
249
+ def test_push_should_enqueue_packet
250
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
251
+ session.push(packet)
252
+ assert_equal [packet], session.queue
253
+ end
254
+
255
+ def test_send_message_should_delegate_to_socket
256
+ session!
257
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
258
+ socket.expects(:send_packet).with(packet)
259
+ session.send_message(packet)
260
+ end
261
+
262
+ def test_enqueue_message_should_delegate_to_socket
263
+ session!
264
+ packet = P(:byte, SERVICE_ACCEPT, :string, "test")
265
+ socket.expects(:enqueue_packet).with(packet)
266
+ session.enqueue_message(packet)
267
+ end
268
+
269
+ def test_configure_client_should_pass_options_to_socket_client_state
270
+ session.configure_client :compression => :standard
271
+ assert_equal :standard, socket.client.compression
272
+ end
273
+
274
+ def test_configure_server_should_pass_options_to_socket_server_state
275
+ session.configure_server :compression => :standard
276
+ assert_equal :standard, socket.server.compression
277
+ end
278
+
279
+ def test_hint_should_set_hint_on_socket
280
+ assert !socket.hints[:authenticated]
281
+ session.hint :authenticated
282
+ assert socket.hints[:authenticated]
283
+ end
284
+
285
+ private
286
+
287
+ def socket
288
+ @socket ||= stub("socket", :hints => {})
289
+ end
290
+
291
+ def server_version
292
+ @server_version ||= stub("server_version")
293
+ end
294
+
295
+ def algorithms
296
+ @algorithms ||= stub("algorithms", :initialized? => true, :allow? => true)
297
+ end
298
+
299
+ def session(options={})
300
+ @session ||= begin
301
+ host = options.delete(:host) || "net.ssh.test"
302
+ TCPSocket.stubs(:open).with(host, options[:port] || 22).returns(socket)
303
+ Net::SSH::Transport::ServerVersion.stubs(:new).returns(server_version)
304
+ Net::SSH::Transport::Algorithms.stubs(:new).returns(algorithms)
305
+
306
+ Net::SSH::Transport::Session.new(host, options)
307
+ end
308
+ end
309
+
310
+ # a simple alias to make the tests more self-documenting. the bang
311
+ # version makes it look more like the session is being instantiated
312
+ alias session! session
313
+ end
314
+
315
+ end
@@ -0,0 +1,173 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/state'
3
+
4
+ module Transport
5
+
6
+ class TestState < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @socket = @state = @deflater = @inflater = nil
10
+ end
11
+
12
+ def teardown
13
+ if @deflater
14
+ @deflater.finish if !@deflater.finished?
15
+ @deflater.close
16
+ end
17
+
18
+ if @inflater
19
+ @inflater.finish if !@inflater.finished?
20
+ @inflater.close
21
+ end
22
+
23
+ state.cleanup
24
+ end
25
+
26
+ def test_constructor_should_initialize_all_values
27
+ assert_equal 0, state.sequence_number
28
+ assert_equal 0, state.packets
29
+ assert_equal 0, state.blocks
30
+
31
+ assert_nil state.compression
32
+ assert_nil state.compression_level
33
+ assert_nil state.max_packets
34
+ assert_nil state.max_blocks
35
+ assert_nil state.rekey_limit
36
+
37
+ assert_equal "identity", state.cipher.name
38
+ assert_instance_of Net::SSH::Transport::HMAC::None, state.hmac
39
+ end
40
+
41
+ def test_increment_should_increment_counters
42
+ state.increment(24)
43
+ assert_equal 1, state.sequence_number
44
+ assert_equal 1, state.packets
45
+ assert_equal 3, state.blocks
46
+ end
47
+
48
+ def test_reset_should_reset_counters_and_fix_defaults_for_maximums
49
+ state.increment(24)
50
+ state.reset!
51
+ assert_equal 1, state.sequence_number
52
+ assert_equal 0, state.packets
53
+ assert_equal 0, state.blocks
54
+ assert_equal 2147483648, state.max_packets
55
+ assert_equal 134217728, state.max_blocks
56
+ end
57
+
58
+ def test_set_should_set_variables_and_reset_counters
59
+ state.expects(:reset!)
60
+ state.set :cipher => :a, :hmac => :b, :compression => :c,
61
+ :compression_level => :d, :max_packets => 500, :max_blocks => 1000,
62
+ :rekey_limit => 1500
63
+ assert_equal :a, state.cipher
64
+ assert_equal :b, state.hmac
65
+ assert_equal :c, state.compression
66
+ assert_equal :d, state.compression_level
67
+ assert_equal 500, state.max_packets
68
+ assert_equal 1000, state.max_blocks
69
+ assert_equal 1500, state.rekey_limit
70
+ end
71
+
72
+ def test_set_with_max_packets_should_respect_max_packets_setting
73
+ state.set :max_packets => 500
74
+ assert_equal 500, state.max_packets
75
+ end
76
+
77
+ def test_set_with_max_blocks_should_respect_max_blocks_setting
78
+ state.set :max_blocks => 1000
79
+ assert_equal 1000, state.max_blocks
80
+ end
81
+
82
+ def test_set_with_rekey_limit_should_include_rekey_limit_in_computation_of_max_blocks
83
+ state.set :rekey_limit => 4000
84
+ assert_equal 500, state.max_blocks
85
+ end
86
+
87
+ def test_compressor_defaults_to_default_zlib_compression
88
+ expect = deflater.deflate("hello world")
89
+ assert_equal expect, state.compressor.deflate("hello world")
90
+ end
91
+
92
+ def test_compressor_uses_compression_level_when_given
93
+ state.set :compression_level => 1
94
+ expect = deflater(1).deflate("hello world")
95
+ assert_equal expect, state.compressor.deflate("hello world")
96
+ end
97
+
98
+ def test_compress_when_no_compression_is_active_returns_text
99
+ assert_equal "hello everybody", state.compress("hello everybody")
100
+ end
101
+
102
+ def test_decompress_when_no_compression_is_active_returns_text
103
+ assert_equal "hello everybody", state.decompress("hello everybody")
104
+ end
105
+
106
+ def test_compress_when_compression_is_delayed_and_no_auth_hint_is_set_should_return_text
107
+ state.set :compression => :delayed
108
+ assert_equal "hello everybody", state.compress("hello everybody")
109
+ end
110
+
111
+ def test_decompress_when_compression_is_delayed_and_no_auth_hint_is_set_should_return_text
112
+ state.set :compression => :delayed
113
+ assert_equal "hello everybody", state.decompress("hello everybody")
114
+ end
115
+
116
+ def test_compress_when_compression_is_enabled_should_return_compressed_text
117
+ state.set :compression => :standard
118
+ assert_equal "x\234\312H\315\311\311WH-K-\252L\312O\251\004\000\000\000\377\377", state.compress("hello everybody")
119
+ end
120
+
121
+ def test_decompress_when_compression_is_enabled_should_return_decompressed_text
122
+ state.set :compression => :standard
123
+ assert_equal "hello everybody", state.decompress("x\234\312H\315\311\311WH-K-\252L\312O\251\004\000\000\000\377\377")
124
+ end
125
+
126
+ def test_compress_when_compression_is_delayed_and_auth_hint_is_set_should_return_compressed_text
127
+ socket.hints[:authenticated] = true
128
+ state.set :compression => :delayed
129
+ assert_equal "x\234\312H\315\311\311WH-K-\252L\312O\251\004\000\000\000\377\377", state.compress("hello everybody")
130
+ end
131
+
132
+ def test_decompress_when_compression_is_delayed_and_auth_hint_is_set_should_return_decompressed_text
133
+ socket.hints[:authenticated] = true
134
+ state.set :compression => :delayed
135
+ assert_equal "hello everybody", state.decompress("x\234\312H\315\311\311WH-K-\252L\312O\251\004\000\000\000\377\377")
136
+ end
137
+
138
+ def test_needs_rekey_should_be_true_if_packets_exceeds_max_packets
139
+ state.set :max_packets => 2
140
+ state.increment(8)
141
+ state.increment(8)
142
+ assert !state.needs_rekey?
143
+ state.increment(8)
144
+ assert state.needs_rekey?
145
+ end
146
+
147
+ def test_needs_rekey_should_be_true_if_blocks_exceeds_max_blocks
148
+ state.set :max_blocks => 10
149
+ assert !state.needs_rekey?
150
+ state.increment(88)
151
+ assert state.needs_rekey?
152
+ end
153
+
154
+ private
155
+
156
+ def deflater(level=Zlib::DEFAULT_COMPRESSION)
157
+ @deflater ||= Zlib::Deflate.new(level)
158
+ end
159
+
160
+ def inflater
161
+ @inflater ||= Zlib::Inflate.new(nil)
162
+ end
163
+
164
+ def socket
165
+ @socket ||= stub("socket", :hints => {})
166
+ end
167
+
168
+ def state
169
+ @state ||= Net::SSH::Transport::State.new(socket, :test)
170
+ end
171
+ end
172
+
173
+ end