net-ssh 3.0.1 → 3.0.2.rc1

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