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
|
/* 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
|
* request's grant is recorded once the callback returns, so a flag
|
||||||
* already set is an earlier request's. */
|
* already set is an earlier request's. */
|
||||||
if (!rej && channel->sessionGranted) {
|
if (!rej && wolfSSH_ChannelGetSessionGranted(channel) == 1) {
|
||||||
rej = 1;
|
rej = 1;
|
||||||
reason = "a session is already running on the channel";
|
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 wolfSSH_CTX_SetChannelOpenCb(WOLFSSH_CTX* ctx, WS_CallbackChannelOpen cb)
|
||||||
{
|
{
|
||||||
int ret = WS_SSH_CTX_NULL_E;
|
int ret = WS_SSH_CTX_NULL_E;
|
||||||
|
|
|
||||||
|
|
@ -5862,6 +5862,37 @@ static void TestAcceptDivertMatchesScpCommandToken(void)
|
||||||
|
|
||||||
#endif /* WOLFSSH_SCP */
|
#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. */
|
/* A username change after the first userauth request must end the session. */
|
||||||
static void TestUsernameChangeDisconnects(void)
|
static void TestUsernameChangeDisconnects(void)
|
||||||
{
|
{
|
||||||
|
|
@ -16006,6 +16037,7 @@ int main(int argc, char** argv)
|
||||||
TestChannelReqExecCallbackRuns();
|
TestChannelReqExecCallbackRuns();
|
||||||
TestChannelReqSubsysCallbackRuns();
|
TestChannelReqSubsysCallbackRuns();
|
||||||
TestSessionReqCallbackSeesCommandSz();
|
TestSessionReqCallbackSeesCommandSz();
|
||||||
|
TestChannelGetSessionGrantedAccessor();
|
||||||
TestMalformedSessionRequestSkipsCallback();
|
TestMalformedSessionRequestSkipsCallback();
|
||||||
TestSessionReqCallbackMayFreeChannel();
|
TestSessionReqCallbackMayFreeChannel();
|
||||||
TestAppChannelsAcceptKeepsStopWithPendingOutput();
|
TestAppChannelsAcceptKeepsStopWithPendingOutput();
|
||||||
|
|
|
||||||
|
|
@ -451,6 +451,12 @@ WOLFSSH_API const char* wolfSSH_ChannelGetSessionCommand(
|
||||||
WOLFSSH_API word32 wolfSSH_ChannelGetSessionCommandSz(
|
WOLFSSH_API word32 wolfSSH_ChannelGetSessionCommandSz(
|
||||||
const WOLFSSH_CHANNEL* channel);
|
const WOLFSSH_CHANNEL* channel);
|
||||||
WOLFSSH_API int wolfSSH_ChannelIsPty(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 */
|
/* Channel callbacks */
|
||||||
typedef int (*WS_CallbackChannelOpen)(WOLFSSH_CHANNEL* channel, void* ctx);
|
typedef int (*WS_CallbackChannelOpen)(WOLFSSH_CHANNEL* channel, void* ctx);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue