Skip to content

Commit

Permalink
Merge pull request #719 from JacobBarthelmeh/cat
Browse files Browse the repository at this point in the history
cat of large file with ssh shell
  • Loading branch information
ejohnstown authored Aug 9, 2024
2 parents 40aabc2 + 2fbe010 commit 468a205
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 29 deletions.
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

0 comments on commit 468a205

Please sign in to comment.