net-ssh 2.9.1 → 2.9.2.beta

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.
@@ -42,14 +42,12 @@ module Net; module SSH; module Transport
42
42
  camellia192-ctr@openssh.org
43
43
  camellia256-ctr@openssh.org
44
44
  cast128-ctr blowfish-ctr 3des-ctr
45
- aes256-gcm@openssh.com aes128-gcm@openssh.com
46
45
  ),
46
+
47
47
  :hmac => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96
48
48
  hmac-ripemd160 hmac-ripemd160@openssh.com
49
49
  hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96
50
- hmac-sha2-512-96 none
51
- hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com
52
- umac-128-etm@openssh.com),
50
+ hmac-sha2-512-96 none),
53
51
 
54
52
  :compression => %w(none zlib@openssh.com zlib),
55
53
  :language => %w()
@@ -57,9 +55,7 @@ module Net; module SSH; module Transport
57
55
  if defined?(OpenSSL::PKey::EC)
58
56
  ALGORITHMS[:host_key] += %w(ecdsa-sha2-nistp256
59
57
  ecdsa-sha2-nistp384
60
- ecdsa-sha2-nistp521
61
- ssh-ed25519-cert-v01@openssh.com
62
- ssh-ed25519)
58
+ ecdsa-sha2-nistp521)
63
59
  ALGORITHMS[:kex] += %w(ecdh-sha2-nistp256
64
60
  ecdh-sha2-nistp384
65
61
  ecdh-sha2-nistp521
@@ -221,8 +217,13 @@ module Net; module SSH; module Transport
221
217
  # apply the preferred algorithm order, if any
222
218
  if options[algorithm]
223
219
  algorithms[algorithm] = Array(options[algorithm]).compact.uniq
224
- invalid = algorithms[algorithm].detect { |name| !ALGORITHMS[algorithm].include?(name) }
225
- raise NotImplementedError, "unsupported #{algorithm} algorithm: `#{invalid}'" if invalid
220
+ unsupported = []
221
+ algorithms[algorithm].select! do |name|
222
+ supported = ALGORITHMS[algorithm].include?(name)
223
+ unsupported << name unless supported
224
+ supported
225
+ end
226
+ lwarn { "unsupported #{algorithm} algorithm: `#{unsupported}'" } unless unsupported.empty?
226
227
 
227
228
  # make sure all of our supported algorithms are tacked onto the
228
229
  # end, so that if the user tries to give a list of which none are
@@ -41,9 +41,6 @@ module Net; module SSH; module Transport
41
41
  "camellia192-ctr@openssh.org" => "camellia-192-ecb",
42
42
  "camellia256-ctr@openssh.org" => "camellia-256-ecb",
43
43
 
44
- "aes256-gcm@openssh.com" => "aes-256-gcm",
45
- "aes128-gcm@openssh.com" => "aes-128-gcm",
46
-
47
44
  "none" => "none",
48
45
  }
49
46
 
@@ -14,6 +14,8 @@ module Net; module SSH; module Transport
14
14
  # per the SSH2 protocol. It also adds an abstraction for polling packets,
15
15
  # to allow for both blocking and non-blocking reads.
16
16
  module PacketStream
17
+ PROXY_COMMAND_HOST_IP = '<no hostip for proxy command>'.freeze
18
+
17
19
  include BufferedIo
18
20
 
19
21
  def self.extended(object)
@@ -64,7 +66,7 @@ module Net; module SSH; module Transport
64
66
  addr = getpeername
65
67
  Socket.getnameinfo(addr, Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV).first
66
68
  else
67
- "<no hostip for proxy command>"
69
+ PROXY_COMMAND_HOST_IP
68
70
  end
69
71
  end
70
72
 
@@ -93,11 +93,16 @@ module Net; module SSH; module Transport
93
93
  @host_as_string ||= begin
94
94
  string = "#{host}"
95
95
  string = "[#{string}]:#{port}" if port != DEFAULT_PORT
96
- if socket.peer_ip != host
97
- string2 = socket.peer_ip
96
+
97
+ peer_ip = socket.peer_ip
98
+
99
+ if peer_ip != Net::SSH::Transport::PacketStream::PROXY_COMMAND_HOST_IP &&
100
+ peer_ip != host
101
+ string2 = peer_ip
98
102
  string2 = "[#{string2}]:#{port}" if port != DEFAULT_PORT
99
103
  string << "," << string2
100
104
  end
105
+
101
106
  string
102
107
  end
103
108
  end
@@ -16,15 +16,15 @@ module Net; module SSH
16
16
 
17
17
  # A convenience method for instantiating a new Version instance with the
18
18
  # given +major+, +minor+, and +tiny+ components.
19
- def self.[](major, minor, tiny)
20
- new(major, minor, tiny)
19
+ def self.[](major, minor, tiny, pre = nil)
20
+ new(major, minor, tiny, pre)
21
21
  end
22
22
 
23
23
  attr_reader :major, :minor, :tiny
24
24
 
25
25
  # Create a new Version object with the given components.
26
- def initialize(major, minor, tiny)
27
- @major, @minor, @tiny = major, minor, tiny
26
+ def initialize(major, minor, tiny, pre = nil)
27
+ @major, @minor, @tiny, @pre = major, minor, tiny, pre
28
28
  end
29
29
 
30
30
  # Compare this version to the given +version+ object.
@@ -35,7 +35,7 @@ module Net; module SSH
35
35
  # Converts this version object to a string, where each of the three
36
36
  # version components are joined by the '.' character. E.g., 2.0.0.
37
37
  def to_s
38
- @to_s ||= [@major, @minor, @tiny].join(".")
38
+ @to_s ||= [@major, @minor, @tiny, @pre].compact.join(".")
39
39
  end
40
40
 
41
41
  # Converts this version to a canonical integer that may be compared
@@ -51,10 +51,14 @@ module Net; module SSH
51
51
  MINOR = 9
52
52
 
53
53
  # The tiny component of this version of the Net::SSH library
54
- TINY = 1
54
+ TINY = 2
55
+
56
+ # The prerelease component of this version of the Net::SSH library
57
+ # nil allowed
58
+ PRE = "beta"
55
59
 
56
60
  # The current version of the Net::SSH library as a Version instance
57
- CURRENT = new(MAJOR, MINOR, TINY)
61
+ CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
58
62
 
59
63
  # The current version of the Net::SSH library as a String
60
64
  STRING = CURRENT.to_s
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDODCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBCMRAwDgYDVQQDDAduZXQt
3
+ c3NoMRkwFwYKCZImiZPyLGQBGRYJc29sdXRpb3VzMRMwEQYKCZImiZPyLGQBGRYD
4
+ Y29tMB4XDTE0MTIwMjE3MzkyMFoXDTE1MTIwMjE3MzkyMFowQjEQMA4GA1UEAwwH
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
20
+ -----END CERTIFICATE-----
data/net-ssh.gemspec CHANGED
@@ -2,15 +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 2.9.2.beta ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "net-ssh"
8
- s.version = "2.9.1"
9
+ s.version = "2.9.2.beta"
9
10
 
10
- 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
+ s.require_paths = ["lib"]
11
13
  s.authors = ["Jamis Buck", "Delano Mandelbaum"]
12
- s.cert_chain = ["gem-public_cert.pem"]
13
- s.date = "2014-05-13"
14
+ s.cert_chain = ["net-ssh-public_cert.pem"]
15
+ s.date = "2014-12-02"
14
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."
15
17
  s.email = "net-ssh@solutious.com"
16
18
  s.extra_rdoc_files = [
@@ -26,7 +28,6 @@ Gem::Specification.new do |s|
26
28
  "Rakefile",
27
29
  "Rudyfile",
28
30
  "THANKS.txt",
29
- "gem-public_cert.pem",
30
31
  "lib/net/ssh.rb",
31
32
  "lib/net/ssh/authentication/agent.rb",
32
33
  "lib/net/ssh/authentication/agent/java_pageant.rb",
@@ -46,6 +47,7 @@ Gem::Specification.new do |s|
46
47
  "lib/net/ssh/config.rb",
47
48
  "lib/net/ssh/connection/channel.rb",
48
49
  "lib/net/ssh/connection/constants.rb",
50
+ "lib/net/ssh/connection/keepalive.rb",
49
51
  "lib/net/ssh/connection/session.rb",
50
52
  "lib/net/ssh/connection/term.rb",
51
53
  "lib/net/ssh/errors.rb",
@@ -106,6 +108,7 @@ Gem::Specification.new do |s|
106
108
  "lib/net/ssh/verifiers/secure.rb",
107
109
  "lib/net/ssh/verifiers/strict.rb",
108
110
  "lib/net/ssh/version.rb",
111
+ "net-ssh-public_cert.pem",
109
112
  "net-ssh.gemspec",
110
113
  "setup.rb",
111
114
  "support/arcfour_check.rb",
@@ -177,14 +180,13 @@ Gem::Specification.new do |s|
177
180
  ]
178
181
  s.homepage = "https://github.com/net-ssh/net-ssh"
179
182
  s.licenses = ["MIT"]
180
- s.require_paths = ["lib"]
181
183
  s.rubyforge_project = "net-ssh"
182
- s.rubygems_version = "1.8.23"
183
- s.signing_key = "/mnt/gem/gem-private_key.pem"
184
+ s.rubygems_version = "2.2.2"
185
+ s.signing_key = "/mnt/gem/net-ssh-private_key.pem"
184
186
  s.summary = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
185
187
 
186
188
  if s.respond_to? :specification_version then
187
- s.specification_version = 3
189
+ s.specification_version = 4
188
190
 
189
191
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
190
192
  s.add_development_dependency(%q<test-unit>, [">= 0"])
@@ -1,7 +1,9 @@
1
1
  require 'common'
2
2
  require 'net/ssh/authentication/methods/password'
3
+ require 'net/ssh/authentication/session'
3
4
  require 'authentication/methods/common'
4
5
 
6
+
5
7
  module Authentication; module Methods
6
8
 
7
9
  class TestPassword < Test::Unit::TestCase
@@ -24,6 +26,47 @@ module Authentication; module Methods
24
26
  end
25
27
  end
26
28
 
29
+ def test_authenticate_ask_for_password_for_second_time_when_password_is_incorrect
30
+ transport.expect do |t,packet|
31
+ assert_equal USERAUTH_REQUEST, packet.type
32
+ assert_equal "jamis", packet.read_string
33
+ assert_equal "ssh-connection", packet.read_string
34
+ assert_equal "password", packet.read_string
35
+ assert_equal false, packet.read_bool
36
+ assert_equal "the-password", packet.read_string
37
+ t.return(USERAUTH_FAILURE, :string, "publickey,password")
38
+
39
+ t.expect do |t2, packet2|
40
+ assert_equal USERAUTH_REQUEST, packet2.type
41
+ assert_equal "jamis", packet2.read_string
42
+ assert_equal "ssh-connection", packet2.read_string
43
+ assert_equal "password", packet2.read_string
44
+ assert_equal false, packet2.read_bool
45
+ assert_equal "the-password-2", packet2.read_string
46
+ t.return(USERAUTH_SUCCESS)
47
+ end
48
+ end
49
+
50
+ subject.expects(:prompt).with("jamis@'s password:", false).returns("the-password-2")
51
+ subject.authenticate("ssh-connection", "jamis", "the-password")
52
+ end
53
+
54
+ def test_authenticate_ask_for_password_if_not_given
55
+ transport.expect do |t,packet|
56
+ assert_equal USERAUTH_REQUEST, packet.type
57
+ assert_equal "bill", packet.read_string
58
+ assert_equal "ssh-connection", packet.read_string
59
+ assert_equal "password", packet.read_string
60
+ assert_equal false, packet.read_bool
61
+ assert_equal "good-password", packet.read_string
62
+ t.return(USERAUTH_SUCCESS)
63
+ end
64
+
65
+ transport.instance_eval { @host='testhost' }
66
+ subject.expects(:prompt).with("bill@testhost's password:", false).returns("good-password")
67
+ subject.authenticate("ssh-connection", "bill", nil)
68
+ end
69
+
27
70
  def test_authenticate_when_password_is_acceptible_should_return_true
28
71
  transport.expect do |t,packet|
29
72
  assert_equal USERAUTH_REQUEST, packet.type
@@ -110,6 +110,25 @@ module Authentication
110
110
  assert_equal "Okay, but not the best", result.last.comment
111
111
  end
112
112
 
113
+ def test_identities_should_ignore_unimplemented_ones
114
+ key1 = key
115
+ key2 = OpenSSL::PKey::DSA.new(512)
116
+ key2.to_blob[0..5]='badkey'
117
+ key3 = OpenSSL::PKey::DSA.new(512)
118
+
119
+ socket.expect do |s, type, buffer|
120
+ assert_equal SSH2_AGENT_REQUEST_IDENTITIES, type
121
+ s.return(SSH2_AGENT_IDENTITIES_ANSWER, :long, 3, :string, Net::SSH::Buffer.from(:key, key1), :string, "My favorite key", :string, Net::SSH::Buffer.from(:key, key2), :string, "bad", :string, Net::SSH::Buffer.from(:key, key3), :string, "Okay, but not the best")
122
+ end
123
+
124
+ result = agent.identities
125
+ assert_equal 2,result.size
126
+ assert_equal key1.to_blob, result.first.to_blob
127
+ assert_equal key3.to_blob, result.last.to_blob
128
+ assert_equal "My favorite key", result.first.comment
129
+ assert_equal "Okay, but not the best", result.last.comment
130
+ end
131
+
113
132
  def test_close_should_close_socket
114
133
  socket.expects(:close)
115
134
  agent.close
@@ -366,12 +366,29 @@ module Connection
366
366
  def test_process_should_call_enqueue_message_if_io_select_timed_out
367
367
  timeout = Net::SSH::Connection::Session::DEFAULT_IO_SELECT_TIMEOUT
368
368
  options = { :keepalive => true }
369
- expected_packet = P(:byte, Net::SSH::Packet::IGNORE, :string, "keepalive")
369
+ expected_packet = P(:byte, Net::SSH::Packet::GLOBAL_REQUEST, :string, "keepalive@openssh.com", :bool, true)
370
370
  IO.stubs(:select).with([socket],[],nil,timeout).returns(nil)
371
- transport.expects(:enqueue_message).with{ |msg| msg.content == expected_packet.content }
371
+ transport.expects(:enqueue_message).with{ |msg| msg.content == expected_packet.content }
372
372
  session(options).process
373
373
  end
374
374
 
375
+ def test_process_should_raise_if_keepalives_not_answered
376
+ timeout = Net::SSH::Connection::Session::DEFAULT_IO_SELECT_TIMEOUT
377
+ options = { :keepalive => true, :keepalive_interval => 300, :keepalive_maxcount => 3 }
378
+ expected_packet = P(:byte, Net::SSH::Packet::GLOBAL_REQUEST, :string, "keepalive@openssh.com", :bool, true)
379
+ [1,2,3].each do |i|
380
+ Time.stubs(:now).returns(i*300)
381
+ IO.stubs(:select).with([socket],[],nil,timeout).returns(nil)
382
+ transport.expects(:enqueue_message).with{ |msg| msg.content == expected_packet.content }
383
+ session(options).process
384
+ end
385
+
386
+ Time.stubs(:now).returns(4*300)
387
+ IO.stubs(:select).with([socket],[],nil,timeout).returns(nil)
388
+ transport.expects(:enqueue_message).with{ |msg| msg.content == expected_packet.content }
389
+ assert_raises(Net::SSH::Timeout) { session(options).process }
390
+ end
391
+
375
392
  def test_process_should_not_call_enqueue_message_unless_io_select_timed_out
376
393
  timeout = Net::SSH::Connection::Session::DEFAULT_IO_SELECT_TIMEOUT
377
394
  options = { :keepalive => true }
@@ -3,15 +3,15 @@
3
3
  # Tests for the following patch:
4
4
  #
5
5
  # http://github.com/net-ssh/net-ssh/tree/portfwfix
6
- #
6
+ #
7
7
  # It fixes 3 issues, regarding closing forwarded ports:
8
- #
8
+ #
9
9
  # 1.) if client closes a forwarded connection, but the server is reading, net-ssh terminates with IOError socket closed.
10
10
  # 2.) if client force closes (RST) a forwarded connection, but server is reading, net-ssh terminates with
11
11
  # 3.) if server closes the sending side, the on_eof is not handled.
12
- #
12
+ #
13
13
  # More info:
14
- #
14
+ #
15
15
  # http://net-ssh.lighthouseapp.com/projects/36253/tickets/7
16
16
 
17
17
  require 'common'
@@ -21,26 +21,26 @@ require 'timeout'
21
21
  require 'tempfile'
22
22
 
23
23
  class TestForward < Test::Unit::TestCase
24
-
24
+
25
25
  def localhost
26
26
  'localhost'
27
27
  end
28
-
28
+
29
29
  def ssh_start_params
30
30
  [localhost ,ENV['USER'], {:keys => "~/.ssh/id_rsa", :verbose => :debug}]
31
31
  end
32
-
32
+
33
33
  def start_server_sending_lot_of_data(exceptions)
34
34
  server = TCPServer.open(0)
35
35
  Thread.start do
36
36
  loop do
37
37
  Thread.start(server.accept) do |client|
38
38
  begin
39
- 10000.times do |i|
39
+ 10000.times do |i|
40
40
  client.puts "item#{i}"
41
41
  end
42
42
  client.close
43
- rescue
43
+ rescue
44
44
  exceptions << $!
45
45
  raise
46
46
  end
@@ -49,14 +49,14 @@ class TestForward < Test::Unit::TestCase
49
49
  end
50
50
  return server
51
51
  end
52
-
52
+
53
53
  def start_server_closing_soon(exceptions=nil)
54
54
  server = TCPServer.open(0)
55
55
  Thread.start do
56
56
  loop do
57
57
  Thread.start(server.accept) do |client|
58
58
  begin
59
- client.recv(1024)
59
+ client.recv(1024)
60
60
  client.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, [1, 0].pack("ii"))
61
61
  client.close
62
62
  rescue
@@ -68,20 +68,20 @@ class TestForward < Test::Unit::TestCase
68
68
  end
69
69
  return server
70
70
  end
71
-
71
+
72
72
  def test_local_ephemeral_port_should_work_correctly
73
73
  session = Net::SSH.start(*ssh_start_params)
74
-
74
+
75
75
  assert_nothing_raised do
76
76
  assigned_port = session.forward.local(0, localhost, 22)
77
77
  assert_not_nil assigned_port
78
78
  assert_operator assigned_port, :>, 0
79
79
  end
80
80
  end
81
-
81
+
82
82
  def test_remote_ephemeral_port_should_work_correctly
83
83
  session = Net::SSH.start(*ssh_start_params)
84
-
84
+
85
85
  assert_nothing_raised do
86
86
  session.forward.remote(22, localhost, 0, localhost)
87
87
  session.loop { !(session.forward.active_remotes.length > 0) }
@@ -90,9 +90,58 @@ class TestForward < Test::Unit::TestCase
90
90
  assert_operator assigned_port, :>, 0
91
91
  end
92
92
  end
93
-
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
+
94
143
  def test_loop_should_not_abort_when_local_side_of_forward_is_closed
95
- session = Net::SSH.start(*ssh_start_params)
144
+ session = Net::SSH.start(*ssh_start_params)
96
145
  server_exc = Queue.new
97
146
  server = start_server_sending_lot_of_data(server_exc)
98
147
  remote_port = server.addr[1]
@@ -112,10 +161,10 @@ class TestForward < Test::Unit::TestCase
112
161
  session.loop(0.1) { client_done.empty? }
113
162
  assert_equal "Broken pipe", "#{server_exc.pop}" unless server_exc.empty?
114
163
  end
115
-
164
+
116
165
  def test_loop_should_not_abort_when_local_side_of_forward_is_reset
117
166
  session = Net::SSH.start(*ssh_start_params)
118
- server_exc = Queue.new
167
+ server_exc = Queue.new
119
168
  server = start_server_sending_lot_of_data(server_exc)
120
169
  remote_port = server.addr[1]
121
170
  local_port = 0 # request ephemeral port
@@ -143,9 +192,9 @@ class TestForward < Test::Unit::TestCase
143
192
  yield UNIXServer.open(path)
144
193
  File.delete(path)
145
194
  end if defined?(UNIXServer)
146
-
195
+
147
196
  def test_forward_local_unix_socket_to_remote_port
148
- session = Net::SSH.start(*ssh_start_params)
197
+ session = Net::SSH.start(*ssh_start_params)
149
198
  server_exc = Queue.new
150
199
  server = start_server_sending_lot_of_data(server_exc)
151
200
  remote_port = server.addr[1]
@@ -174,7 +223,7 @@ class TestForward < Test::Unit::TestCase
174
223
  end if defined?(UNIXSocket)
175
224
 
176
225
  def test_loop_should_not_abort_when_server_side_of_forward_is_closed
177
- session = Net::SSH.start(*ssh_start_params)
226
+ session = Net::SSH.start(*ssh_start_params)
178
227
  server = start_server_closing_soon
179
228
  remote_port = server.addr[1]
180
229
  local_port = 0 # request ephemeral port
@@ -183,18 +232,18 @@ class TestForward < Test::Unit::TestCase
183
232
  Thread.start do
184
233
  begin
185
234
  client = TCPSocket.new(localhost, local_port)
186
- 1.times do |i|
235
+ 1.times do |i|
187
236
  client.puts "item#{i}"
188
237
  end
189
238
  client.close
190
239
  sleep(0.1)
191
- ensure
240
+ ensure
192
241
  client_done << true
193
242
  end
194
243
  end
195
244
  session.loop(0.1) { client_done.empty? }
196
245
  end
197
-
246
+
198
247
  def start_server
199
248
  server = TCPServer.open(0)
200
249
  Thread.start do
@@ -206,9 +255,9 @@ class TestForward < Test::Unit::TestCase
206
255
  end
207
256
  return server
208
257
  end
209
-
258
+
210
259
  def test_server_eof_should_be_handled
211
- session = Net::SSH.start(*ssh_start_params)
260
+ session = Net::SSH.start(*ssh_start_params)
212
261
  server = start_server do |client|
213
262
  client.write "This is a small message!"
214
263
  client.close