Skip to content

Commit

Permalink
Merge pull request #597 from JacobBarthelmeh/sftp
Browse files Browse the repository at this point in the history
  • Loading branch information
ejohnstown authored Sep 30, 2023
2 parents 7578a7d + 5780570 commit a84df10
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 74 deletions.
5 changes: 5 additions & 0 deletions examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,12 @@ static void ShowUsage(void)
printf(" -j <filename> filename for the user's public key\n");
printf(" -x exit after successful connection without doing\n"
" read/write\n");
#ifdef WOLFSSH_TEST_BLOCK
printf("-N non-blocking sockets required when compiled with "
"WOLFSSH_TEST_BLOCK\n");
#else
printf(" -N use non-blocking sockets\n");
#endif
#ifdef WOLFSSH_TERM
printf(" -t use psuedo terminal\n");
#endif
Expand Down
61 changes: 43 additions & 18 deletions examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,24 +1161,47 @@ static int sftp_worker(thread_ctx_t* threadCtx)
s = (WS_SOCKET_T)wolfSSH_get_fd(ssh);

do {
if (wolfSSH_SFTP_PendingSend(ssh)) {
/* Yes, process the SFTP data. */
ret = wolfSSH_SFTP_read(ssh);
error = wolfSSH_get_error(ssh);
timeout = (ret == WS_REKEYING) ?
TEST_SFTP_TIMEOUT : TEST_SFTP_TIMEOUT_NONE;
if (error == WS_WANT_READ || error == WS_WANT_WRITE ||
error == WS_CHAN_RXD || error == WS_REKEYING ||
error == WS_WINDOW_FULL)
ret = error;
if (error == WS_WANT_WRITE && wolfSSH_SFTP_PendingSend(ssh)) {
continue; /* no need to spend time attempting to pull data
* if there is still pending sends */
}
if (error == WS_EOF) {
break;
}
}

selected = tcp_select(s, timeout);
if (selected == WS_SELECT_ERROR_READY) {
break;
}

if (selected == WS_SELECT_RECV_READY) {
if (ret == WS_WANT_READ || ret == WS_WANT_WRITE ||
selected == WS_SELECT_RECV_READY) {
ret = wolfSSH_worker(ssh, NULL);
error = wolfSSH_get_error(ssh);
if (ret == WS_REKEYING) {
/* In a rekey, keep turning the crank. */
/* In a rekey, keeping turning the crank. */
timeout = TEST_SFTP_TIMEOUT;
continue;
}
if (error == WS_WANT_READ) {
/* If would block, keep turning the crank. */

if (error == WS_WANT_READ || error == WS_WANT_WRITE ||
error == WS_WINDOW_FULL) {
timeout = TEST_SFTP_TIMEOUT;
ret = error;
continue;
}

if (error == WS_EOF) {
break;
}
Expand All @@ -1188,39 +1211,41 @@ static int sftp_worker(thread_ctx_t* threadCtx)
}
}

if (wolfSSH_SFTP_PendingSend(ssh)) {
/* Yes, process the SFTP data. */
ret = wolfSSH_SFTP_read(ssh);
timeout = (ret == WS_REKEYING) ?
TEST_SFTP_TIMEOUT : TEST_SFTP_TIMEOUT_NONE;
continue;
}

ret = wolfSSH_stream_peek(ssh, peek_buf, sizeof(peek_buf));
if (ret > 0) {
/* Yes, process the SFTP data. */
ret = wolfSSH_SFTP_read(ssh);
error = wolfSSH_get_error(ssh);
timeout = (ret == WS_REKEYING) ?
TEST_SFTP_TIMEOUT : TEST_SFTP_TIMEOUT_NONE;
if (error == WS_WANT_READ || error == WS_WANT_WRITE ||
error == WS_CHAN_RXD || error == WS_REKEYING ||
error == WS_WINDOW_FULL)
ret = error;
if (error == WS_EOF)
break;
continue;
}
else if (ret == WS_REKEYING) {
timeout = TEST_SFTP_TIMEOUT;
continue;
}
else if (ret < 0) {
error = wolfSSH_get_error(ssh);
if (error == WS_EOF)
break;
}

/* Old check for EOF here */
{
if (ret == WS_FATAL_ERROR && error == 0) {
WOLFSSH_CHANNEL* channel =
wolfSSH_ChannelNext(ssh, NULL);
wolfSSH_ChannelNext(ssh, NULL);
if (channel && wolfSSH_ChannelGetEof(channel)) {
ret = WS_EOF;
ret = 0;
break;
}
}

timeout = TEST_SFTP_TIMEOUT;
} while (1);
} while (ret != WS_FATAL_ERROR);

return ret;
}
Expand Down
54 changes: 40 additions & 14 deletions examples/sftpclient/sftpclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,18 +503,19 @@ static int doCmds(func_args* args)
}

do {
ret = wolfSSH_SFTP_Get(ssh, pt, to, resume, &myStatusCb);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
}

ret = wolfSSH_SFTP_Get(ssh, pt, to, resume, &myStatusCb);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
} while (ret == WS_WANT_READ || ret == WS_WANT_WRITE ||
ret == WS_CHAN_RXD);
ret == WS_CHAN_RXD || ret == WS_REKEYING);

#ifndef WOLFSSH_NO_TIMESTAMP
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
Expand Down Expand Up @@ -607,11 +608,19 @@ static int doCmds(func_args* args)
}

do {
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
}

ret = wolfSSH_SFTP_Put(ssh, pt, to, resume, &myStatusCb);
err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
err == WS_CHAN_RXD || err == WS_REKEYING) &&
ret == WS_FATAL_ERROR);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
} while (ret == WS_WANT_READ || ret == WS_WANT_WRITE ||
ret == WS_CHAN_RXD || ret == WS_REKEYING);

#ifndef WOLFSSH_NO_TIMESTAMP
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
Expand Down Expand Up @@ -921,10 +930,19 @@ static int doCmds(func_args* args)
}

do {
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
}

ret = wolfSSH_SFTP_Rename(ssh, pt, to);
err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
&& ret != WS_SUCCESS);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
} while (ret == WS_WANT_READ || ret == WS_WANT_WRITE ||
ret == WS_CHAN_RXD || ret == WS_REKEYING);
if (ret != WS_SUCCESS) {
if (SFTP_FPUTS(args, "Error with rename\n") < 0) {
err_msg("fputs error");
Expand All @@ -942,10 +960,18 @@ static int doCmds(func_args* args)
WS_SFTPNAME* current;

do {
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(ssh);
}
}

current = wolfSSH_SFTP_LS(ssh, workingDir);
err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
&& current == NULL && err != WS_SUCCESS);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
err == WS_REKEYING) &&
(current == NULL && err != WS_SUCCESS));

if (WSTRNSTR(msg, "-s", MAX_CMD_SZ) != NULL) {
char tmpStr[WOLFSSH_MAX_FILENAME];
Expand Down
11 changes: 10 additions & 1 deletion scripts/external.test
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ if test -n "$WOLFSSH_EXTERNAL_TEST"; then
echo "WOLFSSH_EXTERNAL_TEST set, running test..."
else
echo "WOLFSSH_EXTERNAL_TEST NOT set, won't run"
exit 0
exit 77
fi

# test for nonblocking only
./examples/client/client -h | grep WOLFSSH_TEST_BLOCK
if [ $? -eq 0 ]
then
echo "macro NO_WOLFSSH_CLIENT was used"
echo "skipping for now"
exit 77
fi

do_cleanup() {
Expand Down
10 changes: 9 additions & 1 deletion scripts/get-put.test
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@ then
then
echo "macro NO_WOLFSSH_CLIENT was used"
echo "skipping test"
exit 0
exit 77
else
echo "wolfSFTP client not compiled in or not working"
exit 1
fi
fi

# test for nonblocking only
./examples/client/client -h | grep WOLFSSH_TEST_BLOCK
if [ $? -eq 0 ]
then
echo "macro WOLFSSH_TEST_BLOCK was used"
exit 77
fi

if test ! -x ./examples/echoserver/echoserver
then
echo "This test requires the wolfSSH echoserver."
Expand Down
9 changes: 9 additions & 0 deletions scripts/scp.test
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ counter=0

[ ! -x ./examples/scpclient/wolfscp ] && echo -e "\n\nwolfscp client doesn't exist" && exit 1

# test for nonblocking only
./examples/client/client -h | grep WOLFSSH_TEST_BLOCK
if [ $? -eq 0 ]
then
echo "macro NO_WOLFSSH_CLIENT was used"
echo "skipping for now"
exit 77
fi

create_port() {
while [ ! -s "$ready_file" ] && [ "$counter" -lt 20 ]; do
echo -e "waiting for ready file..."
Expand Down
61 changes: 37 additions & 24 deletions scripts/sftp.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ no_pid=-1
server_pid=$no_pid
ready_file=`pwd`/wolfssh_sftp_ready$$
counter=0
nonblockingOnly=0

[ ! -x ./examples/sftpclient/wolfsftp ] && echo -e "\n\nwolfSFTP client doesn't exist" && exit 1

Expand All @@ -15,7 +16,15 @@ if [ $? -eq 0 ]
then
echo "macro NO_WOLFSSH_CLIENT was used"
echo "skipping test"
exit 0
exit 77
fi

# test for nonblocking only
./examples/client/client -h | grep WOLFSSH_TEST_BLOCK
if [ $? -eq 0 ]
then
echo "macro NO_WOLFSSH_CLIENT was used"
nonblockingOnly=1
fi

#echo "ready file $ready_file"
Expand Down Expand Up @@ -67,17 +76,19 @@ trap do_trap INT TERM

[ ! -x ./examples/sftpclient/wolfsftp ] && echo -e "\n\nClient doesn't exist" && exit 1

echo "Test basic connection"
./examples/echoserver/echoserver -1 -R $ready_file &
server_pid=$!
create_port
echo "exit" | ./examples/sftpclient/wolfsftp -u jill -P upthehill -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nfailed to connect"
do_cleanup
exit 1
if [ $nonblockingOnly = 0 ]; then
echo "Test basic connection"
./examples/echoserver/echoserver -1 -R $ready_file &
server_pid=$!
create_port
echo "exit" | ./examples/sftpclient/wolfsftp -u jill -P upthehill -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nfailed to connect"
do_cleanup
exit 1
fi
fi

# Test non blocking connection
Expand All @@ -95,18 +106,20 @@ if [ $RESULT -ne 0 ]; then
fi

# Test of setting directory
echo "Test of setting directory"
PWD=`pwd`
./examples/echoserver/echoserver -d $PWD/examples -1 -R $ready_file &
server_pid=$!
create_port
echo "exit" | ./examples/sftpclient/wolfsftp -N -u jill -P upthehill -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nfailed to connect"
do_cleanup
exit 1
if [ $nonblockingOnly = 0 ]; then
echo "Test of setting directory"
PWD=`pwd`
./examples/echoserver/echoserver -d $PWD/examples -1 -R $ready_file &
server_pid=$!
create_port
echo "exit" | ./examples/sftpclient/wolfsftp -N -u jill -P upthehill -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nfailed to connect"
do_cleanup
exit 1
fi
fi

echo -e "\nALL Tests Passed"
Expand Down
2 changes: 1 addition & 1 deletion src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

/* percent of time that forced want read/write is done */
#ifndef WOLFSSH_BLOCK_PROB
#define WOLFSSH_BLOCK_PROB 75
#define WOLFSSH_BLOCK_PROB 50
#endif
#endif

Expand Down
Loading

0 comments on commit a84df10

Please sign in to comment.