wolfSSH_ChannelIdRead() has no rekey guard, so a drained channel still
reports zero mid-rekey and the drain loop calls the reply in. That send
returns WS_REKEYING before it prepares a packet, so nothing is queued.
- take the send's status instead of discarding it
- latch eofAnswered and ChildRunning on every status but WS_REKEYING, so
the reply is retried on a later pass; the KEX traffic wakes it
- a short send is left latching: it bundled the EOF and set eofTxd, so a
retry queues nothing and the loop would stall in an untimed select
waiting on a peer that has already half-closed
- same change in the Espressif copy
The drain runs between wolfSSH_worker() and the get_error() that classifies
its result, and its reads and sends latch their own status: WS_WINDOW_FULL
and WS_WANT_WRITE from a send, WS_REKEYING from a read. The ladder then read
the drain's status as the worker's, matched no arm, and ended the session
with the backlog unsent and no EOF.
- Read the error once, right after the worker returns
A chunk read out of the channel is gone from it, so breaking the drain on
a non-positive send dropped whatever the send had not taken, and the echo
back to a half-closing peer came up short.
- Keep the chunk and its offset across worker passes, and read the next
chunk only once the last one is out
- Give the drain its own buffer; the read path below it reuses
channelBuffer in the same pass
- Answer the EOF off a drained flag, since a held tail means a zero read
count no longer marks an emptied channel
Every in-tree caller of wolfSSH_worker() now recognises a peer half-close.
wolfsshd's shell loop and both echoservers need it: all three ladders end in
"else if (rc != WS_WANT_READ) break", and wolfsshd's reaches
kill(childPid, SIGKILL), so without it a client half-close kills the command
it just finished feeding.
- wolfsshd closes the child's stdin off the channel's own EOF state instead of
off a worker return of zero, which no longer happens on a half-close.
- The echoservers answer the half-close off wolfSSH_ChannelGetEof() rather
than the WS_EOF status: the flush inside wolfSSH_worker() can supersede that
status, and it is raised once. They hand back the backlog first, finish a
short send, and only send the EOF once the channel is empty. Answering is
not conditional on the shell build, where an echo session is the default.
- The SFTP loops peek before leaving, so a half-close with requests still
buffered is served rather than dropped, and they report an ordinary session
end as success.
- The clients -- examples/client, scpclient, sftpclient, apps/wolfssh -- treat
it as the graceful case instead of an error. apps/wolfssh counts it as a
finished flush as well, since one worker pass can drain the queue and
consume the peer's EOF together.
- portfwd relays it to the local socket with shutdown(SHUT_WR) so a local
reader waiting on end-of-input returns, once the backlog has genuinely been
handed over: a read cut short by a rekey leaves the half-close for a later
pass.
- The Windows half of wolfsshd does not answer with an EOF of its own. That
latches eofTxd and the child's remaining output would be refused, which is
the defect this series removes from the library.
- The mplabx port drains before tearing down, the way its SFTP read path
already did; its worker arm was unreachable for a half-close until now.
The receive mock and the packet builders sit ahead of every endpoint region
rather than inside the server half. A staged-packet IORecv and a plaintext
packet builder have nothing to do with which endpoint is built, and the tests
that follow reach for them from both halves.
- Marked WS_MAYBE_UNUSED, since either half can be the only user of any one.
- WantWriteIoSend() joins DiscardIoSend() among the send mocks.
- A relocation only: no test body changes, and the moved text is unchanged
bar the annotation. Read it with --color-moved.
ES_ERROR() passes its arguments straight to fprintf(stderr, ...), so a
message with no trailing newline runs into whatever the shell or the
test harness prints next.
- 7 sites in the echoserver, 6 in tests/auth.c, 8 in the Espressif copy
of the echoserver, which carries the same macro and takes this kind of
cross-cutting fix (e91ff50d, ab8058d7)
- the two wrapped format strings already ended with a newline
- Reply to a port-0 (dynamic) tcpip-forward with the bound port.
- Add WS_FWD_PORT_CHECK (1024) as the status/port boundary in WS_FwdCbError.
- Callback returns a WS_FwdCbError status below it, the port at or above it.
- DoGlobalRequestFwd reports the port and rejects a port-0 setup with none.
- Map a callback rejection to WS_RESOURCE_E so a no-reply request keeps the link.
- Update the echoserver reference callbacks (examples and Espressif) to
recover the OS-chosen port with getsockname() and return it under the new
convention.
- Add regress coverage for the allocated-port and rejection paths.
Issue: F-5573
Co-authored-by: John Safranek <john@wolfssl.com>
- Track open SFTP file handles per session in a fileList, returning
opaque session-scoped handle IDs instead of raw file descriptors.
- Resolve and validate client-supplied handle IDs via FindFileHandle.
- Free the handle list and close handles on error paths, including the
Windows code paths.
- Drop the old raw-fd SFTP_ValidateFileHandle/STOREHANDLE handle table
and its tests, superseded by the per-session ID lookup.
The project file for the wolfSFTP example client is specifying a
too-specific Windows target platform version. It is the only project
file specifying the version to four places. Removed it and using the
default Windows version for the version of the build tools.
Historically, some systems have used <sys/errno.h> in place of <errno.h>, but the C standard,
all the way back to C89/Ansi C, specifies that the correct name is `errno.h` -
and most modern compilers create a sys/errno.h compatibility shim sys/errno.h -
but musl-gcc does not have this compatibility shim,
reasoning that sys/errno.h is non-standard, and fails to compile:
```
$ CC=musl-gcc ./configure --enable-static --disable-shared --enable-scp --enable-sftp --enable-shell --with-wolfssl=wolfssl/install-musl
(...)
$ make
make -j17 all-am
make[1]: Entering directory '/home/hans/projects/wolfssh'
CC examples/client/common.o
CC examples/client/client.o
CC src/libwolfssh_la-ssh.lo
CC src/libwolfssh_la-internal.lo
CC src/libwolfssh_la-log.lo
CC src/libwolfssh_la-port.lo
CC src/libwolfssh_la-io.lo
CC src/libwolfssh_la-wolfscp.lo
CC src/libwolfssh_la-wolfsftp.lo
CC examples/echoserver/echoserver.o
CC src/libwolfssh_la-wolfterm.lo
CC examples/sftpclient/sftpclient.o
CC examples/scpclient/scpclient.o
In file included from examples/echoserver/echoserver.c:91:
/usr/include/x86_64-linux-musl/sys/errno.h:1:2: error: #warning redirecting incorrect #include <sys/errno.h> to <errno.h> [-Werror=cpp]
1 | #warning redirecting incorrect #include <sys/errno.h> to <errno.h>
| ^~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:1452: examples/echoserver/echoserver.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: Leaving directory '/home/hans/projects/wolfssh'
make: *** [Makefile:1020: all] Error 2
```
so, unless we need to support pre-C89 (35+ year old C) compilers,
we can just replace sys/errno.h with errno.h.
This adds a GitHub Action workflow to test the FATFS support for the wolfsftp client.
The workflow:
- Installs dependencies
- Clones and builds wolfSSL with appropriate flags
- Compiles the FATFS library
- Configures and builds wolfSSH with FATFS support
- Creates a test file
- Sets up an SSH server
- Uses the wolfsftp client to transfer a test file
- Verifies the file in the FATFS image
Co-Authored-By: andrew@wolfssl.com <andrew@wolfssl.com>
Co-Authored-By: andrew@wolfssl.com <andrew@wolfssl.com>