costan-rtunnel 0.4.0
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.
- 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
|