git ssb

0+

cel / sslh



Tree: 2781c75ff99cd5da7b25f6b883d78ff3de987308

Files: 2781c75ff99cd5da7b25f6b883d78ff3de987308 / t

10798 bytesRaw
1#! /usr/bin/perl -w
2
3# Test script for sslh
4
5use strict;
6use IO::Socket::INET6;
7use Test::More qw/no_plan/;
8
9# We use ports 9000, 9001 and 9002 -- hope that won't clash
10# with anything...
11my $ssh_address = "ip6-localhost:9000";
12my $ssl_address = "ip6-localhost:9001";
13my $sslh_port = 9002;
14my $no_listen = 9003; # Port on which no-one listens
15my $pidfile = "/tmp/sslh_test.pid";
16
17# Which tests do we run
18my $SSL_CNX = 1;
19my $SSH_SHY_CNX = 1;
20my $SSH_BOLD_CNX = 1;
21my $SSL_MIX_SSH = 1;
22my $SSH_MIX_SSL = 1;
23my $BIG_MSG = 0; # This test is unreliable
24my $STALL_CNX = 0; # This test needs fixing
25
26# Robustness tests. These are mostly to achieve full test
27# coverage, but do not necessarily result in an actual test
28# (e.g. some tests need to be run with valgrind to check all
29# memory management code).
30my $RB_CNX_NOSERVER = 1;
31my $RB_PARAM_NOHOST = 1;
32my $RB_WRONG_USERNAME = 1;
33my $RB_OPEN_PID_FILE = 1;
34my $RB_BIND_ADDRESS = 1;
35my $RB_RESOLVE_ADDRESS = 1;
36
37`lcov --directory . --zerocounters`;
38
39
40my ($ssh_pid, $ssl_pid);
41
42if (!($ssh_pid = fork)) {
43 exec "./echosrv --listen $ssh_address --prefix 'ssh: '";
44}
45
46if (!($ssl_pid = fork)) {
47 exec "./echosrv --listen $ssl_address --prefix 'ssl: '";
48}
49
50my @binaries = ('sslh-select', 'sslh-fork');
51for my $binary (@binaries) {
52 warn "Testing $binary\n";
53
54# Start sslh with the right plumbing
55 my $sslh_pid;
56 if (!($sslh_pid = fork)) {
57 my $user = (getpwuid $<)[0]; # Run under current username
58 my $cmd = "./$binary -v -f -u $user --listen localhost:$sslh_port --ssh $ssh_address --ssl $ssl_address -P $pidfile";
59 warn "$cmd\n";
60 #exec $cmd;
61 exec "valgrind --leak-check=full ./sslh-select -v -f -u $user --listen localhost:$sslh_port --ssh $ssh_address -ssl $ssl_address -P $pidfile";
62 exit 0;
63 }
64 warn "spawned $sslh_pid\n";
65 sleep 1; # valgrind can be heavy -- wait 5 seconds
66
67
68 my $test_data = "hello world\n";
69# my $ssl_test_data = (pack 'n', ((length $test_data) + 2)) . $test_data;
70 my $ssl_test_data = "\x16\x03\x03$test_data\n";
71
72# Test: SSL connection
73 if ($SSL_CNX) {
74 print "***Test: SSL connection\n";
75 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
76 warn "$!\n" unless $cnx_l;
77 if (defined $cnx_l) {
78 print $cnx_l $ssl_test_data;
79 my $data;
80 my $n = sysread $cnx_l, $data, 1024;
81 is($data, "ssl: $ssl_test_data", "SSL connection");
82 }
83 }
84
85# Test: Shy SSH connection
86 if ($SSH_SHY_CNX) {
87 print "***Test: Shy SSH connection\n";
88 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
89 warn "$!\n" unless $cnx_h;
90 if (defined $cnx_h) {
91 sleep 3;
92 print $cnx_h $test_data;
93 my $data = <$cnx_h>;
94 is($data, "ssh: $test_data", "Shy SSH connection");
95 }
96 }
97
98# Test: Bold SSH connection
99 if ($SSH_BOLD_CNX) {
100 print "***Test: Bold SSH connection\n";
101 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
102 warn "$!\n" unless $cnx_h;
103 if (defined $cnx_h) {
104 my $td = "SSH-2.0 testsuite\t$test_data";
105 print $cnx_h $td;
106 my $data = <$cnx_h>;
107 is($data, "ssh: $td", "Bold SSH connection");
108 }
109 }
110
111# Test: One SSL half-started then one SSH
112 if ($SSL_MIX_SSH) {
113 print "***Test: One SSL half-started then one SSH\n";
114 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
115 warn "$!\n" unless $cnx_l;
116 if (defined $cnx_l) {
117 print $cnx_l $ssl_test_data;
118 my $cnx_h= new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
119 warn "$!\n" unless $cnx_h;
120 if (defined $cnx_h) {
121 sleep 3;
122 print $cnx_h $test_data;
123 my $data_h = <$cnx_h>;
124 is($data_h, "ssh: $test_data", "SSH during SSL being established");
125 }
126 my $data;
127 my $n = sysread $cnx_l, $data, 1024;
128 is($data, "ssl: $ssl_test_data", "SSL connection interrupted by SSH");
129 }
130 }
131
132# Test: One SSH half-started then one SSL
133 if ($SSH_MIX_SSL) {
134 print "***Test: One SSH half-started then one SSL\n";
135 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
136 warn "$!\n" unless $cnx_h;
137 if (defined $cnx_h) {
138 sleep 3;
139 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
140 warn "$!\n" unless $cnx_l;
141 if (defined $cnx_l) {
142 print $cnx_l $ssl_test_data;
143 my $data;
144 my $n = sysread $cnx_l, $data, 1024;
145 is($data, "ssl: $ssl_test_data", "SSL during SSH being established");
146 }
147 print $cnx_h $test_data;
148 my $data = <$cnx_h>;
149 is($data, "ssh: $test_data", "SSH connection interrupted by SSL");
150 }
151 }
152
153
154# Test: Big messages (careful: don't go over echosrv's buffer limit (1M))
155 if ($BIG_MSG) {
156 print "***Test: big message\n";
157 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
158 warn "$!\n" unless $cnx_l;
159 my $rept = 1000;
160 my $test_data2 = $ssl_test_data . ("helloworld"x$rept);
161 if (defined $cnx_l) {
162 my $n = syswrite $cnx_l, $test_data2;
163 my ($data);
164 $n = sysread $cnx_l, $data, 1 << 20;
165 is($data, "ssl: ". $test_data2, "Big message");
166 }
167 }
168
169# Test: Stalled connection
170# Create two connections, stall one, check the other one
171# works, unstall first and check it works fine
172# This test needs fixing.
173# Now that echosrv no longer works on "lines" (finishing
174# with '\n'), it may cut blocks randomly with prefixes.
175# The whole thing needs to be re-thought as it'll only
176# work by chance.
177 if ($STALL_CNX) {
178 print "***Test: Stalled connection\n";
179 my $cnx_1 = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
180 warn "$!\n" unless defined $cnx_1;
181 my $cnx_2 = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
182 warn "$!\n" unless defined $cnx_2;
183 my $test_data2 = "helloworld";
184 sleep 4;
185 my $rept = 1000;
186 if (defined $cnx_1 and defined $cnx_2) {
187 print $cnx_1 ($test_data2 x $rept);
188 print $cnx_1 "\n";
189 print $cnx_2 ($test_data2 x $rept);
190 print $cnx_2 "\n";
191 my $data = <$cnx_2>;
192 is($data, "ssh: " . ($test_data2 x $rept) . "\n", "Stalled connection (1)");
193 print $cnx_2 ($test_data2 x $rept);
194 print $cnx_2 "\n";
195 $data = <$cnx_2>;
196 is($data, "ssh: " . ($test_data2 x $rept) . "\n", "Stalled connection (2)");
197 $data = <$cnx_1>;
198 is($data, "ssh: " . ($test_data2 x $rept) . "\n", "Stalled connection (3)");
199
200 }
201 }
202
203 my $pid = `cat $pidfile`;
204 warn "killing $pid\n";
205 kill TERM => $pid or warn "kill process: $!\n";
206 sleep 1;
207}
208
209# Robustness: Connecting to non-existant server
210if ($RB_CNX_NOSERVER) {
211 print "***Test: Connecting to non-existant server\n";
212 my $sslh_pid;
213 if (!($sslh_pid = fork)) {
214 my $user = (getpwuid $<)[0]; # Run under current username
215 exec "./sslh-select -v -f -u $user --listen localhost:$sslh_port --ssh localhost:$no_listen --ssl localhost:$no_listen -P $pidfile";
216 }
217 warn "spawned $sslh_pid\n";
218
219 sleep 1;
220
221 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
222 warn "$!\n" unless $cnx_h;
223 if (defined $cnx_h) {
224 sleep 1;
225 my $test_data = "hello";
226 print $cnx_h $test_data;
227 }
228 # Ideally we should check a log is emitted.
229
230 kill TERM => `cat $pidfile` or warn "kill: $!\n";
231 sleep 1;
232}
233
234
235# Robustness: No hostname in address
236if ($RB_PARAM_NOHOST) {
237 print "***Test: No hostname in address\n";
238 my $sslh_pid;
239 if (!($sslh_pid = fork)) {
240 my $user = (getpwuid $<)[0]; # Run under current username
241 exec "./sslh-select -v -f -u $user --listen $sslh_port --ssh $ssh_address --ssl $ssl_address -P $pidfile";
242 }
243 warn "spawned $sslh_pid\n";
244 waitpid $sslh_pid, 0;
245 my $code = $? >> 8;
246 warn "exited with $code\n";
247 is($code, 1, "Exit status on illegal option");
248}
249
250# Robustness: User does not exist
251if ($RB_WRONG_USERNAME) {
252 print "***Test: Changing to non-existant username\n";
253 my $sslh_pid;
254 if (!($sslh_pid = fork)) {
255 my $user = (getpwuid $<)[0]; # Run under current username
256 exec "./sslh-select -v -f -u ${user}_doesnt_exist --listen localhost:$sslh_port --ssh $ssh_address --ssl $ssl_address -P $pidfile";
257 }
258 warn "spawned $sslh_pid\n";
259 waitpid $sslh_pid, 0;
260 my $code = $? >> 8;
261 warn "exited with $code\n";
262 is($code, 2, "Exit status on non-existant username");
263}
264
265# Robustness: Can't open PID file
266if ($RB_OPEN_PID_FILE) {
267 print "***Test: Can't open PID file\n";
268 my $sslh_pid;
269 if (!($sslh_pid = fork)) {
270 my $user = (getpwuid $<)[0]; # Run under current username
271 exec "./sslh-select -v -f -u $user --listen localhost:$sslh_port --ssh $ssh_address --ssl $ssl_address -P /dont_exist/$pidfile";
272 # You don't have a /dont_exist/ directory, do you?!
273 }
274 warn "spawned $sslh_pid\n";
275 waitpid $sslh_pid, 0;
276 my $code = $? >> 8;
277 warn "exited with $code\n";
278 is($code, 3, "Exit status if can't open PID file");
279}
280
281# Robustness: Can't bind address
282if ($RB_BIND_ADDRESS) {
283 print "***Test: Can't bind address\n";
284 my $sslh_pid;
285 if (!($sslh_pid = fork)) {
286 my $user = (getpwuid $<)[0]; # Run under current username
287 exec "./sslh-select -v -f -u $user --listen 74.125.39.106:9000 --ssh $ssh_address --ssl $ssl_address -P $pidfile";
288 }
289 warn "spawned $sslh_pid\n";
290 waitpid $sslh_pid, 0;
291 my $code = $? >> 8;
292 warn "exited with $code\n";
293 is($code, 1, "Exit status if can't bind address");
294}
295
296# Robustness: Can't resolve address
297if ($RB_RESOLVE_ADDRESS) {
298 print "***Test: Can't resolve address\n";
299 my $sslh_pid;
300 if (!($sslh_pid = fork)) {
301 my $user = (getpwuid $<)[0]; # Run under current username
302 exec "./sslh-select -v -f -u $user --listen blahblah.dontexist:9000 --ssh $ssh_address --ssl $ssl_address -P $pidfile";
303 }
304 warn "spawned $sslh_pid\n";
305 waitpid $sslh_pid, 0;
306 my $code = $? >> 8;
307 warn "exited with $code\n";
308 is($code, 4, "Exit status if can't resolve address");
309}
310
311`lcov --directory . --capture --output-file sslh_cov.info`;
312`genhtml sslh_cov.info`;
313
314`killall echosrv`;
315
316

Built with git-ssb-web