Skip to content

Commit cbc787b

Browse files
committed
Forwarding Test
1. Add a test script and expect script for testing forwarding. 2. Update portfwd to have a ready file option. 3. Fix echoserver error string, needed NL.
1 parent f18c692 commit cbc787b

File tree

5 files changed

+226
-3
lines changed

5 files changed

+226
-3
lines changed

examples/echoserver/echoserver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2753,7 +2753,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
27532753

27542754
#ifdef WOLFSSH_TEST_BLOCK
27552755
if (!nonBlock) {
2756-
ES_ERROR("Use -N when testing forced non blocking");
2756+
ES_ERROR("Use -N when testing forced non blocking\n");
27572757
}
27582758
#endif
27592759

examples/portfwd/portfwd.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
235235
const char* fwdToHost = NULL;
236236
const char* username = NULL;
237237
const char* password = NULL;
238+
const char* readyFile = NULL;
238239
SOCKADDR_IN_T hostAddr;
239240
socklen_t hostAddrSz = sizeof(hostAddr);
240241
SOCKET_T sshFd;
@@ -266,7 +267,7 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
266267

267268
((func_args*)args)->return_code = 0;
268269

269-
while ((ch = mygetopt(argc, argv, "?f:h:p:t:u:F:P:T:")) != -1) {
270+
while ((ch = mygetopt(argc, argv, "?f:h:p:t:u:F:P:R:T:")) != -1) {
270271
switch (ch) {
271272
case 'h':
272273
host = myoptarg;
@@ -306,6 +307,10 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
306307
password = myoptarg;
307308
break;
308309

310+
case 'R':
311+
readyFile = myoptarg;
312+
break;
313+
309314
case 'T':
310315
fwdToHost = myoptarg;
311316
break;
@@ -404,6 +409,21 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
404409
if (ret != WS_SUCCESS)
405410
err_sys("Couldn't connect SFTP");
406411

412+
if (readyFile != NULL) {
413+
#ifndef NO_FILESYSTEM
414+
WFILE* f = NULL;
415+
ret = WFOPEN(NULL, &f, readyFile, "w");
416+
if (f != NULL && ret == 0) {
417+
char portStr[10];
418+
int l = WSNPRINTF(portStr, sizeof(portStr), "%d\n", (int)port);
419+
WFWRITE(NULL, portStr, MIN((size_t)l, sizeof(portStr)), 1, f);
420+
WFCLOSE(NULL, f);
421+
}
422+
#else
423+
err_sys("cannot create readyFile with no file system.\r\n");
424+
#endif
425+
}
426+
407427
FD_ZERO(&templateFds);
408428
FD_SET(sshFd, &templateFds);
409429
FD_SET(listenFd, &templateFds);

scripts/fwd.test

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env sh
2+
3+
# Prerequisite checking
4+
5+
if [ ! -x "$(which expect)" ]
6+
then
7+
echo "skipping: missing expect"
8+
exit 77
9+
fi
10+
11+
if [ ! -x ./scripts/fwd.test.expect ]
12+
then
13+
echo "fail: missing expect script"
14+
exit 1
15+
fi
16+
17+
if [ ! -x "$(which nc)" ]
18+
then
19+
echo "skipping: missing netcat"
20+
exit 77
21+
fi
22+
23+
## libtool can leave behind a script that runs the actual executable.
24+
if [ ! -x ./examples/echoserver/echoserver ] || \
25+
./examples/echoserver/echoserver "-?" 2>&1 | grep -q "does not exist"
26+
then
27+
echo "fail: missing echoserver"
28+
exit 1
29+
fi
30+
31+
## libtool can leave behind a script that runs the actual executable.
32+
if [ ! -x ./examples/portfwd/portfwd ] || \
33+
./examples/portfwd/portfwd "-?" 2>&1 | grep -q "does not exist"
34+
then
35+
echo "skipping: missing forwarding"
36+
exit 77
37+
fi
38+
39+
## test for nonblocking only
40+
if ./examples/client/client "-?" 2>&1 | grep WOLFSSH_TEST_BLOCK >/dev/null 2>&1
41+
then
42+
echo "skipping: non-blocking test"
43+
exit 77
44+
fi
45+
46+
47+
# Run the expect script
48+
49+
./scripts/fwd.test.expect

scripts/fwd.test.expect

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#!/usr/bin/env expect -f
2+
#
3+
# SSH Tunnel Test Script
4+
#
5+
# Tests an SSH tunnel using wolfSSH and netcat (nc).
6+
#
7+
# Architecture:
8+
#
9+
# [nc client] --plain--> :12345 [wolfssh client]
10+
# |
11+
# SSH
12+
# |
13+
# [wolfssh server] :ephem --plain--> :11111 [nc server]
14+
#
15+
# The nc client sends each line of a Lorem Ipsum paragraph through the tunnel
16+
# to the nc server one at a time. The server echoes each line back. Both sides
17+
# verify receipt of every line.
18+
#
19+
# Ports used:
20+
# 11111 - nc server (plain text backend)
21+
# 12345 - wolfssh client listener (plain text, nc connects here)
22+
# 22222 - wolfSSH rendezvous (SSH, internal use only)
23+
#
24+
# Requirements: nc (netcat), expect
25+
26+
set timeout 30
27+
28+
set lorem_lines {
29+
{Lorem ipsum dolor sit amet, consectetur adipiscing elit,}
30+
{sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.}
31+
{Ut enim ad minim veniam, quis nostrud exercitation ullamco}
32+
{laboris nisi ut aliquip ex ea commodo consequat.}
33+
{Duis aute irure dolor in reprehenderit in voluptate velit esse}
34+
{cillum dolore eu fugat nulla pariatur.}
35+
{Excepteur sint occaecat cupidatat non proident, sunt in culpa qui}
36+
{officia deserunt mollit anim id est laborum.}
37+
}
38+
39+
# PIDs for cleanup
40+
set nc_server_pid ""
41+
set wolfssh_srv_pid ""
42+
set wolfssh_clt_pid ""
43+
set nc_client_pid ""
44+
45+
# --- Cleanup -----------------------------------------------------------------
46+
proc cleanup {} {
47+
global nc_client_pid wolfssh_clt_pid wolfssh_srv_pid nc_server_pid
48+
49+
puts "\n--- Cleaning up ---"
50+
foreach pid [list $nc_client_pid $wolfssh_clt_pid $wolfssh_srv_pid $nc_server_pid] {
51+
if {$pid ne ""} {
52+
catch {exec kill $pid}
53+
}
54+
}
55+
puts "Done."
56+
}
57+
58+
# --- Fail helper -------------------------------------------------------------
59+
proc fail {msg} {
60+
puts "\n\[FAIL\] $msg"
61+
cleanup
62+
exit 1
63+
}
64+
65+
# --- Check prerequisites -----------------------------------------------------
66+
foreach tool {nc} {
67+
if {[catch {exec which $tool}]} {
68+
puts "ERROR: '$tool' not found in PATH"
69+
exit 1
70+
}
71+
}
72+
73+
# --- [1] Start nc server -----------------------------------------------------
74+
puts "\n\[1\] Starting nc server: nc -l 11111"
75+
spawn nc -l 11111
76+
set nc_server_id $spawn_id
77+
set nc_server_pid [exp_pid]
78+
puts " PID $nc_server_pid — waiting for a connection..."
79+
80+
# --- [2] Start wolfssh server ------------------------------------------------
81+
puts "\n\[2\] Starting wolfssh server..."
82+
spawn ./examples/echoserver/echoserver -1 -f
83+
set wolfssh_srv_id $spawn_id
84+
set wolfssh_srv_pid [exp_pid]
85+
puts " PID $wolfssh_srv_pid — waiting for a connection..."
86+
87+
# --- [3] Start wolfssh client ------------------------------------------------
88+
puts "\n\[3\] Starting wolfssh client (plain:12345 -> 11111)..."
89+
spawn ./examples/portfwd/portfwd -u jill -P upthehill -f 12345 -t 11111
90+
set wolfssh_clt_id $spawn_id
91+
set wolfssh_clt_pid [exp_pid]
92+
93+
expect {
94+
-i $wolfssh_clt_id
95+
-re {sampled} {
96+
puts " wolfssh client ready (PID $wolfssh_clt_pid)."
97+
}
98+
-re {(?i)(error|fatal)} {
99+
fail "wolfssh client failed to start"
100+
}
101+
timeout {
102+
fail "Timed out waiting for wolfssh client to start"
103+
}
104+
}
105+
106+
# Brief pause to let the wolfssh tunnels fully bind their listening ports
107+
sleep 1
108+
109+
# --- [4] Start nc client -----------------------------------------------------
110+
puts "\n\[4\] Starting nc client: nc localhost 12345"
111+
spawn nc localhost 12345
112+
set nc_client_id $spawn_id
113+
set nc_client_pid [exp_pid]
114+
puts " PID $nc_client_pid"
115+
116+
# Allow the TCP handshake and SSH negotiation to complete
117+
sleep 1
118+
119+
# --- [5] Send each line, verify receipt, echo back, verify echo --------------
120+
set n [llength $lorem_lines]
121+
set i 0
122+
foreach line $lorem_lines {
123+
incr i
124+
puts "\n\[5.$i/$n\] Client sending: \"$line\""
125+
send -i $nc_client_id "$line\n"
126+
127+
expect {
128+
-i $nc_server_id
129+
-ex $line {
130+
puts " \[PASS\] Server received line $i."
131+
}
132+
timeout {
133+
fail "Server did not receive line $i within ${timeout}s"
134+
}
135+
}
136+
137+
send -i $nc_server_id "$line\n"
138+
139+
expect {
140+
-i $nc_client_id
141+
-ex $line {
142+
puts " \[PASS\] Client received echo of line $i."
143+
}
144+
timeout {
145+
fail "Client did not receive echo of line $i within ${timeout}s"
146+
}
147+
}
148+
}
149+
150+
# --- Done --------------------------------------------------------------------
151+
puts "\n=== TEST PASSED ===\n"
152+
153+
cleanup
154+
exit 0

scripts/include.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ if BUILD_SCP
1111
dist_noinst_SCRIPTS+= scripts/scp.test
1212
endif
1313

14-
dist_noinst_SCRIPTS+= scripts/external.test
14+
dist_noinst_SCRIPTS+= scripts/external.test scripts/fwd.test

0 commit comments

Comments
 (0)