Skip to content

Commit 567efa5

Browse files
Merge pull request #874 from ejohnstown/rxd-fix
RxD Fix
2 parents a2e6556 + 2c6c0c7 commit 567efa5

File tree

7 files changed

+255
-11
lines changed

7 files changed

+255
-11
lines changed

examples/echoserver/echoserver.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,22 +383,24 @@ static int wolfSSH_AGENT_DefaultActions(WS_AgentCbAction action, void* vCtx)
383383
if (action == WOLFSSH_AGENT_LOCAL_SETUP) {
384384
struct sockaddr_un* name = &ctx->name;
385385
size_t size;
386+
int envSet = 0, nameBound = 0;
386387

387388
WMEMSET(name, 0, sizeof(struct sockaddr_un));
388389
ctx->pid = getpid();
389390
name->sun_family = AF_LOCAL;
390391

391392
ret = snprintf(name->sun_path, sizeof(name->sun_path),
392393
"/tmp/wolfserver.%d", ctx->pid);
394+
if (ret >= 0) {
395+
name->sun_path[sizeof(name->sun_path) - 1] = '\0';
396+
size = WSTRLEN(name->sun_path);
397+
ret = (size < WSTRLEN("/tmp/wolfserver."));
398+
}
393399

394400
if (ret == 0) {
395-
name->sun_path[sizeof(name->sun_path) - 1] = '\0';
396-
size = WSTRLEN(name->sun_path) +
397-
offsetof(struct sockaddr_un, sun_path);
401+
size += offsetof(struct sockaddr_un, sun_path);
398402
ctx->listenFd = socket(AF_UNIX, SOCK_STREAM, 0);
399-
if (ctx->listenFd == -1) {
400-
ret = -1;
401-
}
403+
ret = (ctx->listenFd == -1) ? -1 : 0;
402404
}
403405

404406
if (ret == 0) {
@@ -407,17 +409,29 @@ static int wolfSSH_AGENT_DefaultActions(WS_AgentCbAction action, void* vCtx)
407409
}
408410

409411
if (ret == 0) {
412+
nameBound = 1;
410413
ret = setenv(EnvNameAuthPort, name->sun_path, 1);
411414
}
412415

413416
if (ret == 0) {
417+
envSet = 1;
414418
ret = listen(ctx->listenFd, 5);
415419
}
416420

417421
if (ret == 0) {
418422
ctx->state = AGENT_STATE_LISTEN;
419423
}
420424
else {
425+
if (nameBound) {
426+
unlink(ctx->name.sun_path);
427+
}
428+
if (envSet) {
429+
unsetenv(EnvNameAuthPort);
430+
}
431+
if (ctx->listenFd >= 0) {
432+
close(ctx->listenFd);
433+
ctx->listenFd = -1;
434+
}
421435
ret = WS_AGENT_SETUP_E;
422436
}
423437
}
@@ -1510,7 +1524,7 @@ static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)
15101524
if (!threadCtx->nonBlock) {
15111525
ret = wolfSSH_accept(threadCtx->ssh);
15121526
if (wolfSSH_get_error(threadCtx->ssh) == WS_AUTH_PENDING) {
1513-
printf("Auth pending error, use -N for non blocking\n");
1527+
printf("Auth pending error, use -N for non-blocking\n");
15141528
printf("Trying to close down the connection\n");
15151529
}
15161530
}
@@ -2749,7 +2763,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
27492763

27502764
#ifdef WOLFSSH_TEST_BLOCK
27512765
if (!nonBlock) {
2752-
ES_ERROR("Use -N when testing forced non blocking");
2766+
ES_ERROR("Use -N when testing forced non-blocking\n");
27532767
}
27542768
#endif
27552769

examples/portfwd/portfwd.c

Lines changed: 25 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,25 @@ 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;
419+
420+
l = WSNPRINTF(portStr, sizeof(portStr), "%d\n", (int)fwdFromPort);
421+
if (l > 0) {
422+
WFWRITE(NULL, portStr, MIN((size_t)l, sizeof(portStr)), 1, f);
423+
}
424+
WFCLOSE(NULL, f);
425+
}
426+
#else
427+
err_sys("cannot create readyFile with no file system.\r\n");
428+
#endif
429+
}
430+
407431
FD_ZERO(&templateFds);
408432
FD_SET(sshFd, &templateFds);
409433
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 "$(command -v 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 "$(command -v 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 -S 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 fugiat 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 {[auto_execok $tool] eq ""} {
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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ 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
15+
EXTRA_DIST += scripts/fwd.test.expect

src/agent.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ static int PostLock(WOLFSSH_AGENT_CTX* agent,
374374
word32 ppSz;
375375

376376
WLOG(WS_LOG_AGENT, "Posting lock to agent %p", agent);
377+
WOLFSSH_UNUSED(agent);
377378

378379
ppSz = sizeof(pp) - 1;
379380
if (passphraseSz < ppSz)
@@ -395,6 +396,7 @@ static int PostUnlock(WOLFSSH_AGENT_CTX* agent,
395396
word32 ppSz;
396397

397398
WLOG(WS_LOG_AGENT, "Posting unlock to agent %p", agent);
399+
WOLFSSH_UNUSED(agent);
398400

399401
ppSz = sizeof(pp) - 1;
400402
if (passphraseSz < ppSz)

src/ssh.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2607,7 +2607,7 @@ int wolfSSH_worker(WOLFSSH* ssh, word32* channelId)
26072607
}
26082608
#endif /* WOLFSSH_TEST_BLOCK */
26092609

2610-
if (ret == WS_SUCCESS) {
2610+
if (ret == WS_SUCCESS || ret == WS_CHAN_RXD) {
26112611
if (channelId != NULL) {
26122612
*channelId = ssh->lastRxId;
26132613
}

0 commit comments

Comments
 (0)