git ssb

0+

cel / sslh



Tree: 9bcb2cdd7a920ebc78b59d0b5797d678424aa93a

Files: 9bcb2cdd7a920ebc78b59d0b5797d678424aa93a / t

10229 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 = 1;
24my $STALL_CNX = 1;
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
70# Test: SSL connection
71 if ($SSL_CNX) {
72 print "***Test: SSL connection\n";
73 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
74 warn "$!\n" unless $cnx_l;
75 if (defined $cnx_l) {
76 print $cnx_l $test_data;
77 my $data = <$cnx_l>;
78 is($data, "ssl: $test_data", "SSL connection");
79 }
80 }
81
82# Test: Shy SSH connection
83 if ($SSH_SHY_CNX) {
84 print "***Test: Shy SSH connection\n";
85 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
86 warn "$!\n" unless $cnx_h;
87 if (defined $cnx_h) {
88 sleep 3;
89 print $cnx_h $test_data;
90 my $data = <$cnx_h>;
91 is($data, "ssh: $test_data", "Shy SSH connection");
92 }
93 }
94
95# Test: Bold SSH connection
96 if ($SSH_BOLD_CNX) {
97 print "***Test: Bold SSH connection\n";
98 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
99 warn "$!\n" unless $cnx_h;
100 if (defined $cnx_h) {
101 my $td = "SSH-2.0 testsuite\t$test_data";
102 print $cnx_h $td;
103 my $data = <$cnx_h>;
104 is($data, "ssh: $td", "Bold SSH connection");
105 }
106 }
107
108# Test: One SSL half-started then one SSH
109 if ($SSL_MIX_SSH) {
110 print "***Test: One SSL half-started then one SSH\n";
111 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
112 warn "$!\n" unless $cnx_l;
113 if (defined $cnx_l) {
114 print $cnx_l $test_data;
115 my $cnx_h= new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
116 warn "$!\n" unless $cnx_h;
117 if (defined $cnx_h) {
118 sleep 3;
119 print $cnx_h $test_data;
120 my $data_h = <$cnx_h>;
121 is($data_h, "ssh: $test_data", "SSH during SSL being established");
122 }
123 my $data = <$cnx_l>;
124 is($data, "ssl: $test_data", "SSL connection interrupted by SSH");
125 }
126 }
127
128# Test: One SSH half-started then one SSL
129 if ($SSH_MIX_SSL) {
130 print "***Test: One SSH half-started then one SSL\n";
131 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
132 warn "$!\n" unless $cnx_h;
133 if (defined $cnx_h) {
134 sleep 3;
135 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
136 warn "$!\n" unless $cnx_l;
137 if (defined $cnx_l) {
138 print $cnx_l $test_data;
139 my $data = <$cnx_l>;
140 is($data, "ssl: $test_data", "SSL during SSH being established");
141 }
142 print $cnx_h $test_data;
143 my $data = <$cnx_h>;
144 is($data, "ssh: $test_data", "SSH connection interrupted by SSL");
145 }
146 }
147
148
149# Test: Big messages (careful: don't go over echosrv's buffer limit (1M))
150 if ($BIG_MSG) {
151 print "***Test: big message\n";
152 my $cnx_l = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
153 warn "$!\n" unless $cnx_l;
154 my $test_data2 = "helloworld";
155 my $rept = 10000;
156 if (defined $cnx_l) {
157 print $cnx_l ($test_data2 x $rept);
158 print $cnx_l "\n";
159 my $data = <$cnx_l>;
160 is($data, "ssl: ". ($test_data2 x $rept) . "\n", "Big message");
161 }
162 }
163
164# Test: Stalled connection
165# Create two connections, stall one, check the other one
166# works, unstall first and check it works fine
167 if ($STALL_CNX) {
168 print "***Test: Stalled connection\n";
169 my $cnx_1 = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
170 warn "$!\n" unless defined $cnx_1;
171 my $cnx_2 = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
172 warn "$!\n" unless defined $cnx_2;
173 my $test_data2 = "helloworld";
174 my $rept = 10000;
175 if (defined $cnx_1 and defined $cnx_2) {
176 print $cnx_1 ($test_data2 x $rept);
177 print $cnx_1 "\n";
178 print $cnx_2 ($test_data2 x $rept);
179 print $cnx_2 "\n";
180 my $data = <$cnx_2>;
181 is($data, "ssl: " . ($test_data2 x $rept) . "\n", "Stalled connection (1)");
182 print $cnx_2 ($test_data2 x $rept);
183 print $cnx_2 "\n";
184 $data = <$cnx_2>;
185 is($data, "ssl: " . ($test_data2 x $rept) . "\n", "Stalled connection (2)");
186 $data = <$cnx_1>;
187 is($data, "ssl: " . ($test_data2 x $rept) . "\n", "Stalled connection (3)");
188
189 }
190 }
191
192 my $pid = `cat $pidfile`;
193 warn "killing $pid\n";
194 kill TERM => $pid or warn "kill process: $!\n";
195 sleep 1;
196}
197
198# Robustness: Connecting to non-existant server
199if ($RB_CNX_NOSERVER) {
200 print "***Test: Connecting to non-existant server\n";
201 my $sslh_pid;
202 if (!($sslh_pid = fork)) {
203 my $user = (getpwuid $<)[0]; # Run under current username
204 exec "./sslh-select -v -f -u $user --listen localhost:$sslh_port --ssh localhost:$no_listen --ssl localhost:$no_listen -P $pidfile";
205 }
206 warn "spawned $sslh_pid\n";
207
208 sleep 1;
209
210 my $cnx_h = new IO::Socket::INET(PeerHost => "localhost:$sslh_port");
211 warn "$!\n" unless $cnx_h;
212 if (defined $cnx_h) {
213 sleep 1;
214 my $test_data = "hello";
215 print $cnx_h $test_data;
216 }
217 # Ideally we should check a log is emitted.
218
219 kill TERM => `cat $pidfile` or warn "kill: $!\n";
220 sleep 1;
221}
222
223
224# Robustness: No hostname in address
225if ($RB_PARAM_NOHOST) {
226 print "***Test: No hostname in address\n";
227 my $sslh_pid;
228 if (!($sslh_pid = fork)) {
229 my $user = (getpwuid $<)[0]; # Run under current username
230 exec "./sslh-select -v -f -u $user --listen $sslh_port --ssh $ssh_address --ssl $ssl_address -P $pidfile";
231 }
232 warn "spawned $sslh_pid\n";
233 waitpid $sslh_pid, 0;
234 my $code = $? >> 8;
235 warn "exited with $code\n";
236 is($code, 1, "Exit status on illegal option");
237}
238
239# Robustness: User does not exist
240if ($RB_WRONG_USERNAME) {
241 print "***Test: Changing to non-existant username\n";
242 my $sslh_pid;
243 if (!($sslh_pid = fork)) {
244 my $user = (getpwuid $<)[0]; # Run under current username
245 exec "./sslh-select -v -f -u ${user}_doesnt_exist --listen localhost:$sslh_port --ssh $ssh_address --ssl $ssl_address -P $pidfile";
246 }
247 warn "spawned $sslh_pid\n";
248 waitpid $sslh_pid, 0;
249 my $code = $? >> 8;
250 warn "exited with $code\n";
251 is($code, 2, "Exit status on non-existant username");
252}
253
254# Robustness: Can't open PID file
255if ($RB_OPEN_PID_FILE) {
256 print "***Test: Can't open PID file\n";
257 my $sslh_pid;
258 if (!($sslh_pid = fork)) {
259 my $user = (getpwuid $<)[0]; # Run under current username
260 exec "./sslh-select -v -f -u $user --listen localhost:$sslh_port --ssh $ssh_address --ssl $ssl_address -P /dont_exist/$pidfile";
261 # You don't have a /dont_exist/ directory, do you?!
262 }
263 warn "spawned $sslh_pid\n";
264 waitpid $sslh_pid, 0;
265 my $code = $? >> 8;
266 warn "exited with $code\n";
267 is($code, 3, "Exit status if can't open PID file");
268}
269
270# Robustness: Can't bind address
271if ($RB_BIND_ADDRESS) {
272 print "***Test: Can't bind address\n";
273 my $sslh_pid;
274 if (!($sslh_pid = fork)) {
275 my $user = (getpwuid $<)[0]; # Run under current username
276 exec "./sslh-select -v -f -u $user --listen 74.125.39.106:9000 --ssh $ssh_address --ssl $ssl_address -P $pidfile";
277 }
278 warn "spawned $sslh_pid\n";
279 waitpid $sslh_pid, 0;
280 my $code = $? >> 8;
281 warn "exited with $code\n";
282 is($code, 1, "Exit status if can't bind address");
283}
284
285# Robustness: Can't resolve address
286if ($RB_RESOLVE_ADDRESS) {
287 print "***Test: Can't resolve address\n";
288 my $sslh_pid;
289 if (!($sslh_pid = fork)) {
290 my $user = (getpwuid $<)[0]; # Run under current username
291 exec "./sslh-select -v -f -u $user --listen blahblah.dontexist:9000 --ssh $ssh_address --ssl $ssl_address -P $pidfile";
292 }
293 warn "spawned $sslh_pid\n";
294 waitpid $sslh_pid, 0;
295 my $code = $? >> 8;
296 warn "exited with $code\n";
297 is($code, 4, "Exit status if can't resolve address");
298}
299
300`lcov --directory . --capture --output-file sslh_cov.info`;
301`genhtml sslh_cov.info`;
302
303`killall echosrv`;
304
305

Built with git-ssb-web