Skip to content

Commit b8b72b6

Browse files
Merge pull request #783 from LinuxJedi/scp-eagain
Fix SCP server side
2 parents 7e9f1ae + a9c7ebc commit b8b72b6

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed

apps/wolfsshd/test/run_all_sshd_tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ test_cases=(
88
"sshd_term_size_test.sh"
99
"sshd_large_sftp_test.sh"
1010
"sshd_bad_sftp_test.sh"
11+
"sshd_scp_fail.sh"
1112
"sshd_term_close_test.sh"
1213
"ssh_kex_algos.sh"
1314
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/sh
2+
3+
# sshd local test
4+
5+
PWD=`pwd`
6+
cd ../../..
7+
8+
TEST_SCP_CLIENT="./examples/scpclient/wolfscp"
9+
USER=`whoami`
10+
PRIVATE_KEY="./keys/hansel-key-ecc.der"
11+
PUBLIC_KEY="./keys/hansel-key-ecc.pub"
12+
13+
if [ -z "$1" ] || [ -z "$2" ]; then
14+
echo "expecting host and port as arguments"
15+
echo "./sshd_exec_test.sh 127.0.0.1 22222"
16+
exit 1
17+
fi
18+
19+
mkdir test-$$
20+
21+
OUTDIR="`pwd`/test-$$"
22+
23+
dd if=/dev/random of=$OUTDIR/test.dat bs=1024 count=512
24+
25+
echo "$TEST_SCP_CLIENT -u $USER -i $PRIVATE_KEY -j $PUBLIC_KEY -S$OUTDIR/test.dat:. -H $1 -p $2"
26+
$TEST_SCP_CLIENT -u $USER -i $PRIVATE_KEY -j $PUBLIC_KEY -S$OUTDIR/test.dat:. -H $1 -p $2
27+
28+
RESULT=$?
29+
if [ "$RESULT" != "0" ]; then
30+
echo "Expecting to pass transfer"
31+
exit 1
32+
fi
33+
34+
MD5SOURCE=`md5sum $OUTDIR/test.dat | awk '{ print $1 }'`
35+
MD5DEST=`md5sum test.dat | awk '{ print $1 }'`
36+
37+
if [ "$MD5SOURCE" != "$MD5DEST" ]; then
38+
echo "Files do not match $MD5SOURCE != $MD5DEST"
39+
exit 1
40+
fi
41+
42+
rm -rf test-$$
43+
rm testout.dat
44+
45+
cd $PWD
46+
exit 0
47+

examples/scpclient/scpclient.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ THREAD_RETURN WOLFSSH_THREAD scp_client(void* args)
344344
wc_ecc_fp_free(); /* free per thread cache */
345345
#endif
346346

347-
if (ret != WS_SUCCESS)
347+
if ((ret != WS_SUCCESS) && (ret != WS_CHANNEL_CLOSED))
348348
((func_args*)args)->return_code = 1;
349349
return 0;
350350
}

src/wolfscp.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ int DoScpSource(WOLFSSH* ssh)
602602
ssh->scpBufferedSz);
603603
if (ret == WS_WINDOW_FULL || ret == WS_REKEYING) {
604604
ret = wolfSSH_worker(ssh, NULL);
605-
if (ret == WS_SUCCESS)
605+
if (ret == WS_SUCCESS || ssh->error == WS_WANT_READ)
606606
continue;
607607
}
608608
if (ret == WS_EXTDATA) {
@@ -616,8 +616,10 @@ int DoScpSource(WOLFSSH* ssh)
616616
* open file descriptor before exit */
617617
ScpSendCtx* sendCtx = NULL;
618618
sendCtx = (ScpSendCtx*)wolfSSH_GetScpSendCtx(ssh);
619-
if (sendCtx != NULL)
619+
if (sendCtx != NULL) {
620620
WFCLOSE(ssh->fs, sendCtx->fp);
621+
sendCtx->fp = NULL;
622+
}
621623
#endif
622624
WLOG(WS_LOG_ERROR, scpError, "failed to send file", ret);
623625
break;
@@ -1181,6 +1183,7 @@ static int ParseBasePathHelper(WOLFSSH* ssh, int cmdSz)
11811183

11821184
if (ScpPushDir(ssh->fs, &ctx, ssh->scpBasePath, ssh->ctx->heap) != WS_SUCCESS) {
11831185
WLOG(WS_LOG_DEBUG, "scp : issue opening base dir");
1186+
ssh->error = WS_INVALID_PATH_E;
11841187
ret = WS_FATAL_ERROR;
11851188
}
11861189
else {
@@ -2021,6 +2024,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
20212024
WLOG(WS_LOG_ERROR, scpError, "scp receive callback unable "
20222025
"to write requested size to file", bytes);
20232026
WFCLOSE(ssh->fs, fp);
2027+
fp = NULL;
20242028
ret = WS_SCP_ABORT;
20252029
} else {
20262030
#ifdef WOLFSCP_FLUSH
@@ -2047,6 +2051,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
20472051
flush_bytes = 0;
20482052
#endif
20492053
WFCLOSE(ssh->fs, fp);
2054+
fp = NULL;
20502055
}
20512056

20522057
/* set timestamp info */
@@ -2587,6 +2592,7 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
25872592
if ((sendCtx->fp != NULL) &&
25882593
((ret < 0) || (*totalFileSz == (word32)ret))) {
25892594
WFCLOSE(ssh->fs, sendCtx->fp);
2595+
sendCtx->fp = NULL;
25902596
}
25912597
}
25922598

@@ -2758,6 +2764,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
27582764
if ((sendCtx != NULL) && (sendCtx->fp != NULL) &&
27592765
((ret < 0) || (*totalFileSz == (word32)ret))) {
27602766
WFCLOSE(ssh->fs, sendCtx->fp);
2767+
sendCtx->fp = NULL;
27612768
}
27622769

27632770
break;
@@ -2840,13 +2847,20 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
28402847
break;
28412848
}
28422849

2850+
if (sendCtx->fp == NULL) {
2851+
WLOG(WS_LOG_ERROR, "scp: file has been closed, abort");
2852+
ret = WS_SCP_ABORT;
2853+
break;
2854+
}
2855+
28432856
ret = (word32)WFREAD(ssh->fs, buf, 1, bufSz, sendCtx->fp);
28442857
if (ret == 0) { /* handle case of EOF */
28452858
ret = WS_EOF;
28462859
}
28472860

28482861
if ((ret <= 0) || (fileOffset + ret == *totalFileSz)) {
28492862
WFCLOSE(ssh->fs, sendCtx->fp);
2863+
sendCtx->fp = NULL;
28502864
}
28512865

28522866
break;

0 commit comments

Comments
 (0)