net-ssh 3.0.1 → 3.0.2.rc1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 95e458a7ed58017d4658db4ac2b3126a0f09d43f
4
- data.tar.gz: 1840e7ee533d79e4a42bb2e42cd1c3d6e31da5f8
3
+ metadata.gz: 93524ab10733902b604b76acc36193d8bcf4ca1b
4
+ data.tar.gz: 88e5c681181e9011458adb039bc2853b4f31310b
5
5
  SHA512:
6
- metadata.gz: 1906d2443742af07de4b8dad4b7c3f85cde768f703f4e445f0cbd249311febd8e9e33d276b37d90af4119d702b6dc5d4a7b7cc3e9b581b63444dd87d7141732c
7
- data.tar.gz: edefc22e10946ea02716b0665c83f1d99ebc2db02f26c36f42dcc2e310dbb33052f749eb20f2726cbd361be007954d831f6740c37da8c43280472112ccdb2e3e
6
+ metadata.gz: afbd93ffc5d6ce03bdd1e4a311baf4b7341ab46d0048fe165c32ab7d6de403c6070ae9d5be78cd7ebbebf71d0dd03cc42ab2b2602f453c013cba92ece19c87db
7
+ data.tar.gz: 0a1f1f8cdd3abc441295acba9ff48b7149bd7625aa9d0fa53a505c62b697d87b8661ca02324047b2fbc348b02f5039bd0b9e8239413de708edfa6ae9c5e8228b
checksums.yaml.gz.sig CHANGED
@@ -1 +1 @@
1
- H��.�m18zmGq-�v"�Gn+�b�N���������B����޿�&�pZ�D�)f$[��Nܹ�#tւ�n�A�S�y���x�A��@5��b�g�ן�D�H��4�WT�`@��L~��]|�ە"�&>�P���E�y�H��Wشl{:�!�=W`��h�O��ixt����8�i#IG��էm�ރwW}�*�ق��[���BLI�g]t����=3 ��ۘ�yw��3D8��V���ru� �6��/V��
1
+ �?�.���$�?\��dË��(� �hQڛ���J�s&(/� W��C1AaWͩkEF��} �S�����������g)"��i7oI�ĩ�<JCY0?}��&qt"��_��+i1*`�I�ޞ�f9����ژ�X*�9��<�晚���.
data.tar.gz.sig CHANGED
Binary file
data/CHANGES.txt CHANGED
@@ -1,3 +1,7 @@
1
+ * fixed rare WaitWritable error with proxy commands [Miklos Fazkas, Andre Meij]]
2
+ * if Net::SSH.start user is nil and config has no entry we default to Etc.getlogin
3
+ * Bugfix: CHANNEL_CLOSE was sent before draining ouput buffer #280 [Christopher F. Auston]
4
+
1
5
  === 3.0.1
2
6
  === 3.0.1.rc1
3
7
 
data/README.rdoc CHANGED
@@ -1,4 +1,4 @@
1
- = Net::SSH 2.x
1
+ = Net::SSH 3.x
2
2
 
3
3
  <em><b>Please note: this project is in maintenance mode. It is not under active development but pull requests are very much welcome. Just be sure to include tests! -- delano</b></em>
4
4
 
data/Rakefile CHANGED
@@ -74,7 +74,11 @@ end
74
74
 
75
75
  require 'rake/testtask'
76
76
  Rake::TestTask.new do |t|
77
- t.libs = ["lib", "test"]
77
+ if ENV['NET_SSH_RUN_INTEGRATION_TESTS']
78
+ t.libs = ["lib","test","test/integration"]
79
+ else
80
+ t.libs = ["lib", "test"]
81
+ end
78
82
  end
79
83
 
80
84
  Rake::TestTask.new(:'integration-test') do |t|
data/lib/net/ssh.rb CHANGED
@@ -188,7 +188,10 @@ module Net
188
188
  # password auth method
189
189
  # * :non_interactive => non interactive applications should set it to true
190
190
  # to prefer failing a password/etc auth methods vs asking for password
191
- def self.start(host, user, options={}, &block)
191
+ #
192
+ # If +user+ parameter is nil it defaults to USER from ssh_config, or
193
+ # local username
194
+ def self.start(host, user=nil, options={}, &block)
192
195
  invalid_options = options.keys - VALID_OPTIONS
193
196
  if invalid_options.any?
194
197
  raise ArgumentError, "invalid option(s): #{invalid_options.join(', ')}"
@@ -222,7 +225,7 @@ module Net
222
225
  transport = Transport::Session.new(host, options)
223
226
  auth = Authentication::Session.new(transport, options)
224
227
 
225
- user = options.fetch(:user, user)
228
+ user = options.fetch(:user, user) || Etc.getlogin
226
229
  if auth.authenticate("ssh-connection", user, options[:password])
227
230
  connection = Connection::Session.new(transport, options)
228
231
  if block_given?
@@ -232,16 +232,13 @@ module Net
232
232
  identity
233
233
  end
234
234
 
235
- rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError => e
235
+ rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError, ArgumentError => e
236
236
  if ignore_decryption_errors
237
237
  identity
238
238
  else
239
239
  process_identity_loading_error(identity, e)
240
240
  nil
241
241
  end
242
- rescue ArgumentError => e
243
- process_identity_loading_error(identity, e)
244
- nil
245
242
  rescue Exception => e
246
243
  process_identity_loading_error(identity, e)
247
244
  nil
@@ -126,7 +126,7 @@ module Net; module SSH; module Connection
126
126
  @pending_requests = []
127
127
  @on_open_failed = @on_data = @on_extended_data = @on_process = @on_close = @on_eof = nil
128
128
  @on_request = {}
129
- @closing = @eof = @sent_eof = false
129
+ @closing = @eof = @sent_eof = @local_closed = @remote_closed = false
130
130
  end
131
131
 
132
132
  # A shortcut for accessing properties of the channel (see #properties).
@@ -269,14 +269,28 @@ module Net; module SSH; module Connection
269
269
  connection.loop { active? }
270
270
  end
271
271
 
272
- # Returns true if the channel is currently closing, but not actually
273
- # closed. A channel is closing when, for instance, #close has been
274
- # invoked, but the server has not yet responded with a CHANNEL_CLOSE
275
- # packet of its own.
272
+ # True if close() has been called; NOTE: if the channel has data waiting to
273
+ # be sent then the channel will close after all the data is sent. See
274
+ # closed?() to determine if we have actually sent CHANNEL_CLOSE to server.
275
+ # This may be true for awhile before closed? returns true if we are still
276
+ # sending buffered output to server.
276
277
  def closing?
277
278
  @closing
278
279
  end
279
280
 
281
+ # True if we have sent CHANNEL_CLOSE to the remote server.
282
+ def local_closed?
283
+ @local_closed
284
+ end
285
+
286
+ def remote_closed?
287
+ @remote_closed
288
+ end
289
+
290
+ def remote_closed!
291
+ @remote_closed = true
292
+ end
293
+
280
294
  # Requests that the channel be closed. If the channel is already closing,
281
295
  # this does nothing, nor does it do anything if the channel has not yet
282
296
  # been confirmed open (see #do_open_confirmation). Otherwise, it sends a
@@ -285,7 +299,6 @@ module Net; module SSH; module Connection
285
299
  return if @closing
286
300
  if remote_id
287
301
  @closing = true
288
- connection.send_message(Buffer.from(:byte, CHANNEL_CLOSE, :long, remote_id))
289
302
  end
290
303
  end
291
304
 
@@ -311,10 +324,16 @@ module Net; module SSH; module Connection
311
324
  @on_process.call(self) if @on_process
312
325
  enqueue_pending_output
313
326
 
314
- if @eof and not @sent_eof and output.empty? and remote_id
327
+ if @eof and not @sent_eof and output.empty? and remote_id and not @local_closed
315
328
  connection.send_message(Buffer.from(:byte, CHANNEL_EOF, :long, remote_id))
316
329
  @sent_eof = true
317
330
  end
331
+
332
+ if @closing and not @local_closed and output.empty? and remote_id
333
+ connection.send_message(Buffer.from(:byte, CHANNEL_CLOSE, :long, remote_id))
334
+ @local_closed = true
335
+ connection.cleanup_channel(self)
336
+ end
318
337
  end
319
338
 
320
339
  # Registers a callback to be invoked when data packets are received by the
@@ -220,7 +220,7 @@ module Net; module SSH; module Connection
220
220
  def preprocess
221
221
  return false if block_given? && !yield(self)
222
222
  dispatch_incoming_packets
223
- channels.each { |id, channel| channel.process unless channel.closing? }
223
+ channels.each { |id, channel| channel.process unless channel.local_closed? }
224
224
  return false if block_given? && !yield(self)
225
225
  return true
226
226
  end
@@ -455,6 +455,14 @@ module Net; module SSH; module Connection
455
455
  old
456
456
  end
457
457
 
458
+ def cleanup_channel(channel)
459
+ if channel.local_closed? and channel.remote_closed?
460
+ info { "#{host} delete channel #{channel.local_id} which closed locally and remotely" }
461
+ channels.delete(channel.local_id)
462
+ end
463
+ end
464
+
465
+
458
466
  private
459
467
 
460
468
  # Read all pending packets from the connection and dispatch them as
@@ -583,9 +591,10 @@ module Net; module SSH; module Connection
583
591
  info { "channel_close: #{packet[:local_id]}" }
584
592
 
585
593
  channel = channels[packet[:local_id]]
594
+ channel.remote_closed!
586
595
  channel.close
587
596
 
588
- channels.delete(packet[:local_id])
597
+ cleanup_channel(channel)
589
598
  channel.do_close
590
599
  end
591
600
 
@@ -79,11 +79,26 @@ module Net; module SSH; module Proxy
79
79
  end
80
80
  else
81
81
  def io.send(data, flag)
82
- write_nonblock(data)
82
+ begin
83
+ result = write_nonblock(data)
84
+ rescue IO::WaitWritable, Errno::EINTR
85
+ IO.select(nil, [self])
86
+ retry
87
+ end
88
+ result
83
89
  end
84
90
 
85
91
  def io.recv(size)
86
- read_nonblock(size)
92
+ begin
93
+ result = read_nonblock(size)
94
+ rescue IO::WaitReadable, Errno::EINTR
95
+ timeout_in_seconds = 20
96
+ if IO.select([self], nil, [self], timeout_in_seconds) == nil
97
+ raise "Unexpected spurious read wakeup"
98
+ end
99
+ retry
100
+ end
101
+ result
87
102
  end
88
103
  end
89
104
  io
@@ -51,11 +51,11 @@ module Net; module SSH
51
51
  MINOR = 0
52
52
 
53
53
  # The tiny component of this version of the Net::SSH library
54
- TINY = 1
54
+ TINY = 2
55
55
 
56
56
  # The prerelease component of this version of the Net::SSH library
57
57
  # nil allowed
58
- PRE = nil
58
+ PRE = "rc1"
59
59
 
60
60
  # The current version of the Net::SSH library as a Version instance
61
61
  CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
@@ -1,20 +1,20 @@
1
1
  -----BEGIN CERTIFICATE-----
2
2
  MIIDODCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBCMRAwDgYDVQQDDAduZXQt
3
3
  c3NoMRkwFwYKCZImiZPyLGQBGRYJc29sdXRpb3VzMRMwEQYKCZImiZPyLGQBGRYD
4
- Y29tMB4XDTE0MTIwMjE3MzkyMFoXDTE1MTIwMjE3MzkyMFowQjEQMA4GA1UEAwwH
4
+ Y29tMB4XDTE1MTIwNjIxMDYyNFoXDTE2MTIwNTIxMDYyNFowQjEQMA4GA1UEAwwH
5
5
  bmV0LXNzaDEZMBcGCgmSJomT8ixkARkWCXNvbHV0aW91czETMBEGCgmSJomT8ixk
6
- ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0qnw4JV5JN
7
- MWelqu7pnW2z6GZJ7+zLFYJQNETJyF0U5zo7aCRK08OeUxnpu/TCCXK8iQVkNLfz
8
- 9pVIhF+X8pMEIruAkYGwBt1aWfuSNeyodyMk0vpZdxBHbOTJ4qBRUc6qOtNOeOzv
9
- 8ObYUX52P/EMMaeXTRU+e7MGkB9pb6FvPPNx5akxwIaoRvtcMsc/hJnQuP5r96w6
10
- t06MgKbXhWAX6gev0RVlrQqzxXst6iuvsrgZGjFqzob5wbTiX9M0+bFAB0EI7tJC
11
- sv5keEbtNRaU7p3ZbMm4wTHHJLOtD+BpUCSzwv4ToNj9mZtJBMYw2Eeo7z1DklEG
12
- mr95zbe+zNMCAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQU1bTfpzmitXwv
13
- LmTXi0IO5vd8NGYwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQA0Aps8
14
- UPINGa8XUUtrZtzrgX0/iyXNkKY1ld85g1N3WKEAVLfQI7TlGr0Qv2Ekx6RqlxbR
15
- Vyq08pytSnghW2otR3bIGMGQzqxAeRLb25cjEwH7YIJ32n7ZC1fpMnBZOBDmueWA
16
- B9EonmoO3ne7AJSgIvBbZzBPhzM4HrQGRW8LsPFsuj+dcJI43HOQwkmv2TRz0+t6
17
- mGZldmqLcK0abv4JepLfB9XTue3kuyA29NGBibqyvRwlKckLpvKfHZX6Jxad8xxm
18
- MbvRpzgROzyfw1qYi4dnIyMwTtXFFcZ0a2jpxHPkcTYFK6TzvFgDLAP0Y/u9jqUQ
19
- eZ7/3CdSi/isZHEw
6
+ ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMYnhNtn0f6p
7
+ nTylB8mE8lMdoMLJC8KwpMWsvk73Pe2WVDsH/OSwwwz6oUGk1i70cJyDjIEBNpwT
8
+ 88GpVXJSumvqVsf9fCg3mWNeb5t0J+aeNm9MIvYVMTqj5tydoXQiwnILRDYHV9tZ
9
+ 1c3o59/VlahSTpZ7YEgzVufpAkvEGkbJiG849exiipK7MN/ZIkMOxYVnyRXk43Xc
10
+ 6GYlsHOfSgPwcXwW5g57DCwLQLWrjDsTka28dxDmO7B5Lv5EqzINxVxWsu43OgZG
11
+ 21Io/jIyf5PNpeKPKNGDuAQJ8mvdMYBJoDhtCwgsUYbl0BZzA7g4ytl51HtIeP+j
12
+ Qp/eAvs/RrECAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUBfKiwO2eM4NE
13
+ iRrVG793qEPLYyMwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQCfZFdb
14
+ p4jzkfIzGDbiOxd0R8sdqJoC4nMLEgnQ7dLulawwA3IXe3sHAKgA5kmH3prsKc5H
15
+ zVmM5NlH2P1nRbegIkQTYiIod1hZQCNxdmVG/fprMqPq0ybpUOjjrP5pj0OtszE1
16
+ F2dQia1hOEstMR+n0nAtWII9HJAEyeZjVV0s2Cl7Pt85XJ3hxFcCKwzqsK5xRI7a
17
+ B3vwh3/JJYrFonIohQ//Lg9qTZASEkoKLlq1/hFeICoCGGIGLq45ZB7CzXLooCKi
18
+ s/ZUKye79ELwFYKJOhjW5g725OL3hy+llhEleytwKRwgXFQBPTC4f5UkdxZVVWGH
19
+ e2C9M1m/2odPZo8h
20
20
  -----END CERTIFICATE-----
data/net-ssh.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: net-ssh 3.0.1 ruby lib
5
+ # stub: net-ssh 3.0.2.rc1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "net-ssh"
9
- s.version = "3.0.1"
9
+ s.version = "3.0.2.rc1"
10
10
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Jamis Buck", "Delano Mandelbaum", "Mikl\u{f3}s Fazekas"]
14
14
  s.cert_chain = ["net-ssh-public_cert.pem"]
15
- s.date = "2015-09-25"
15
+ s.date = "2015-12-10"
16
16
  s.description = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol. It allows you to write programs that invoke and interact with processes on remote servers, via SSH2."
17
17
  s.email = "net-ssh@solutious.com"
18
18
  s.extra_rdoc_files = [
@@ -144,14 +144,16 @@ Gem::Specification.new do |s|
144
144
  "test/integration/Vagrantfile",
145
145
  "test/integration/common.rb",
146
146
  "test/integration/playbook.yml",
147
+ "test/integration/test_forward.rb",
147
148
  "test/integration/test_id_rsa_keys.rb",
149
+ "test/integration/test_proxy.rb",
148
150
  "test/known_hosts/github",
149
151
  "test/known_hosts/github_hash",
150
- "test/manual/test_forward.rb",
151
152
  "test/manual/test_pageant.rb",
152
153
  "test/start/test_connection.rb",
153
154
  "test/start/test_options.rb",
154
155
  "test/start/test_transport.rb",
156
+ "test/start/test_user_nil.rb",
155
157
  "test/test_all.rb",
156
158
  "test/test_buffer.rb",
157
159
  "test/test_buffered_io.rb",
data/test/README.txt CHANGED
@@ -16,25 +16,3 @@ INTEGRATION TESTS
16
16
 
17
17
  brew install ansible ; ansible-galaxy install rvm_io.rvm1-ruby ; vagrant up ; vagrant ssh
18
18
  cd /net-ssh ; rake integration-test
19
-
20
- PORT FORWARDING TESTS
21
-
22
- ruby -Ilib -Itest -rrubygems test/manual/test_forward.rb
23
-
24
- test_forward.rb must be run separately from the test suite because
25
- it requires authorizing your public SSH keys on you localhost.
26
-
27
- If you already have keys you can do this:
28
-
29
- cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
30
-
31
- If you don't have keys see:
32
-
33
- http://kimmo.suominen.com/docs/ssh/#ssh-keygen
34
-
35
- You should now be able to login to your localhost with out
36
- bring prompted for a password:
37
-
38
- ssh localhost
39
-
40
- -Delano
@@ -74,8 +74,11 @@ module Connection
74
74
  assert !channel.closing?
75
75
 
76
76
  connection.expect { |t,packet| assert_equal CHANNEL_CLOSE, packet.type }
77
+ connection.expects(:cleanup_channel).with(channel)
77
78
  channel.close
78
79
 
80
+ channel.process
81
+
79
82
  assert channel.closing?
80
83
  end
81
84
 
@@ -117,14 +117,14 @@ module Connection
117
117
  end
118
118
 
119
119
  def test_process_should_exit_after_processing_if_block_is_true_then_false
120
- session.channels[0] = stub("channel", :closing? => false)
120
+ session.channels[0] = stub("channel", :local_closed? => false)
121
121
  session.channels[0].expects(:process)
122
122
  IO.expects(:select).never
123
123
  process_times(2)
124
124
  end
125
125
 
126
126
  def test_process_should_not_process_channels_that_are_closing
127
- session.channels[0] = stub("channel", :closing? => true)
127
+ session.channels[0] = stub("channel", :local_closed? => true)
128
128
  session.channels[0].expects(:process).never
129
129
  IO.expects(:select).never
130
130
  process_times(2)
@@ -299,8 +299,17 @@ module Connection
299
299
  end
300
300
 
301
301
  def test_channel_close_packet_should_be_routed_to_corresponding_channel_and_channel_should_be_closed_and_removed
302
- channel_at(14).expects(:do_close).with()
303
- session.channels[14].expects(:close).with()
302
+ session.channels[14] = stub("channel") do
303
+ # this simulates the case where we closed the channel first, sent
304
+ # CHANNEL_CLOSE to server and are waiting for server's response.
305
+ expects(:local_closed?).returns(true)
306
+ expects(:do_close)
307
+ expects(:close).with()
308
+ expects(:remote_closed!).with()
309
+ expects(:remote_closed?).with().returns(true)
310
+ expects(:local_id).returns(14)
311
+ end
312
+
304
313
  transport.return(CHANNEL_CLOSE, :long, 14)
305
314
  process_times(2)
306
315
  assert session.channels.empty?
@@ -526,7 +535,7 @@ module Connection
526
535
  end
527
536
 
528
537
  def channel_at(local_id)
529
- session.channels[local_id] = stub("channel", :process => true, :closing? => false)
538
+ session.channels[local_id] = stub("channel", :process => true, :local_closed? => false)
530
539
  end
531
540
 
532
541
  def transport(options={})
@@ -8,10 +8,8 @@ Requirements:
8
8
  Setup:
9
9
 
10
10
  ansible-galaxy install rvm_io.rvm1-ruby
11
- vagrant up
12
- vagrant ssh
13
- cd /net-ssh
14
- rake integration-test
11
+ vagrant up ; vagrant ssh
12
+ rake test
15
13
 
16
14
  # TODO
17
15
 
@@ -14,6 +14,12 @@ module IntegrationTestHelpers
14
14
  raise "Command: #{command} failed:#{status.exitstatus}" unless res
15
15
  end
16
16
 
17
+ def tmpdir(&block)
18
+ Dir.mktmpdir do |dir|
19
+ yield(dir)
20
+ end
21
+ end
22
+
17
23
  def set_authorized_key(user,pubkey)
18
24
  authorized_key = "/home/#{user}/.ssh/authorized_keys"
19
25
  sh "sudo cp #{pubkey} #{authorized_key}"
@@ -34,6 +34,14 @@
34
34
  - name: sshd debug
35
35
  lineinfile: dest='/etc/ssh/sshd_config' line='LogLevel DEBUG' regexp=LogLevel
36
36
  notify: restart sshd
37
+ - name: put NET_SSH_RUN_INTEGRATION_TESTS=YES environment
38
+ lineinfile: dest='/etc/environment' line='NET_SSH_RUN_INTEGRATION_TESTS=YES'
39
+ - name: change dir in bashrc
40
+ lineinfile: dest=/home/vagrant/.bashrc owner=vagrant mode=0644
41
+ regexp='^cd ' line='cd /net-ssh'
42
+ - apt: name="{{item}}" state=present
43
+ with_items:
44
+ - pv
37
45
  - gem: name="{{item}}" state=present executable=/usr/local/rvm/rubies/ruby-{{ruby_version}}/bin/gem
38
46
  with_items:
39
47
  - byebug