net-ssh 2.9.2 → 4.0.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 (138) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.gitignore +6 -0
  4. data/.rubocop.yml +5 -0
  5. data/.rubocop_todo.yml +1129 -0
  6. data/.travis.yml +41 -5
  7. data/CHANGES.txt +133 -1
  8. data/Gemfile +13 -0
  9. data/Gemfile.norbnacl +10 -0
  10. data/Gemfile.norbnacl.lock +41 -0
  11. data/ISSUE_TEMPLATE.md +30 -0
  12. data/README.rdoc +26 -81
  13. data/Rakefile +63 -45
  14. data/appveyor.yml +51 -0
  15. data/lib/net/ssh/authentication/agent.rb +174 -14
  16. data/lib/net/ssh/authentication/ed25519.rb +137 -0
  17. data/lib/net/ssh/authentication/ed25519_loader.rb +21 -0
  18. data/lib/net/ssh/authentication/key_manager.rb +36 -30
  19. data/lib/net/ssh/authentication/methods/abstract.rb +4 -0
  20. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +16 -9
  21. data/lib/net/ssh/authentication/methods/password.rb +17 -4
  22. data/lib/net/ssh/authentication/pageant.rb +166 -45
  23. data/lib/net/ssh/authentication/session.rb +3 -2
  24. data/lib/net/ssh/buffer.rb +49 -10
  25. data/lib/net/ssh/buffered_io.rb +17 -12
  26. data/lib/net/ssh/config.rb +39 -8
  27. data/lib/net/ssh/connection/channel.rb +42 -20
  28. data/lib/net/ssh/connection/event_loop.rb +114 -0
  29. data/lib/net/ssh/connection/keepalive.rb +2 -2
  30. data/lib/net/ssh/connection/session.rb +120 -34
  31. data/lib/net/ssh/errors.rb +6 -6
  32. data/lib/net/ssh/key_factory.rb +49 -43
  33. data/lib/net/ssh/known_hosts.rb +49 -3
  34. data/lib/net/ssh/prompt.rb +47 -78
  35. data/lib/net/ssh/proxy/command.rb +31 -5
  36. data/lib/net/ssh/proxy/http.rb +15 -11
  37. data/lib/net/ssh/proxy/https.rb +49 -0
  38. data/lib/net/ssh/proxy/socks4.rb +2 -1
  39. data/lib/net/ssh/proxy/socks5.rb +3 -2
  40. data/lib/net/ssh/ruby_compat.rb +2 -29
  41. data/lib/net/ssh/service/forward.rb +2 -2
  42. data/lib/net/ssh/test/channel.rb +7 -0
  43. data/lib/net/ssh/test/extensions.rb +17 -0
  44. data/lib/net/ssh/test/kex.rb +4 -4
  45. data/lib/net/ssh/test/packet.rb +18 -2
  46. data/lib/net/ssh/test/script.rb +16 -2
  47. data/lib/net/ssh/test/socket.rb +1 -1
  48. data/lib/net/ssh/test.rb +5 -5
  49. data/lib/net/ssh/transport/algorithms.rb +92 -75
  50. data/lib/net/ssh/transport/cipher_factory.rb +19 -26
  51. data/lib/net/ssh/transport/ctr.rb +7 -9
  52. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +20 -9
  53. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +5 -3
  54. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +1 -1
  55. data/lib/net/ssh/transport/key_expander.rb +1 -0
  56. data/lib/net/ssh/transport/openssl.rb +1 -1
  57. data/lib/net/ssh/transport/packet_stream.rb +11 -3
  58. data/lib/net/ssh/transport/server_version.rb +13 -6
  59. data/lib/net/ssh/transport/session.rb +20 -10
  60. data/lib/net/ssh/transport/state.rb +1 -1
  61. data/lib/net/ssh/verifiers/secure.rb +8 -10
  62. data/lib/net/ssh/version.rb +4 -4
  63. data/lib/net/ssh.rb +62 -14
  64. data/net-ssh-public_cert.pem +19 -18
  65. data/net-ssh.gemspec +34 -194
  66. data/support/arcfour_check.rb +1 -1
  67. data/support/ssh_tunnel_bug.rb +1 -1
  68. data.tar.gz.sig +0 -0
  69. metadata +125 -109
  70. metadata.gz.sig +0 -0
  71. data/Rudyfile +0 -96
  72. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  73. data/lib/net/ssh/authentication/agent/socket.rb +0 -178
  74. data/setup.rb +0 -1585
  75. data/test/README.txt +0 -47
  76. data/test/authentication/methods/common.rb +0 -28
  77. data/test/authentication/methods/test_abstract.rb +0 -51
  78. data/test/authentication/methods/test_hostbased.rb +0 -114
  79. data/test/authentication/methods/test_keyboard_interactive.rb +0 -100
  80. data/test/authentication/methods/test_none.rb +0 -41
  81. data/test/authentication/methods/test_password.rb +0 -95
  82. data/test/authentication/methods/test_publickey.rb +0 -148
  83. data/test/authentication/test_agent.rb +0 -224
  84. data/test/authentication/test_key_manager.rb +0 -227
  85. data/test/authentication/test_session.rb +0 -107
  86. data/test/common.rb +0 -108
  87. data/test/configs/auth_off +0 -5
  88. data/test/configs/auth_on +0 -4
  89. data/test/configs/empty +0 -0
  90. data/test/configs/eqsign +0 -3
  91. data/test/configs/exact_match +0 -8
  92. data/test/configs/host_plus +0 -10
  93. data/test/configs/multihost +0 -4
  94. data/test/configs/negative_match +0 -6
  95. data/test/configs/nohost +0 -19
  96. data/test/configs/numeric_host +0 -4
  97. data/test/configs/send_env +0 -2
  98. data/test/configs/substitutes +0 -8
  99. data/test/configs/wild_cards +0 -14
  100. data/test/connection/test_channel.rb +0 -467
  101. data/test/connection/test_session.rb +0 -543
  102. data/test/known_hosts/github +0 -1
  103. data/test/manual/test_forward.rb +0 -285
  104. data/test/manual/test_pageant.rb +0 -37
  105. data/test/start/test_connection.rb +0 -53
  106. data/test/start/test_options.rb +0 -43
  107. data/test/start/test_transport.rb +0 -28
  108. data/test/test_all.rb +0 -11
  109. data/test/test_buffer.rb +0 -433
  110. data/test/test_buffered_io.rb +0 -63
  111. data/test/test_config.rb +0 -221
  112. data/test/test_key_factory.rb +0 -191
  113. data/test/test_known_hosts.rb +0 -13
  114. data/test/transport/hmac/test_md5.rb +0 -41
  115. data/test/transport/hmac/test_md5_96.rb +0 -27
  116. data/test/transport/hmac/test_none.rb +0 -34
  117. data/test/transport/hmac/test_ripemd160.rb +0 -36
  118. data/test/transport/hmac/test_sha1.rb +0 -36
  119. data/test/transport/hmac/test_sha1_96.rb +0 -27
  120. data/test/transport/hmac/test_sha2_256.rb +0 -37
  121. data/test/transport/hmac/test_sha2_256_96.rb +0 -27
  122. data/test/transport/hmac/test_sha2_512.rb +0 -37
  123. data/test/transport/hmac/test_sha2_512_96.rb +0 -27
  124. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
  125. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -146
  126. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -92
  127. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -34
  128. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
  129. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
  130. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
  131. data/test/transport/test_algorithms.rb +0 -324
  132. data/test/transport/test_cipher_factory.rb +0 -443
  133. data/test/transport/test_hmac.rb +0 -34
  134. data/test/transport/test_identity_cipher.rb +0 -40
  135. data/test/transport/test_packet_stream.rb +0 -1761
  136. data/test/transport/test_server_version.rb +0 -78
  137. data/test/transport/test_session.rb +0 -331
  138. data/test/transport/test_state.rb +0 -181
@@ -1,285 +0,0 @@
1
- # $ ruby -Ilib -Itest -rrubygems test/manual/test_forward.rb
2
-
3
- # Tests for the following patch:
4
- #
5
- # http://github.com/net-ssh/net-ssh/tree/portfwfix
6
- #
7
- # It fixes 3 issues, regarding closing forwarded ports:
8
- #
9
- # 1.) if client closes a forwarded connection, but the server is reading, net-ssh terminates with IOError socket closed.
10
- # 2.) if client force closes (RST) a forwarded connection, but server is reading, net-ssh terminates with
11
- # 3.) if server closes the sending side, the on_eof is not handled.
12
- #
13
- # More info:
14
- #
15
- # http://net-ssh.lighthouseapp.com/projects/36253/tickets/7
16
-
17
- require 'common'
18
- require 'net/ssh/buffer'
19
- require 'net/ssh'
20
- require 'timeout'
21
- require 'tempfile'
22
-
23
- class TestForward < Test::Unit::TestCase
24
-
25
- def localhost
26
- 'localhost'
27
- end
28
-
29
- def ssh_start_params
30
- [localhost ,ENV['USER'], {:keys => "~/.ssh/id_rsa", :verbose => :debug}]
31
- end
32
-
33
- def start_server_sending_lot_of_data(exceptions)
34
- server = TCPServer.open(0)
35
- Thread.start do
36
- loop do
37
- Thread.start(server.accept) do |client|
38
- begin
39
- 10000.times do |i|
40
- client.puts "item#{i}"
41
- end
42
- client.close
43
- rescue
44
- exceptions << $!
45
- raise
46
- end
47
- end
48
- end
49
- end
50
- return server
51
- end
52
-
53
- def start_server_closing_soon(exceptions=nil)
54
- server = TCPServer.open(0)
55
- Thread.start do
56
- loop do
57
- Thread.start(server.accept) do |client|
58
- begin
59
- client.recv(1024)
60
- client.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, [1, 0].pack("ii"))
61
- client.close
62
- rescue
63
- exceptions << $!
64
- raise
65
- end
66
- end
67
- end
68
- end
69
- return server
70
- end
71
-
72
- def test_local_ephemeral_port_should_work_correctly
73
- session = Net::SSH.start(*ssh_start_params)
74
-
75
- assert_nothing_raised do
76
- assigned_port = session.forward.local(0, localhost, 22)
77
- assert_not_nil assigned_port
78
- assert_operator assigned_port, :>, 0
79
- end
80
- end
81
-
82
- def test_remote_ephemeral_port_should_work_correctly
83
- session = Net::SSH.start(*ssh_start_params)
84
-
85
- assert_nothing_raised do
86
- session.forward.remote(22, localhost, 0, localhost)
87
- session.loop { !(session.forward.active_remotes.length > 0) }
88
- assigned_port = session.forward.active_remotes.first[0]
89
- assert_not_nil assigned_port
90
- assert_operator assigned_port, :>, 0
91
- end
92
- end
93
-
94
- def test_remote_callback_should_fire
95
- session = Net::SSH.start(*ssh_start_params)
96
-
97
- assert_nothing_raised do
98
- got_port = nil
99
- session.forward.remote(22, localhost, 0, localhost) do |port|
100
- got_port = port
101
- end
102
- session.loop { !(session.forward.active_remotes.length > 0) }
103
- assert_operator session.forward.active_remote_destinations.length, :==, 1
104
- assert_operator session.forward.active_remote_destinations.keys.first, :==, [ 22, localhost ]
105
- assert_operator session.forward.active_remote_destinations.values.first, :==, [ got_port, localhost ]
106
- assert_operator session.forward.active_remotes.first, :==, [ got_port, localhost ]
107
- assigned_port = session.forward.active_remotes.first[0]
108
- assert_operator got_port, :==, assigned_port
109
- assert_not_nil assigned_port
110
- assert_operator assigned_port, :>, 0
111
- end
112
- end
113
-
114
- def test_remote_callback_should_fire_on_error_and_still_throw_exception
115
- session = Net::SSH.start(*ssh_start_params)
116
-
117
- assert_nothing_raised do
118
- session.forward.remote(22, localhost, 22, localhost) do |port|
119
- assert_operator port, :==, :error
120
- end
121
- end
122
- assert_raises(Net::SSH::Exception) do
123
- session.loop { true }
124
- end
125
- end
126
-
127
- def test_remote_callback_should_fire_on_error_but_not_throw_exception_if_asked_not_to
128
- session = Net::SSH.start(*ssh_start_params)
129
-
130
- assert_nothing_raised do
131
- got_port = nil
132
- session.forward.remote(22, localhost, 22, localhost) do |port|
133
- assert_operator port, :==, :error
134
- got_port = port
135
- :no_exception
136
- end
137
- session.loop { !got_port }
138
- assert_operator port, :==, :error
139
- assert_operator session.forward.active_remotes.length, :==, 0
140
- end
141
- end
142
-
143
- def test_loop_should_not_abort_when_local_side_of_forward_is_closed
144
- session = Net::SSH.start(*ssh_start_params)
145
- server_exc = Queue.new
146
- server = start_server_sending_lot_of_data(server_exc)
147
- remote_port = server.addr[1]
148
- local_port = 0 # request ephemeral port
149
- session.forward.local(local_port, localhost, remote_port)
150
- client_done = Queue.new
151
- Thread.start do
152
- begin
153
- client = TCPSocket.new(localhost, local_port)
154
- client.recv(1024)
155
- client.close
156
- sleep(0.2)
157
- ensure
158
- client_done << true
159
- end
160
- end
161
- session.loop(0.1) { client_done.empty? }
162
- assert_equal "Broken pipe", "#{server_exc.pop}" unless server_exc.empty?
163
- end
164
-
165
- def test_loop_should_not_abort_when_local_side_of_forward_is_reset
166
- session = Net::SSH.start(*ssh_start_params)
167
- server_exc = Queue.new
168
- server = start_server_sending_lot_of_data(server_exc)
169
- remote_port = server.addr[1]
170
- local_port = 0 # request ephemeral port
171
- session.forward.local(local_port, localhost, remote_port)
172
- client_done = Queue.new
173
- Thread.start do
174
- begin
175
- client = TCPSocket.new(localhost, local_port)
176
- client.recv(1024)
177
- client.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, [1, 0].pack("ii"))
178
- client.close
179
- sleep(0.1)
180
- ensure
181
- client_done << true
182
- end
183
- end
184
- session.loop(0.1) { client_done.empty? }
185
- assert_equal "Broken pipe", "#{server_exc.pop}" unless server_exc.empty?
186
- end
187
-
188
- def create_local_socket(&blk)
189
- tempfile = Tempfile.new("net_ssh_forward_test")
190
- path = tempfile.path
191
- tempfile.delete
192
- yield UNIXServer.open(path)
193
- File.delete(path)
194
- end if defined?(UNIXServer)
195
-
196
- def test_forward_local_unix_socket_to_remote_port
197
- session = Net::SSH.start(*ssh_start_params)
198
- server_exc = Queue.new
199
- server = start_server_sending_lot_of_data(server_exc)
200
- remote_port = server.addr[1]
201
- client_data = nil
202
-
203
- create_local_socket do |local_socket|
204
- session.forward.local(local_socket, localhost, remote_port)
205
- client_done = Queue.new
206
-
207
- Thread.start do
208
- begin
209
- client = UNIXSocket.new(local_socket.path)
210
- client_data = client.recv(1024)
211
- client.close
212
- sleep(0.2)
213
- ensure
214
- client_done << true
215
- end
216
- end
217
-
218
- session.loop(0.1) { client_done.empty? }
219
- end
220
-
221
- assert_not_nil(client_data, "client should have received data")
222
- assert(client_data.match(/item\d/), 'client should have received the string item')
223
- end if defined?(UNIXSocket)
224
-
225
- def test_loop_should_not_abort_when_server_side_of_forward_is_closed
226
- session = Net::SSH.start(*ssh_start_params)
227
- server = start_server_closing_soon
228
- remote_port = server.addr[1]
229
- local_port = 0 # request ephemeral port
230
- session.forward.local(local_port, localhost, remote_port)
231
- client_done = Queue.new
232
- Thread.start do
233
- begin
234
- client = TCPSocket.new(localhost, local_port)
235
- 1.times do |i|
236
- client.puts "item#{i}"
237
- end
238
- client.close
239
- sleep(0.1)
240
- ensure
241
- client_done << true
242
- end
243
- end
244
- session.loop(0.1) { client_done.empty? }
245
- end
246
-
247
- def start_server
248
- server = TCPServer.open(0)
249
- Thread.start do
250
- loop do
251
- Thread.start(server.accept) do |client|
252
- yield(client)
253
- end
254
- end
255
- end
256
- return server
257
- end
258
-
259
- def test_server_eof_should_be_handled
260
- session = Net::SSH.start(*ssh_start_params)
261
- server = start_server do |client|
262
- client.write "This is a small message!"
263
- client.close
264
- end
265
- client_done = Queue.new
266
- client_exception = Queue.new
267
- client_data = Queue.new
268
- remote_port = server.addr[1]
269
- local_port = session.forward.local(0, localhost, remote_port)
270
- Thread.start do
271
- begin
272
- client = TCPSocket.new(localhost, local_port)
273
- data = client.read(4096)
274
- client.close
275
- client_done << data
276
- rescue
277
- client_done << $!
278
- end
279
- end
280
- timeout(5) do
281
- session.loop(0.1) { client_done.empty? }
282
- assert_equal "This is a small message!", client_done.pop
283
- end
284
- end
285
- end
@@ -1,37 +0,0 @@
1
- #
2
- # Tests for communication capability with Pageant (or KeeAgent)
3
- # process, to include the case where it is running in different UAC
4
- # context.
5
- #
6
- # To run:
7
- # - Ensure that Pageant is running (not as administrator).
8
- # - Open two command prompts, one as an administrator and one limited
9
- # (normal).
10
- # - Within each, from the root net/ssh project directory, execute:
11
- # ruby -Ilib -Itest -rrubygems test/manual/test_pageant.rb
12
- #
13
-
14
- require 'common'
15
- require 'net/ssh/authentication/agent'
16
-
17
- module Authentication
18
-
19
- class TestPageant < Test::Unit::TestCase
20
-
21
- def test_agent_should_be_able_to_negotiate
22
- assert_nothing_raised(Net::SSH::Authentication::AgentNotAvailable) { agent.negotiate! }
23
- end
24
-
25
- private
26
-
27
- def agent(auto=:connect)
28
- @agent ||= begin
29
- agent = Net::SSH::Authentication::Agent.new
30
- agent.connect! if auto == :connect
31
- agent
32
- end
33
- end
34
-
35
- end
36
-
37
- end
@@ -1,53 +0,0 @@
1
- require 'common'
2
- require 'net/ssh'
3
-
4
- module NetSSH
5
- class TestConnection < Test::Unit::TestCase
6
- attr_reader :connection_session
7
-
8
- def setup
9
- authentication_session = mock('authentication_session')
10
- authentication_session.stubs(:authenticate).returns(true)
11
- Net::SSH::Authentication::Session.stubs(:new).returns(authentication_session)
12
- Net::SSH::Transport::Session.stubs(:new).returns(mock('transport_session'))
13
- @connection_session = mock('connection_session')
14
- Net::SSH::Connection::Session.expects(:new => connection_session)
15
- end
16
-
17
- def test_close_connection_on_exception
18
- @connection_session.expects(:closed?).returns(false)
19
- @connection_session.expects(:close).once
20
-
21
- begin
22
- Net::SSH.start('localhost', 'testuser') { raise "error" }
23
- rescue RuntimeError
24
- # We aren't interested in the exception
25
- end
26
- end
27
-
28
- def test_close_connection_on_exception_only_if_still_open
29
- conn_open = states('conn').starts_as(true)
30
- @connection_session.expects(:close).then(conn_open.is(false)).once
31
- @connection_session.expects(:closed?).when(conn_open.is(false)).returns(true)
32
-
33
- begin
34
- Net::SSH.start('localhost', 'testuser') do |ssh|
35
- ssh.close
36
- raise "error"
37
- end
38
- rescue RuntimeError
39
- # We aren't interested in the exception
40
- end
41
- end
42
-
43
- def test_return_value_is_returned
44
- @connection_session.expects(:closed?).returns(false)
45
- @connection_session.expects(:close).once
46
-
47
- val = 1
48
- retval = Net::SSH.start('localhost', 'testuser') { val }
49
- assert_equal(val, retval)
50
- end
51
- end
52
- end
53
-
@@ -1,43 +0,0 @@
1
- require 'common'
2
- require 'net/ssh'
3
-
4
- module NetSSH
5
- class TestStartOptions < Test::Unit::TestCase
6
- def setup
7
- authentication_session = mock('authentication_session')
8
- authentication_session.stubs(:authenticate).returns(true)
9
- Net::SSH::Authentication::Session.stubs(:new).returns(authentication_session)
10
- Net::SSH::Transport::Session.stubs(:new).returns(mock('transport_session'))
11
- Net::SSH::Connection::Session.stubs(:new).returns(mock('connection_session'))
12
- end
13
-
14
- def test_start_should_accept_keepalive_option
15
- assert_nothing_raised do
16
- options = { :keepalive => true }
17
- Net::SSH.start('localhost', 'testuser', options)
18
- end
19
- end
20
-
21
- def test_start_should_accept_keepalive_interval_option
22
- assert_nothing_raised do
23
- options = { :keepalive_interval => 10 }
24
- Net::SSH.start('localhost', 'testuser', options)
25
- end
26
- end
27
-
28
- def test_start_should_accept_send_env_option
29
- assert_nothing_raised do
30
- options = { :send_env => [ /^LC_.*$/, "LANG" ] }
31
- Net::SSH.start('localhost', 'testuser', options)
32
- end
33
- end
34
-
35
- def test_star_should_accept_number_of_password_prompts_option
36
- assert_nothing_raised do
37
- options = { :number_of_password_prompts => 2 }
38
- Net::SSH.start('localhost', 'testuser', options)
39
- end
40
- end
41
- end
42
- end
43
-
@@ -1,28 +0,0 @@
1
- require 'common'
2
- require 'net/ssh'
3
-
4
- module NetSSH
5
- class TestStart < Test::Unit::TestCase
6
- attr_reader :transport_session
7
- attr_reader :authentication_session
8
-
9
- def setup
10
- @transport_session = mock('transport_session')
11
- @authentication_session = mock('authentication_session')
12
- Net::SSH::Transport::Session.expects(:new => transport_session)
13
- Net::SSH::Authentication::Session.expects(:new => authentication_session)
14
- end
15
-
16
- def test_close_transport_when_authentication_fails
17
- authentication_session.expects(:authenticate => false)
18
-
19
- transport_session.expects(:close).at_least_once
20
-
21
- begin
22
- Net::SSH.start('localhost', 'testuser') {}
23
- rescue Net::SSH::AuthenticationFailed
24
- # Authentication should fail, as it is part of the context
25
- end
26
- end
27
- end
28
- end
data/test/test_all.rb DELETED
@@ -1,11 +0,0 @@
1
- $: << '.'
2
-
3
- # $ ruby -Ilib -Itest -rrubygems test/test_all.rb
4
- # $ ruby -Ilib -Itest -rrubygems test/transport/test_server_version.rb
5
- Dir.chdir(File.dirname(__FILE__)) do
6
- test_files = Dir['**/test_*.rb']-['test_all.rb'] # prevent circular require
7
- test_files = test_files.reject { |f| f =~ /^manual/ }
8
- test_files = test_files.select { |f| f =~ Regexp.new(ENV['ONLY']) } if ENV['ONLY']
9
- test_files = test_files.reject { |f| f =~ Regexp.new(ENV['EXCEPT']) } if ENV['EXCEPT']
10
- test_files.each { |file| require(file) }
11
- end