Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/wolfsshd/test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ To run all tests do:
```
$ cd apps/wolfsshd/test/

$ sudo ./run_all_sshd_tests.sh
$ sudo ./run_all_sshd_tests.sh <user>
Running all wolfSSHd tests
Starting up local wolfSSHd for tests on 127.0.0.1:22222
SSHD running on PID 7979
Expand Down
3 changes: 2 additions & 1 deletion apps/wolfsshd/test/run_all_sshd_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ fi
# these tests require setting up an sshd
if [ "$USING_LOCAL_HOST" == 1 ]; then
run_test "sshd_forcedcmd_test.sh"
run_test "sshd_window_full_test.sh"
else
printf "Skipping tests that need to setup local SSHD\n"
SKIPPED=$((SKIPPED+1))
SKIPPED=$((SKIPPED+2))
fi

# these tests run with X509 sshd-config loaded
Expand Down
58 changes: 58 additions & 0 deletions apps/wolfsshd/test/sshd_window_full_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash

# sshd local test

if [ -z "$1" ] || [ -z "$2" ]; then
echo "expecting host and port as arguments"
echo "./sshd_exec_test.sh 127.0.0.1 22222"
exit 1
fi

PWD=`pwd`

if [ ! -z "$3" ]; then
USER="$3"
else
USER=`whoami`
fi
TEST_PORT="$2"
TEST_HOST="$1"
source ./start_sshd.sh
cat <<EOF > sshd_config_test_window
Port $TEST_PORT
Protocol 2
LoginGraceTime 600
PermitRootLogin yes
PasswordAuthentication yes
PermitEmptyPasswords no
UsePrivilegeSeparation no
UseDNS no
HostKey $PWD/../../../keys/server-key.pem
AuthorizedKeysFile $PWD/authorized_keys_test
EOF

start_wolfsshd "sshd_config_test_window"
cd ../../..

TEST_CLIENT="./examples/client/client"
TEST_SFTP="./examples/sftpclient/wolfsftp"
PRIVATE_KEY="./keys/hansel-key-ecc.der"
PUBLIC_KEY="./keys/hansel-key-ecc.pub"

head -c 1G /dev/urandom > random-test.txt

PWD=`pwd`
$TEST_CLIENT -c "cd $PWD; $TEST_CLIENT -c \"cat $PWD/random-test.txt\" -u $USER -i $PRIVATE_KEY -j $PUBLIC_KEY -h $TEST_HOST -p $TEST_PORT" -u $USER -i $PRIVATE_KEY -j $PUBLIC_KEY -h $TEST_HOST -p $TEST_PORT > random-test-result.txt

diff random-test.txt random-test-result.txt
RESULT=$?
if [ "$RESULT" != 0 ]; then
echo "cat did not pass through all expected data"
ls -la random-test.txt
ls -la random-test-result.txt
exit 1
fi

stop_wolfsshd
exit 0

87 changes: 60 additions & 27 deletions apps/wolfsshd/wolfsshd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,10 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
byte shellBuffer[EXAMPLE_BUFFER_SZ];
byte channelBuffer[EXAMPLE_BUFFER_SZ];
char* forcedCmd;
int windowFull = 0;
int windowFull = 0; /* Contains size of bytes from shellBuffer that did
* not get passed on to wolfSSH yet. This happens
* with window full errors or when rekeying. */
int wantWrite = 0;
int peerConnected = 1;
int stdoutEmpty = 0;

Expand Down Expand Up @@ -1423,7 +1426,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
maxFd = sshFd;

FD_ZERO(&writeFds);
if (windowFull) {
if (windowFull || wantWrite) {
FD_SET(sshFd, &writeFds);
}

Expand Down Expand Up @@ -1452,10 +1455,10 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
pending = 1; /* found some pending SSH data */
}

if (windowFull || pending || FD_ISSET(sshFd, &readFds)) {
if (wantWrite || windowFull || pending || FD_ISSET(sshFd, &readFds)) {
word32 lastChannel = 0;

windowFull = 0;
wantWrite = 0;
/* The following tries to read from the first channel inside
the stream. If the pending data in the socket is for
another channel, this will return an error with id
Expand All @@ -1466,24 +1469,31 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
if (cnt_r < 0) {
rc = wolfSSH_get_error(ssh);
if (rc == WS_CHAN_RXD) {
if (lastChannel == shellChannelId) {
cnt_r = wolfSSH_ChannelIdRead(ssh, shellChannelId,
if (!windowFull) { /* don't rewrite channeldBuffer if full
* of windowFull left overs */
if (lastChannel == shellChannelId) {
cnt_r = wolfSSH_ChannelIdRead(ssh, shellChannelId,
channelBuffer,
sizeof channelBuffer);
if (cnt_r <= 0)
break;
cnt_w = (int)write(childFd,
channelBuffer, cnt_r);
if (cnt_w <= 0)
break;
if (cnt_r <= 0)
break;
cnt_w = (int)write(childFd,
channelBuffer, cnt_r);
if (cnt_w <= 0)
break;
}
}
}
else if (rc == WS_CHANNEL_CLOSED) {
peerConnected = 0;
continue;
}
else if (rc == WS_WANT_WRITE) {
windowFull = 1;
wantWrite = 1;
continue;
}
else if (rc == WS_REKEYING) {
wantWrite = 1;
continue;
}
else if (rc != WS_WANT_READ) {
Expand All @@ -1495,17 +1505,22 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
/* if the window was previously full, try resending the data */
if (windowFull) {
cnt_w = wolfSSH_ChannelIdSend(ssh, shellChannelId,
shellBuffer, cnt_r);
if (cnt_w == WS_WINDOW_FULL) {
windowFull = 1;
shellBuffer, windowFull);
if (cnt_w == WS_WINDOW_FULL || cnt_w == WS_REKEYING) {
continue;
}
else if (cnt_w == WS_WANT_WRITE) {
windowFull = 1;
wantWrite = 1;
continue;
}
else {
windowFull = 0;
windowFull -= cnt_w;
if (windowFull > 0) {
WMEMMOVE(shellBuffer, shellBuffer + cnt_w, windowFull);
continue;
}
if (windowFull < 0)
windowFull = 0;
}
}

Expand All @@ -1524,12 +1539,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
if (cnt_r > 0) {
cnt_w = wolfSSH_extended_data_send(ssh, shellBuffer,
cnt_r);
if (cnt_w == WS_WINDOW_FULL) {
windowFull = 1;
if (cnt_w > 0 && cnt_w < cnt_r) { /* partial send */
windowFull = cnt_r - cnt_w;
WMEMMOVE(shellBuffer, shellBuffer + cnt_w,
windowFull);
}
else if (cnt_w == WS_WINDOW_FULL ||
cnt_w == WS_REKEYING) {
windowFull = cnt_r; /* save amount to be sent */
continue;
}
else if (cnt_w == WS_WANT_WRITE) {
windowFull = 1;
wantWrite = 1;
continue;
}
else if (cnt_w < 0)
Expand All @@ -1556,12 +1577,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
if (cnt_r > 0) {
cnt_w = wolfSSH_ChannelIdSend(ssh, shellChannelId,
shellBuffer, cnt_r);
if (cnt_w == WS_WINDOW_FULL) {
windowFull = 1;
if (cnt_w > 0 && cnt_w < cnt_r) { /* partial send */
windowFull = cnt_r - cnt_w;
WMEMMOVE(shellBuffer, shellBuffer + cnt_w,
windowFull);
}
else if (cnt_w == WS_WINDOW_FULL ||
cnt_w == WS_REKEYING) {
windowFull = cnt_r; /* save amount to be sent */
continue;
}
else if (cnt_w == WS_WANT_WRITE) {
windowFull = 1;
wantWrite = 1;
continue;
}
else if (cnt_w < 0) {
Expand All @@ -1586,12 +1613,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
if (cnt_r > 0) {
cnt_w = wolfSSH_ChannelIdSend(ssh, shellChannelId,
shellBuffer, cnt_r);
if (cnt_w == WS_WINDOW_FULL) {
windowFull = 1;
if (cnt_w > 0 && cnt_w < cnt_r) { /* partial send */
windowFull = cnt_r - cnt_w;
WMEMMOVE(shellBuffer, shellBuffer + cnt_w,
windowFull);
}
else if (cnt_w == WS_WINDOW_FULL ||
cnt_w == WS_REKEYING) {
windowFull = cnt_r;
continue;
}
else if (cnt_w == WS_WANT_WRITE) {
windowFull = 1;
wantWrite = 1;
continue;
}
else if (cnt_w < 0) {
Expand Down
2 changes: 2 additions & 0 deletions examples/client/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,10 @@ int ClientUserAuth(byte authType,
* passed in a public key file, use public key auth */
if (pubKeyLoaded == 1) {
if (authType == WOLFSSH_USERAUTH_PASSWORD) {
#ifdef WOLFSSH_DEBUG
printf("rejecting password type with %s in favor of pub key\n",
(char*)authData->username);
#endif
return WOLFSSH_USERAUTH_FAILURE;
}
}
Expand Down