mirror of https://github.com/wolfSSL/wolfssh.git
echoserver: bind sftp and scp as the library does
The subsystem and exec callbacks pick out the same commands the accept state machine does: sftp matched whole, by length and bytes, and scp on the three-byte prefix ChannelCommandIsScp() takes. - sftp with an embedded NUL is refused, rather than granted and then dropped by wolfSSH_SFTP_accept() - a transfer is granted only on the head channel the accept APIs serve, so a request on a later channel is refused rather than answered successpull/1254/head
parent
eef5346f7f
commit
ecb79ea4e3
|
|
@ -768,6 +768,19 @@ static int SessionInUse(const thread_ctx_t* threadCtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP)
|
||||||
|
/* wolfSSH_SFTP_accept() and wolfSSH_SCP_accept() work from the head of the
|
||||||
|
* channel list, so a transfer granted on any other channel answers the peer
|
||||||
|
* success and then runs against the wrong one. The shell has no such limit:
|
||||||
|
* its callback keeps the channel id. */
|
||||||
|
static int TransferChannel(const thread_ctx_t* threadCtx,
|
||||||
|
WOLFSSH_CHANNEL* channel)
|
||||||
|
{
|
||||||
|
return channel == wolfSSH_ChannelNext(threadCtx->ssh, NULL);
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSH_SFTP || WOLFSSH_SCP */
|
||||||
|
|
||||||
|
|
||||||
/* Registered in every build, in both modes: with no shell the echoserver
|
/* Registered in every build, in both modes: with no shell the echoserver
|
||||||
* still has to take the channel to mark it connected, so ssh_worker() will
|
* still has to take the channel to mark it connected, so ssh_worker() will
|
||||||
* echo on it. Returns WS_SUCCESS to accept the request, 1 to reject it. */
|
* echo on it. Returns WS_SUCCESS to accept the request, 1 to reject it. */
|
||||||
|
|
@ -919,9 +932,15 @@ static int wsSubsysStartCb(WOLFSSH_CHANNEL* channel, void* vCtx)
|
||||||
type = wolfSSH_ChannelGetSessionType(channel);
|
type = wolfSSH_ChannelGetSessionType(channel);
|
||||||
|
|
||||||
/* A truncated subsystem string leaves the command NULL, and this
|
/* A truncated subsystem string leaves the command NULL, and this
|
||||||
* runs before anything else has looked at it. */
|
* runs before anything else has looked at it. The name matches
|
||||||
|
* whole, length and bytes, as wolfSSH_SFTP_accept() asks: granting
|
||||||
|
* sftp with an embedded NUL answers success on a session it then
|
||||||
|
* refuses. */
|
||||||
if (type == WOLFSSH_SESSION_SUBSYSTEM && cmd != NULL
|
if (type == WOLFSSH_SESSION_SUBSYSTEM && cmd != NULL
|
||||||
&& WSTRCMP(cmd, "sftp") == 0) {
|
&& wolfSSH_ChannelGetSessionCommandSz(channel)
|
||||||
|
== (word32)WSTRLEN("sftp")
|
||||||
|
&& WSTRCMP(cmd, "sftp") == 0
|
||||||
|
&& TransferChannel(threadCtx, channel)) {
|
||||||
threadCtx->doSftp = 1;
|
threadCtx->doSftp = 1;
|
||||||
rej = WS_SUCCESS;
|
rej = WS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -946,9 +965,14 @@ static int wsExecStartCb(WOLFSSH_CHANNEL* channel, void* vCtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSH_SCP
|
#ifdef WOLFSSH_SCP
|
||||||
if (cmd != NULL && WSTRNCMP(cmd, "scp ", 4) == 0) {
|
/* The prefix ChannelCommandIsScp() matches, so both modes agree. */
|
||||||
((thread_ctx_t*)vCtx)->doScp = 1;
|
if (cmd != NULL && WSTRNCMP(cmd, "scp", 3) == 0) {
|
||||||
rej = WS_SUCCESS;
|
/* An scp command the transfer cannot be run for is refused
|
||||||
|
* rather than served as a session. */
|
||||||
|
if (TransferChannel((thread_ctx_t*)vCtx, channel)) {
|
||||||
|
((thread_ctx_t*)vCtx)->doScp = 1;
|
||||||
|
rej = WS_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* WOLFSSH_SCP */
|
#endif /* WOLFSSH_SCP */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue