net-ssh 2.9.2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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