mirror of https://github.com/wolfSSL/wolfssh.git
ssh: add a channel session-granted accessor
wolfSSH_ChannelGetSessionGranted() reports whether a shell, exec or subsystem request on a channel has been answered CHANNEL_SUCCESS, so an application can tell a second request from the first without reaching into WOLFSSH_CHANNEL. - the flag is still clear for the request a session callback is answering, so a set flag is an earlier request's grant - wolfsshd's session callback reads the grant through itpull/1258/head
parent
fd4d462510
commit
dc03049a13
|
|
@ -544,7 +544,7 @@ static int SessionRequestCb(WOLFSSH_CHANNEL* channel, void* vCtx)
|
|||
/* One program start per channel, as RFC 4254 section 6.5 allows. This
|
||||
* request's grant is recorded once the callback returns, so a flag
|
||||
* already set is an earlier request's. */
|
||||
if (!rej && channel->sessionGranted) {
|
||||
if (!rej && wolfSSH_ChannelGetSessionGranted(channel) == 1) {
|
||||
rej = 1;
|
||||
reason = "a session is already running on the channel";
|
||||
}
|
||||
|
|
|
|||
11
src/ssh.c
11
src/ssh.c
|
|
@ -5774,6 +5774,17 @@ word32 wolfSSH_ChannelGetSessionCommandSz(const WOLFSSH_CHANNEL* channel)
|
|||
}
|
||||
|
||||
|
||||
/* returns 1 if a session was granted on the channel, 0 if not, and
|
||||
* negative on failure */
|
||||
int wolfSSH_ChannelGetSessionGranted(const WOLFSSH_CHANNEL* channel)
|
||||
{
|
||||
if (channel == NULL) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
return channel->sessionGranted;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSH_CTX_SetChannelOpenCb(WOLFSSH_CTX* ctx, WS_CallbackChannelOpen cb)
|
||||
{
|
||||
int ret = WS_SSH_CTX_NULL_E;
|
||||
|
|
|
|||
|
|
@ -5862,6 +5862,37 @@ static void TestAcceptDivertMatchesScpCommandToken(void)
|
|||
|
||||
#endif /* WOLFSSH_SCP */
|
||||
|
||||
/* The grant an application reads through the public accessor is the one the
|
||||
* channel records: clear while the request that would set it is still being
|
||||
* answered, set once it has been. */
|
||||
static void TestChannelGetSessionGrantedAccessor(void)
|
||||
{
|
||||
ChannelOpenHarness harness;
|
||||
WOLFSSH_CHANNEL* channel;
|
||||
byte in[128];
|
||||
word32 inSz;
|
||||
|
||||
AssertIntEQ(wolfSSH_ChannelGetSessionGranted(NULL), WS_BAD_ARGUMENT);
|
||||
|
||||
InitChannelOpenHarness(&harness, NULL, 0);
|
||||
channel = SeedUnconfirmedChannel(&harness);
|
||||
AssertIntEQ(ChannelUpdatePeer(channel, 5, 1024, 1024), WS_SUCCESS);
|
||||
channel->openConfirmed = 1;
|
||||
AssertIntEQ(wolfSSH_ChannelGetSessionGranted(channel), 0);
|
||||
|
||||
inSz = BuildChannelStringRequestPacket(channel->channel, "exec", 1,
|
||||
"ls", in, sizeof(in));
|
||||
RepointHarnessInput(&harness, in, inSz);
|
||||
|
||||
AssertIntEQ(DoReceive(harness.ssh), WS_SUCCESS);
|
||||
AssertIntEQ(wolfSSH_ChannelGetSessionGranted(channel), 1);
|
||||
AssertIntEQ(wolfSSH_ChannelGetSessionGranted(channel),
|
||||
channel->sessionGranted);
|
||||
|
||||
FreeChannelOpenHarness(&harness);
|
||||
}
|
||||
|
||||
|
||||
/* A username change after the first userauth request must end the session. */
|
||||
static void TestUsernameChangeDisconnects(void)
|
||||
{
|
||||
|
|
@ -16006,6 +16037,7 @@ int main(int argc, char** argv)
|
|||
TestChannelReqExecCallbackRuns();
|
||||
TestChannelReqSubsysCallbackRuns();
|
||||
TestSessionReqCallbackSeesCommandSz();
|
||||
TestChannelGetSessionGrantedAccessor();
|
||||
TestMalformedSessionRequestSkipsCallback();
|
||||
TestSessionReqCallbackMayFreeChannel();
|
||||
TestAppChannelsAcceptKeepsStopWithPendingOutput();
|
||||
|
|
|
|||
|
|
@ -451,6 +451,12 @@ WOLFSSH_API const char* wolfSSH_ChannelGetSessionCommand(
|
|||
WOLFSSH_API word32 wolfSSH_ChannelGetSessionCommandSz(
|
||||
const WOLFSSH_CHANNEL* channel);
|
||||
WOLFSSH_API int wolfSSH_ChannelIsPty(const WOLFSSH_CHANNEL* channel);
|
||||
/* Returns 1 once a shell, exec or subsystem request on the channel has been
|
||||
* answered CHANNEL_SUCCESS, 0 while none has been, and WS_BAD_ARGUMENT when
|
||||
* channel is NULL. A session-request callback sees this still clear for the
|
||||
* request it is answering, so a set flag is an earlier request's grant. */
|
||||
WOLFSSH_API int wolfSSH_ChannelGetSessionGranted(
|
||||
const WOLFSSH_CHANNEL* channel);
|
||||
|
||||
/* Channel callbacks */
|
||||
typedef int (*WS_CallbackChannelOpen)(WOLFSSH_CHANNEL* channel, void* ctx);
|
||||
|
|
|
|||
Loading…
Reference in New Issue