costan-rtunnel 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -0
- data/LICENSE +21 -0
- data/Manifest +49 -0
- data/README.markdown +84 -0
- data/Rakefile +45 -0
- data/bin/rtunnel_client +4 -0
- data/bin/rtunnel_server +4 -0
- data/lib/rtunnel.rb +20 -0
- data/lib/rtunnel/client.rb +308 -0
- data/lib/rtunnel/command_processor.rb +62 -0
- data/lib/rtunnel/command_protocol.rb +50 -0
- data/lib/rtunnel/commands.rb +233 -0
- data/lib/rtunnel/connection_id.rb +24 -0
- data/lib/rtunnel/core.rb +58 -0
- data/lib/rtunnel/crypto.rb +106 -0
- data/lib/rtunnel/frame_protocol.rb +34 -0
- data/lib/rtunnel/io_extensions.rb +54 -0
- data/lib/rtunnel/leak.rb +35 -0
- data/lib/rtunnel/rtunnel_client_cmd.rb +41 -0
- data/lib/rtunnel/rtunnel_server_cmd.rb +32 -0
- data/lib/rtunnel/server.rb +351 -0
- data/lib/rtunnel/socket_factory.rb +119 -0
- data/spec/client_spec.rb +47 -0
- data/spec/cmds_spec.rb +127 -0
- data/spec/integration_spec.rb +105 -0
- data/spec/server_spec.rb +21 -0
- data/spec/spec_helper.rb +3 -0
- data/test/command_stubs.rb +77 -0
- data/test/protocol_mocks.rb +43 -0
- data/test/scenario_connection.rb +109 -0
- data/test/test_client.rb +48 -0
- data/test/test_command_protocol.rb +82 -0
- data/test/test_commands.rb +49 -0
- data/test/test_connection_id.rb +30 -0
- data/test/test_crypto.rb +127 -0
- data/test/test_frame_protocol.rb +109 -0
- data/test/test_io_extensions.rb +70 -0
- data/test/test_server.rb +70 -0
- data/test/test_socket_factory.rb +42 -0
- data/test/test_tunnel.rb +186 -0
- data/test_data/authorized_keys2 +4 -0
- data/test_data/known_hosts +4 -0
- data/test_data/random_rsa_key +27 -0
- data/test_data/ssh_host_dsa_key +12 -0
- data/test_data/ssh_host_rsa_key +27 -0
- data/tests/_ab_test.rb +16 -0
- data/tests/_stress_test.rb +96 -0
- data/tests/lo_http_server.rb +55 -0
- metadata +121 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'rtunnel'
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
require 'test/protocol_mocks.rb'
|
6
|
+
|
7
|
+
# Send mock for frames.
|
8
|
+
class EmSendFramesMock < EmSendMock
|
9
|
+
include RTunnel::FrameProtocol
|
10
|
+
end
|
11
|
+
|
12
|
+
# Receive mock for frames.
|
13
|
+
class EmReceiveFramesMock < EmReceiveMock
|
14
|
+
include RTunnel::FrameProtocol
|
15
|
+
object_name :frame
|
16
|
+
end
|
17
|
+
|
18
|
+
class FrameProtocolTest < Test::Unit::TestCase
|
19
|
+
def setup
|
20
|
+
super
|
21
|
+
@send_mock = EmSendFramesMock.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def continuous_data_test(frames)
|
29
|
+
truncated_data_test frames, []
|
30
|
+
end
|
31
|
+
|
32
|
+
def truncated_data_test(frames, sub_lengths)
|
33
|
+
frames.each { |frame| @send_mock.send_frame frame }
|
34
|
+
in_string = @send_mock.string
|
35
|
+
in_strings, i = [], 0
|
36
|
+
sub_lengths.each do |sublen|
|
37
|
+
in_strings << in_string[i, sublen]
|
38
|
+
i += sublen
|
39
|
+
end
|
40
|
+
in_strings << in_string[i..-1] if i < in_string.length
|
41
|
+
out_frames = EmReceiveFramesMock.new(@send_mock.string).replay.frames
|
42
|
+
assert_equal frames, out_frames
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_empty_frame
|
46
|
+
continuous_data_test ['']
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_byte_frame
|
50
|
+
continuous_data_test ['F']
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_string_frame
|
54
|
+
continuous_data_test [(32...128).to_a.pack('C*')]
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_multiple_frames
|
58
|
+
continuous_data_test [(32...128).to_a.pack('C*'), '', 'F', '', '1234567890']
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_truncated_border
|
62
|
+
truncated_data_test ['A', 'A'], [1, 0, 2, 0]
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_truncated_border_and_joined_data_size
|
66
|
+
truncated_data_test ['A', 'A'], [1, 1, 1, 1]
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_truncated_size
|
70
|
+
long_frame = (32...128).to_a.pack('C*') * 5
|
71
|
+
truncated_data_test [long_frame], [1]
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_truncated_size_and_data
|
75
|
+
long_frame = (32...128).to_a.pack('C*') * 5
|
76
|
+
truncated_data_test [long_frame], [1, 16]
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_badass
|
80
|
+
# TODO(not_me): this test takes 4 seconds; replace with more targeted tests
|
81
|
+
|
82
|
+
# build the badass string
|
83
|
+
s2_frame = 'qwertyuiopasdfgh' * 8 * 128 # 16384 characters, size is 3 bytes
|
84
|
+
@send_mock.send_frame s2_frame
|
85
|
+
s2_string = @send_mock.string
|
86
|
+
s2_count = 3
|
87
|
+
send_string = s2_string * s2_count
|
88
|
+
ex_frames = [s2_frame] * s2_count
|
89
|
+
|
90
|
+
# build cut points in a string
|
91
|
+
s2_points = [0, 1, 2, 3, 4, 5, 127, 128, 8190, 16381, 16382, 16383]
|
92
|
+
cut_points = []
|
93
|
+
0.upto(s2_count - 1) do |i|
|
94
|
+
cut_points += s2_points.map { |p| p + i * s2_string.length }
|
95
|
+
end
|
96
|
+
|
97
|
+
# try all combinations of cutting up the string in 4 pieces
|
98
|
+
0.upto(cut_points.length - 1) do |i|
|
99
|
+
(i + 1).upto(cut_points.length - 1) do |j|
|
100
|
+
(j + 1).upto(cut_points.length - 1) do |k|
|
101
|
+
packets = [0...cut_points[i], cut_points[i]...cut_points[j],
|
102
|
+
cut_points[j]...cut_points[k], cut_points[k]..-1].
|
103
|
+
map { |r| send_string[r] }
|
104
|
+
assert_equal ex_frames, EmReceiveFramesMock.new(packets).replay.frames
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rtunnel'
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class IOExtensionsTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@test_sizes = [0, 1, 10, 127, 128, (1 << 20), (1 << 45) / 3, (1 << 62) / 5]
|
9
|
+
@test_strings = ['', 'a',
|
10
|
+
(32..127).to_a.map { |c| c.chr}.join,
|
11
|
+
(32..127).to_a.map { |c| c.chr}.join * 511]
|
12
|
+
@str = StringIO.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_varsizes_independent
|
16
|
+
@test_sizes.each do |size|
|
17
|
+
@str = StringIO.new
|
18
|
+
@str.write_varsize size
|
19
|
+
@str.rewind
|
20
|
+
assert_equal size, @str.read_varsize
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_varsizes_appended
|
25
|
+
@test_sizes.each { |size| @str.write_varsize size }
|
26
|
+
@str.rewind
|
27
|
+
@test_sizes.each do |size|
|
28
|
+
assert_equal size, @str.read_varsize
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_varsize_error
|
33
|
+
@str.write_varsize((1 << 62) / 3)
|
34
|
+
vs = @str.string
|
35
|
+
0.upto(vs.length - 1) do |truncated_len|
|
36
|
+
@str = StringIO.new
|
37
|
+
@str.write vs[0, truncated_len]
|
38
|
+
@str.rewind
|
39
|
+
assert_raise(RTunnel::TruncatedDataError) { @str.read_varsize }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_varstring_independent
|
44
|
+
@test_strings.each do |str|
|
45
|
+
@str = StringIO.new
|
46
|
+
@str.write_varstring str
|
47
|
+
@str.rewind
|
48
|
+
assert_equal str, @str.read_varstring
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_varstring_appended
|
53
|
+
@test_strings.each { |str| @str.write_varstring str }
|
54
|
+
@str.rewind
|
55
|
+
@test_strings.each do |str|
|
56
|
+
assert_equal str, @str.read_varstring
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_varstring_error
|
61
|
+
@str.write_varstring 'This will be truncated'
|
62
|
+
vs = @str.string
|
63
|
+
0.upto(vs.length - 1) do |truncated_len|
|
64
|
+
@str = StringIO.new
|
65
|
+
@str.write vs[0, truncated_len]
|
66
|
+
@str.rewind
|
67
|
+
assert_raise(RTunnel::TruncatedDataError) { @str.read_varstring }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/test/test_server.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rtunnel'
|
2
|
+
|
3
|
+
require 'resolv'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
|
7
|
+
class ServerTest < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
super
|
10
|
+
@server = RTunnel::Server.new(:control_address => 'localhost')
|
11
|
+
@localhost_addr = Resolv.getaddress 'localhost'
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_options
|
15
|
+
server = RTunnel::Server
|
16
|
+
assert_equal "18.241.3.100:#{RTunnel::DEFAULT_CONTROL_PORT}",
|
17
|
+
server.extract_control_address('18.241.3.100')
|
18
|
+
assert_equal "18.241.3.100:9199",
|
19
|
+
server.extract_control_address('18.241.3.100:9199')
|
20
|
+
assert_equal "#{@localhost_addr}:#{RTunnel::DEFAULT_CONTROL_PORT}",
|
21
|
+
server.extract_control_address('localhost')
|
22
|
+
assert_equal "#{@localhost_addr}:9199",
|
23
|
+
server.extract_control_address('localhost:9199')
|
24
|
+
assert_equal "0.0.0.0:9199",
|
25
|
+
server.extract_control_address('9199')
|
26
|
+
|
27
|
+
assert_equal RTunnel::KEEP_ALIVE_INTERVAL,
|
28
|
+
server.extract_keep_alive_interval(nil)
|
29
|
+
assert_equal 29, server.extract_keep_alive_interval(29)
|
30
|
+
|
31
|
+
assert_equal 0, server.extract_lowest_listen_port(nil)
|
32
|
+
assert_equal 29, server.extract_lowest_listen_port(29)
|
33
|
+
assert_equal 65535, server.extract_highest_listen_port(nil)
|
34
|
+
assert_equal 29, server.extract_highest_listen_port(29)
|
35
|
+
|
36
|
+
assert_equal nil, server.extract_authorized_keys(nil)
|
37
|
+
keyset = server.extract_authorized_keys 'test_data/known_hosts'
|
38
|
+
assert_equal RTunnel::Crypto::KeySet, keyset.class
|
39
|
+
assert keyset.length != 0, 'No key read from the known_hosts file'
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_validate_remote_listen
|
43
|
+
# remove Connection's new override, don't want event_machine here
|
44
|
+
EventMachine::Connection.class_eval do
|
45
|
+
class << self
|
46
|
+
alias_method :backup_new, :new
|
47
|
+
remove_method :new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
server = RTunnel::Server.new(:control_address => 'localhost',
|
52
|
+
:lowest_listen_port => 91,
|
53
|
+
:highest_listen_port => 105)
|
54
|
+
connection = RTunnel::Server::ControlConnection.new server
|
55
|
+
|
56
|
+
assert !connection.validate_remote_listen('localhost', 80)
|
57
|
+
assert connection.validate_remote_listen('localhost', 91)
|
58
|
+
assert connection.validate_remote_listen('localhost', 105)
|
59
|
+
assert !connection.validate_remote_listen('localhost', 90)
|
60
|
+
assert !connection.validate_remote_listen('localhost', 106)
|
61
|
+
|
62
|
+
# re-instate Connection's new override
|
63
|
+
EventMachine::Connection.class_eval do
|
64
|
+
class << self
|
65
|
+
alias_method :new, :backup_new
|
66
|
+
remove_method :backup_new
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rtunnel'
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class SocketFactoryTest < Test::Unit::TestCase
|
6
|
+
SF = RTunnel::SocketFactory
|
7
|
+
|
8
|
+
def setup
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_host_from_address
|
17
|
+
assert_equal nil, SF.host_from_address(nil)
|
18
|
+
assert_equal '127.0.0.1', SF.host_from_address('127.0.0.1')
|
19
|
+
assert_equal '127.0.0.1', SF.host_from_address('127.0.0.1:1234')
|
20
|
+
assert_equal 'fe80::1%lo0', SF.host_from_address('fe80::1%lo0')
|
21
|
+
assert_equal 'fe80::1%lo0', SF.host_from_address('fe80::1%lo0:19020')
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_port_from_address
|
25
|
+
assert_equal nil, SF.port_from_address(nil)
|
26
|
+
assert_equal nil, SF.port_from_address('127.0.0.1')
|
27
|
+
assert_equal 1234, SF.port_from_address('127.0.0.1:1234')
|
28
|
+
assert_equal nil, SF.port_from_address('fe80::1%lo0')
|
29
|
+
assert_equal 19020, SF.port_from_address('fe80::1%lo0:19020')
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_inbound
|
33
|
+
assert SF.inbound?(:in_port => 1)
|
34
|
+
assert SF.inbound?(:in_host => '1')
|
35
|
+
assert SF.inbound?(:in_addr => '1')
|
36
|
+
assert SF.inbound?(:inbound => true)
|
37
|
+
assert !SF.inbound?(:out_port => 1)
|
38
|
+
assert !SF.inbound?(:out_host => '1')
|
39
|
+
assert !SF.inbound?(:out_addr => '1')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/test/test_tunnel.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'rtunnel'
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'eventmachine'
|
7
|
+
|
8
|
+
require 'test/scenario_connection.rb'
|
9
|
+
|
10
|
+
# Integration tests ensuring that we can start a tunnel.
|
11
|
+
class TunnelTest < Test::Unit::TestCase
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
|
15
|
+
@connection_time = 0.001
|
16
|
+
@secure_connection_time = 0.5
|
17
|
+
@log_level = 'debug'
|
18
|
+
@local_host = '127.0.0.1'
|
19
|
+
@listen_port = 21335
|
20
|
+
@tunnel_port = 21336
|
21
|
+
@control_port = 21337
|
22
|
+
@key_file = 'test_data/ssh_host_rsa_key'
|
23
|
+
@hosts_file = 'test_data/known_hosts'
|
24
|
+
|
25
|
+
@tunnel_server = new_server
|
26
|
+
@tunnel_client = new_client
|
27
|
+
end
|
28
|
+
|
29
|
+
def new_server(extra_options = {})
|
30
|
+
RTunnel::Server.new({
|
31
|
+
:control_address => "#{@local_host}:#{@control_port}",
|
32
|
+
:log_level => @log_level
|
33
|
+
}.merge(extra_options))
|
34
|
+
end
|
35
|
+
|
36
|
+
def new_client(extra_options = {})
|
37
|
+
RTunnel::Client.new({
|
38
|
+
:control_address => "#{@local_host}:#{@control_port}",
|
39
|
+
:remote_listen_address => "#{@local_host}:#{@listen_port}",
|
40
|
+
:tunnel_to_address => "#{@local_host}:#{@tunnel_port}",
|
41
|
+
:log_level => @log_level
|
42
|
+
}.merge(extra_options))
|
43
|
+
end
|
44
|
+
|
45
|
+
def tunnel_test(connection_time = nil)
|
46
|
+
@stop_proc = proc do
|
47
|
+
@tunnel_client.stop
|
48
|
+
@tunnel_server.stop
|
49
|
+
@stop_proc = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
EventMachine::run do
|
53
|
+
@tunnel_server.start
|
54
|
+
@tunnel_client.start
|
55
|
+
|
56
|
+
if connection_time
|
57
|
+
EventMachine.add_timer(connection_time) { yield }
|
58
|
+
else
|
59
|
+
EventMachine.next_tick { yield }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_client_driven_tunnel
|
65
|
+
tunnel_test do
|
66
|
+
@tunnel_server.on_remote_listen do
|
67
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
68
|
+
ScenarioConnection, self, [[:recv, 'Hello'], [:send, 'World'],
|
69
|
+
[:unbind], [:stop, @stop_proc]]
|
70
|
+
|
71
|
+
EventMachine::connect @local_host, @listen_port,
|
72
|
+
ScenarioConnection, self, [[:send, 'Hello'], [:recv, 'World'],
|
73
|
+
[:close]]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_server_driven_tunnel
|
79
|
+
tunnel_test do
|
80
|
+
@tunnel_server.on_remote_listen do
|
81
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
82
|
+
ScenarioConnection, self, [[:send, 'Hello'], [:recv, 'World'],
|
83
|
+
[:close]]
|
84
|
+
|
85
|
+
EventMachine::connect @local_host, @listen_port,
|
86
|
+
ScenarioConnection, self, [[:recv, 'Hello'], [:send, 'World'],
|
87
|
+
[:unbind], [:stop]]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_two_tunnels
|
93
|
+
start_second = lambda do
|
94
|
+
@tunnel_client.stop
|
95
|
+
@tunnel_client.start
|
96
|
+
@tunnel_server.on_remote_listen do
|
97
|
+
EventMachine::connect @local_host, @listen_port,
|
98
|
+
ScenarioConnection, self, [[:send, 'Hello'], [:recv, 'World'],
|
99
|
+
[:unbind], [:stop, @stop_proc]]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
tunnel_test do
|
104
|
+
@tunnel_server.on_remote_listen do
|
105
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
106
|
+
ScenarioConnection, self, [[:recv, 'Hello'], [:send, 'World'],
|
107
|
+
[:close], [:recv, 'Hello'], [:send, 'World'], [:close]]
|
108
|
+
|
109
|
+
EventMachine::connect @local_host, @listen_port,
|
110
|
+
ScenarioConnection, self, [[:send, 'Hello'], [:recv, 'World'],
|
111
|
+
[:proc, start_second], [:unbind]]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_secure_tunnel
|
117
|
+
@tunnel_server = new_server :authorized_keys => @hosts_file
|
118
|
+
@tunnel_client = new_client :private_key => @key_file
|
119
|
+
tunnel_test do
|
120
|
+
@tunnel_server.on_remote_listen do
|
121
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
122
|
+
ScenarioConnection, self, [[:recv, 'Hello'], [:send, 'World'],
|
123
|
+
[:unbind], [:stop, @stop_proc]]
|
124
|
+
|
125
|
+
EventMachine::connect @local_host, @listen_port,
|
126
|
+
ScenarioConnection, self, [[:send, 'Hello'], [:recv, 'World'],
|
127
|
+
[:close]]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_secure_async_tunnel
|
133
|
+
@tunnel_server = new_server :authorized_keys => @hosts_file
|
134
|
+
@tunnel_client = new_client :private_key => @key_file
|
135
|
+
tunnel_test do
|
136
|
+
@tunnel_server.on_remote_listen do
|
137
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
138
|
+
ScenarioConnection, self, [[:send, 'World'], [:recv, 'Hello'],
|
139
|
+
[:unbind], [:stop, @stop_proc]]
|
140
|
+
|
141
|
+
EventMachine::connect @local_host, @listen_port,
|
142
|
+
ScenarioConnection, self, [[:send, 'Hello'], [:recv, 'World'],
|
143
|
+
[:close]]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_bad_listen_address
|
149
|
+
@tunnel_server = new_server
|
150
|
+
@tunnel_client = new_client :remote_listen_address =>
|
151
|
+
"18.70.0.160:#{@listen_port}"
|
152
|
+
|
153
|
+
tunnel_test do
|
154
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
155
|
+
ScenarioConnection, self, []
|
156
|
+
|
157
|
+
EventMachine::connect @local_host, @listen_port,
|
158
|
+
ScenarioConnection, self, [[:unbind], [:stop, @stop_proc]]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# TODO: fix this
|
163
|
+
def test_secure_server_rejects_unsecure_client
|
164
|
+
@tunnel_server = new_server :authorized_keys => @hosts_file
|
165
|
+
tunnel_test(@secure_connection_time) do
|
166
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
167
|
+
ScenarioConnection, self, []
|
168
|
+
|
169
|
+
EventMachine::connect @local_host, @listen_port,
|
170
|
+
ScenarioConnection, self, [[:unbind], [:stop, @stop_proc]]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# hrmf... this is testing security and its not 100% reliable... but I can't think of a better way
|
175
|
+
def test_secure_server_rejects_unauthorized_key
|
176
|
+
@tunnel_server = new_server :authorized_keys => @hosts_file
|
177
|
+
@tunnel_client = new_client :private_key => 'test_data/random_rsa_key'
|
178
|
+
tunnel_test(@secure_connection_time) do
|
179
|
+
EventMachine::start_server @local_host, @tunnel_port,
|
180
|
+
ScenarioConnection, self, []
|
181
|
+
|
182
|
+
EventMachine::connect @local_host, @listen_port,
|
183
|
+
ScenarioConnection, self, [[:unbind], [:stop, @stop_proc]]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|