net-ssh 2.0.20 → 2.0.21
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +16 -0
- data/Rakefile +8 -2
- data/lib/net/ssh/buffered_io.rb +48 -0
- data/lib/net/ssh/config.rb +16 -6
- data/lib/net/ssh/service/forward.rb +24 -3
- data/lib/net/ssh/version.rb +1 -1
- data/net-ssh.gemspec +4 -1
- data/test/README.txt +42 -0
- data/test/configs/nohost +19 -0
- data/test/manual/test_forward.rb +185 -0
- data/test/test_all.rb +1 -0
- data/test/test_config.rb +6 -0
- metadata +5 -2
data/CHANGELOG.rdoc
CHANGED
@@ -1,4 +1,18 @@
|
|
1
1
|
|
2
|
+
|
3
|
+
=== 2.0.21 / 20 Mar 2010
|
4
|
+
|
5
|
+
* Fix for "IdentifyFile" in ~/.ssh/config does not work if no "Host" statement is given (http://net-ssh.lighthouseapp.com/projects/36253/tickets/9-identifyfile-in-sshconfig-does-not-work-if-no-host-statement-is-given#ticket-9-5) [xbaldauf, Delano Mandelbaum]
|
6
|
+
|
7
|
+
* Fix for client closes a forwarded connection, but the server is reading, net-ssh terminates with IOError socket closed (http://net-ssh.lighthouseapp.com/projects/36253/tickets/7) [Miklós Fazekas]
|
8
|
+
|
9
|
+
* Fix for client force closes (RST) a forwarded connection, but server is reading, net-ssh terminates with exception [Miklós Fazekas]
|
10
|
+
|
11
|
+
* Fix for server closes the sending side, the on_eof is not handled. [Miklós Fazekas]
|
12
|
+
|
13
|
+
* Removed Hanna dependency in Rakefile [Delano Mandelbaum]
|
14
|
+
|
15
|
+
|
2
16
|
=== 2.0.20 / 10 Feb 2010
|
3
17
|
|
4
18
|
* Support "ProxyCommand none" directive [Andy Lo-A-Foe]
|
@@ -20,7 +34,9 @@
|
|
20
34
|
=== 2.0.16 / 28 Nov 2009
|
21
35
|
|
22
36
|
* Fix for "multiple hosts are separated by whitespace" [Akinori MUSHA]
|
37
|
+
|
23
38
|
* Add support for the ProxyCommand directive [Akinori MUSHA]
|
39
|
+
|
24
40
|
* Switched from #recv(1) to #readpartial in lib/net/ssh/transport/server_version.rb, so that closed sockets are recognized [Alex Peuchert]
|
25
41
|
|
26
42
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake/clean'
|
3
3
|
require 'rake/gempackagetask'
|
4
|
-
require 'hanna/rdoctask'
|
5
4
|
require 'fileutils'
|
6
5
|
include FileUtils
|
7
|
-
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'hanna/rdoctask'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rake/rdoctask'
|
11
|
+
end
|
12
|
+
|
13
|
+
|
8
14
|
task :default => :package
|
9
15
|
|
10
16
|
# CONFIG =============================================================
|
data/lib/net/ssh/buffered_io.rb
CHANGED
@@ -147,4 +147,52 @@ module Net; module SSH
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
+
|
151
|
+
|
152
|
+
# Fixes for two issues by Miklós Fazekas:
|
153
|
+
#
|
154
|
+
# * if client closes a forwarded connection, but the server is
|
155
|
+
# reading, net-ssh terminates with IOError socket closed.
|
156
|
+
# * if client force closes (RST) a forwarded connection, but
|
157
|
+
# server is reading, net-ssh terminates with [an exception]
|
158
|
+
#
|
159
|
+
# See:
|
160
|
+
#
|
161
|
+
# http://net-ssh.lighthouseapp.com/projects/36253/tickets/7
|
162
|
+
# http://github.com/net-ssh/net-ssh/tree/portfwfix
|
163
|
+
#
|
164
|
+
module ForwardedBufferedIo
|
165
|
+
def fill(n=8192)
|
166
|
+
begin
|
167
|
+
super(n)
|
168
|
+
rescue Errno::ECONNRESET => e
|
169
|
+
debug { "connection was reset => shallowing exception:#{e}" }
|
170
|
+
return 0
|
171
|
+
rescue IOError => e
|
172
|
+
if e.message =~ /closed/ then
|
173
|
+
debug { "connection was reset => shallowing exception:#{e}" }
|
174
|
+
return 0
|
175
|
+
else
|
176
|
+
raise
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def send_pending
|
182
|
+
begin
|
183
|
+
super
|
184
|
+
rescue Errno::ECONNRESET => e
|
185
|
+
debug { "connection was reset => shallowing exception:#{e}" }
|
186
|
+
return 0
|
187
|
+
rescue IOError => e
|
188
|
+
if e.message =~ /closed/ then
|
189
|
+
debug { "connection was reset => shallowing exception:#{e}" }
|
190
|
+
return 0
|
191
|
+
else
|
192
|
+
raise
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
150
198
|
end; end
|
data/lib/net/ssh/config.rb
CHANGED
@@ -55,12 +55,14 @@ module Net; module SSH
|
|
55
55
|
# ones. Returns a hash containing the OpenSSH options. (See
|
56
56
|
# #translate for how to convert the OpenSSH options into Net::SSH
|
57
57
|
# options.)
|
58
|
-
def load(
|
59
|
-
file = File.expand_path(
|
58
|
+
def load(path, host, settings={})
|
59
|
+
file = File.expand_path(path)
|
60
60
|
return settings unless File.readable?(file)
|
61
61
|
|
62
|
+
globals = {}
|
62
63
|
matched_host = nil
|
63
64
|
multi_host = []
|
65
|
+
seen_host = false
|
64
66
|
IO.foreach(file) do |line|
|
65
67
|
next if line =~ /^\s*(?:#.*)?$/
|
66
68
|
|
@@ -75,29 +77,37 @@ module Net; module SSH
|
|
75
77
|
|
76
78
|
key.downcase!
|
77
79
|
value = $1 if value =~ /^"(.*)"$/
|
78
|
-
|
80
|
+
|
79
81
|
value = case value.strip
|
80
82
|
when /^\d+$/ then value.to_i
|
81
83
|
when /^no$/i then false
|
82
84
|
when /^yes$/i then true
|
83
85
|
else value
|
84
86
|
end
|
85
|
-
|
87
|
+
|
86
88
|
if key == 'host'
|
87
89
|
# Support "Host host1 host2 hostN".
|
88
90
|
# See http://github.com/net-ssh/net-ssh/issues#issue/6
|
89
91
|
multi_host = value.split(/\s+/)
|
90
92
|
matched_host = multi_host.select { |h| host =~ pattern2regex(h) }.first
|
93
|
+
seen_host = true
|
94
|
+
elsif !seen_host
|
95
|
+
if key == 'identityfile'
|
96
|
+
(globals[key] ||= []) << value
|
97
|
+
else
|
98
|
+
globals[key] = value unless settings.key?(key)
|
99
|
+
end
|
91
100
|
elsif !matched_host.nil?
|
92
101
|
if key == 'identityfile'
|
93
|
-
settings[key] ||= []
|
94
|
-
settings[key] << value
|
102
|
+
(settings[key] ||= []) << value
|
95
103
|
else
|
96
104
|
settings[key] = value unless settings.key?(key)
|
97
105
|
end
|
98
106
|
end
|
99
107
|
end
|
100
108
|
|
109
|
+
settings = globals.merge(settings) if globals
|
110
|
+
|
101
111
|
return settings
|
102
112
|
end
|
103
113
|
|
@@ -193,21 +193,42 @@ module Net; module SSH; module Service
|
|
193
193
|
end
|
194
194
|
|
195
195
|
private
|
196
|
-
|
196
|
+
|
197
197
|
# Perform setup operations that are common to all forwarded channels.
|
198
198
|
# +client+ is a socket, +channel+ is the channel that was just created,
|
199
199
|
# and +type+ is an arbitrary string describing the type of the channel.
|
200
200
|
def prepare_client(client, channel, type)
|
201
201
|
client.extend(Net::SSH::BufferedIo)
|
202
|
+
client.extend(Net::SSH::ForwardedBufferedIo)
|
202
203
|
client.logger = logger
|
203
204
|
|
204
205
|
session.listen_to(client)
|
205
206
|
channel[:socket] = client
|
206
207
|
|
207
|
-
channel.on_data do |ch, data|
|
208
|
+
channel.on_data do |ch, data|
|
209
|
+
debug { "data:#{data.length} on #{type} forwarded channel" }
|
208
210
|
ch[:socket].enqueue(data)
|
209
211
|
end
|
210
|
-
|
212
|
+
|
213
|
+
# Handles server close on the sending side by Miklós Fazekas
|
214
|
+
channel.on_eof do |ch|
|
215
|
+
debug { "eof #{type} on #{type} forwarded channel" }
|
216
|
+
begin
|
217
|
+
ch[:socket].send_pending
|
218
|
+
ch[:socket].shutdown Socket::SHUT_WR
|
219
|
+
rescue IOError => e
|
220
|
+
if e.message =~ /closed/ then
|
221
|
+
debug { "epipe in on_eof => shallowing exception:#{e}" }
|
222
|
+
else
|
223
|
+
raise
|
224
|
+
end
|
225
|
+
rescue Errno::EPIPE => e
|
226
|
+
debug { "epipe in on_eof => shallowing exception:#{e}" }
|
227
|
+
rescue Errno::ENOTCONN => e
|
228
|
+
debug { "enotconn in on_eof => shallowing exception:#{e}" }
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
211
232
|
channel.on_close do |ch|
|
212
233
|
debug { "closing #{type} forwarded channel" }
|
213
234
|
ch[:socket].close if !client.closed?
|
data/lib/net/ssh/version.rb
CHANGED
data/net-ssh.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "net-ssh"
|
3
3
|
s.rubyforge_project = 'net-ssh'
|
4
|
-
s.version = "2.0.
|
4
|
+
s.version = "2.0.21"
|
5
5
|
s.summary = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
|
6
6
|
s.description = s.summary
|
7
7
|
s.authors = ["Jamis Buck", "Delano Mandelbaum"]
|
@@ -91,6 +91,7 @@
|
|
91
91
|
setup.rb
|
92
92
|
support/arcfour_check.rb
|
93
93
|
support/ssh_tunnel_bug.rb
|
94
|
+
test/README.txt
|
94
95
|
test/authentication/methods/common.rb
|
95
96
|
test/authentication/methods/test_abstract.rb
|
96
97
|
test/authentication/methods/test_hostbased.rb
|
@@ -105,9 +106,11 @@
|
|
105
106
|
test/configs/exact_match
|
106
107
|
test/configs/host_plus
|
107
108
|
test/configs/multihost
|
109
|
+
test/configs/nohost
|
108
110
|
test/configs/wild_cards
|
109
111
|
test/connection/test_channel.rb
|
110
112
|
test/connection/test_session.rb
|
113
|
+
test/manual/test_forward.rb
|
111
114
|
test/test_all.rb
|
112
115
|
test/test_buffer.rb
|
113
116
|
test/test_buffered_io.rb
|
data/test/README.txt
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
2010-03-16
|
2
|
+
|
3
|
+
RUNNING TESTS
|
4
|
+
|
5
|
+
Run the test suite from the net-ssh directory with the following command:
|
6
|
+
|
7
|
+
ruby -Ilib -Itest -rrubygems test/test_all.rb
|
8
|
+
|
9
|
+
Run a single test file like this:
|
10
|
+
|
11
|
+
ruby -Ilib -Itest -rrubygems test/transport/test_server_version.rb
|
12
|
+
|
13
|
+
|
14
|
+
EXPECTED RESULTS
|
15
|
+
|
16
|
+
* Ruby 1.8: all tests pass
|
17
|
+
|
18
|
+
* Ruby 1.9: all tests pass
|
19
|
+
|
20
|
+
* JRuby 1.4: 96% tests pass (242 tests, 554 assertions, 0 failures, 8 errors)
|
21
|
+
|
22
|
+
|
23
|
+
PORT FORWARDING TESTS
|
24
|
+
|
25
|
+
ruby -Ilib -Itest -rrubygems test/manual/test_forward.rb
|
26
|
+
|
27
|
+
test_forward.rb must be run separately from the test suite because
|
28
|
+
it requires authorizing your public SSH keys on you localhost.
|
29
|
+
|
30
|
+
If you already have keys you can do this:
|
31
|
+
|
32
|
+
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
|
33
|
+
|
34
|
+
If you don't have keys see:
|
35
|
+
|
36
|
+
http://kimmo.suominen.com/docs/ssh/#ssh-keygen
|
37
|
+
|
38
|
+
You should now be able to login to your localhost with out
|
39
|
+
bring prompted for a password:
|
40
|
+
|
41
|
+
ssh localhost
|
42
|
+
|
data/test/configs/nohost
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
# $ ruby -Ilib -Itest -rrubygems test/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
|
+
|
22
|
+
class TestForward < Test::Unit::TestCase
|
23
|
+
|
24
|
+
def localhost
|
25
|
+
'localhost'
|
26
|
+
end
|
27
|
+
|
28
|
+
def ssh_start_params
|
29
|
+
[localhost ,ENV['USER']] #:verbose => :debug
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_free_port
|
33
|
+
server = TCPServer.open(0)
|
34
|
+
server.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR,true)
|
35
|
+
port = server.addr[1]
|
36
|
+
server.close
|
37
|
+
port
|
38
|
+
end
|
39
|
+
|
40
|
+
def start_server_sending_lot_of_data(exceptions)
|
41
|
+
server = TCPServer.open(0)
|
42
|
+
Thread.start do
|
43
|
+
loop do
|
44
|
+
Thread.start(server.accept) do |client|
|
45
|
+
begin
|
46
|
+
10000.times do |i|
|
47
|
+
client.puts "item#{i}"
|
48
|
+
end
|
49
|
+
client.close
|
50
|
+
rescue
|
51
|
+
exceptions << $!
|
52
|
+
raise
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return server
|
58
|
+
end
|
59
|
+
|
60
|
+
def start_server_closing_soon(exceptions=nil)
|
61
|
+
server = TCPServer.open(0)
|
62
|
+
Thread.start do
|
63
|
+
loop do
|
64
|
+
Thread.start(server.accept) do |client|
|
65
|
+
begin
|
66
|
+
client.recv(1024)
|
67
|
+
client.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, [1, 0].pack("ii"))
|
68
|
+
client.close
|
69
|
+
rescue
|
70
|
+
exceptions << $!
|
71
|
+
raise
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
return server
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_loop_should_not_abort_when_local_side_of_forward_is_closed
|
80
|
+
session = Net::SSH.start(*ssh_start_params)
|
81
|
+
server_exc = Queue.new
|
82
|
+
server = start_server_sending_lot_of_data(server_exc)
|
83
|
+
remote_port = server.addr[1]
|
84
|
+
local_port = find_free_port
|
85
|
+
session.forward.local(local_port, localhost, remote_port)
|
86
|
+
client_done = Queue.new
|
87
|
+
Thread.start do
|
88
|
+
begin
|
89
|
+
client = TCPSocket.new(localhost, local_port)
|
90
|
+
client.recv(1024)
|
91
|
+
client.close
|
92
|
+
sleep(0.2)
|
93
|
+
ensure
|
94
|
+
client_done << true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
session.loop(0.1) { client_done.empty? }
|
98
|
+
assert_equal "Broken pipe", "#{server_exc.pop}" unless server_exc.empty?
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_loop_should_not_abort_when_local_side_of_forward_is_reset
|
102
|
+
session = Net::SSH.start(*ssh_start_params)
|
103
|
+
server_exc = Queue.new
|
104
|
+
server = start_server_sending_lot_of_data(server_exc)
|
105
|
+
remote_port = server.addr[1]
|
106
|
+
local_port = find_free_port
|
107
|
+
session.forward.local(local_port, localhost, remote_port)
|
108
|
+
client_done = Queue.new
|
109
|
+
Thread.start do
|
110
|
+
begin
|
111
|
+
client = TCPSocket.new(localhost, local_port)
|
112
|
+
client.recv(1024)
|
113
|
+
client.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, [1, 0].pack("ii"))
|
114
|
+
client.close
|
115
|
+
sleep(0.1)
|
116
|
+
ensure
|
117
|
+
client_done << true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
session.loop(0.1) { client_done.empty? }
|
121
|
+
assert_equal "Broken pipe", "#{server_exc.pop}" unless server_exc.empty?
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_loop_should_not_abort_when_server_side_of_forward_is_closed
|
125
|
+
session = Net::SSH.start(*ssh_start_params)
|
126
|
+
server = start_server_closing_soon
|
127
|
+
remote_port = server.addr[1]
|
128
|
+
local_port = find_free_port
|
129
|
+
session.forward.local(local_port, localhost, remote_port)
|
130
|
+
client_done = Queue.new
|
131
|
+
Thread.start do
|
132
|
+
begin
|
133
|
+
client = TCPSocket.new(localhost, local_port)
|
134
|
+
1.times do |i|
|
135
|
+
client.puts "item#{i}"
|
136
|
+
end
|
137
|
+
client.close
|
138
|
+
sleep(0.1)
|
139
|
+
ensure
|
140
|
+
client_done << true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
session.loop(0.1) { client_done.empty? }
|
144
|
+
end
|
145
|
+
|
146
|
+
def start_server
|
147
|
+
server = TCPServer.open(0)
|
148
|
+
Thread.start do
|
149
|
+
loop do
|
150
|
+
Thread.start(server.accept) do |client|
|
151
|
+
yield(client)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
return server
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_server_eof_should_be_handled
|
159
|
+
session = Net::SSH.start(*ssh_start_params)
|
160
|
+
server = start_server do |client|
|
161
|
+
client.write "This is a small message!"
|
162
|
+
client.close
|
163
|
+
end
|
164
|
+
client_done = Queue.new
|
165
|
+
client_exception = Queue.new
|
166
|
+
client_data = Queue.new
|
167
|
+
remote_port = server.addr[1]
|
168
|
+
local_port = find_free_port
|
169
|
+
session.forward.local(local_port, localhost, remote_port)
|
170
|
+
Thread.start do
|
171
|
+
begin
|
172
|
+
client = TCPSocket.new(localhost, local_port)
|
173
|
+
data = client.read(4096)
|
174
|
+
client.close
|
175
|
+
client_done << data
|
176
|
+
rescue
|
177
|
+
client_done << $!
|
178
|
+
end
|
179
|
+
end
|
180
|
+
timeout(5) do
|
181
|
+
session.loop(0.1) { client_done.empty? }
|
182
|
+
assert_equal "This is a small message!", client_done.pop
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/test/test_all.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# $ ruby -Ilib -Itest -rrubygems test/transport/test_server_version.rb
|
3
3
|
Dir.chdir(File.dirname(__FILE__)) do
|
4
4
|
test_files = Dir['**/test_*.rb']
|
5
|
+
test_files = test_files.reject { |f| f =~ /^manual/ }
|
5
6
|
test_files = test_files.select { |f| f =~ Regexp.new(ENV['ONLY']) } if ENV['ONLY']
|
6
7
|
test_files = test_files.reject { |f| f =~ Regexp.new(ENV['EXCEPT']) } if ENV['EXCEPT']
|
7
8
|
test_files.each { |file| require(file) }
|
data/test/test_config.rb
CHANGED
@@ -38,6 +38,12 @@ class TestConfig < Test::Unit::TestCase
|
|
38
38
|
assert !config.key?(:rekey_limit)
|
39
39
|
end
|
40
40
|
|
41
|
+
def test_load_with_no_host
|
42
|
+
config = Net::SSH::Config.load(config(:nohost), "test.host")
|
43
|
+
assert_equal %w(~/.ssh/id_dsa ~/.ssh/id_rsa), config['identityfile']
|
44
|
+
assert_equal 1985, config['port']
|
45
|
+
end
|
46
|
+
|
41
47
|
def test_load_with_multiple_hosts
|
42
48
|
config = Net::SSH::Config.load(config(:multihost), "test.host")
|
43
49
|
assert config['compression']
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamis Buck
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-
|
13
|
+
date: 2010-03-20 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- setup.rb
|
100
100
|
- support/arcfour_check.rb
|
101
101
|
- support/ssh_tunnel_bug.rb
|
102
|
+
- test/README.txt
|
102
103
|
- test/authentication/methods/common.rb
|
103
104
|
- test/authentication/methods/test_abstract.rb
|
104
105
|
- test/authentication/methods/test_hostbased.rb
|
@@ -113,9 +114,11 @@ files:
|
|
113
114
|
- test/configs/exact_match
|
114
115
|
- test/configs/host_plus
|
115
116
|
- test/configs/multihost
|
117
|
+
- test/configs/nohost
|
116
118
|
- test/configs/wild_cards
|
117
119
|
- test/connection/test_channel.rb
|
118
120
|
- test/connection/test_session.rb
|
121
|
+
- test/manual/test_forward.rb
|
119
122
|
- test/test_all.rb
|
120
123
|
- test/test_buffer.rb
|
121
124
|
- test/test_buffered_io.rb
|