Skip to content

Commit

Permalink
Merge pull request #713 from ejohnstown/channel-callbacks
Browse files Browse the repository at this point in the history
Channel Callbacks
  • Loading branch information
douzzer authored Jul 16, 2024
2 parents 94ebc62 + 015ae84 commit 24884dc
Show file tree
Hide file tree
Showing 4 changed files with 391 additions and 69 deletions.
170 changes: 110 additions & 60 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -7761,6 +7761,9 @@ static int DoChannelOpen(WOLFSSH* ssh,
else {
ChannelUpdatePeer(newChannel, peerChannelId,
peerInitialWindowSz, peerMaxPacketSz);
if (ssh->ctx->channelOpenCb) {
ret = ssh->ctx->channelOpenCb(newChannel, ssh->channelOpenCtx);
}
if (ssh->channelListSz == 0)
ssh->defaultPeerChannelId = peerChannelId;
#ifdef WOLFSSH_FWD
Expand Down Expand Up @@ -7791,16 +7794,18 @@ static int DoChannelOpen(WOLFSSH* ssh,
const char *description = NULL;

if (fail_reason == OPEN_ADMINISTRATIVELY_PROHIBITED)
description = "Each session cannot have more than one channel open.";
description = "Administratively prohibited.";
else if (fail_reason == OPEN_UNKNOWN_CHANNEL_TYPE)
description = "Channel type not supported.";
else if (fail_reason == OPEN_RESOURCE_SHORTAGE)
description = "Not enough resources.";

if (description != NULL)
ret = SendChannelOpenFail(ssh, peerChannelId, fail_reason, description, "en");
if (description != NULL) {
ret = SendChannelOpenFail(ssh, peerChannelId,
fail_reason, description, "en");
}
else
ret = SendRequestSuccess(ssh, 0);
ret = SendRequestSuccess(ssh, 0); /* XXX Is this right? */
}

#ifdef WOLFSSH_FWD
Expand Down Expand Up @@ -7856,6 +7861,12 @@ static int DoChannelOpenConf(WOLFSSH* ssh,
ret = ChannelUpdatePeer(channel, peerChannelId,
peerInitialWindowSz, peerMaxPacketSz);

if (ret == WS_SUCCESS) {
if (ssh->ctx->channelOpenConfCb != NULL) {
ret = ssh->ctx->channelOpenConfCb(channel, ssh->channelOpenCtx);
}
}

if (ret == WS_SUCCESS) {
ssh->serverState = SERVER_CHANNEL_OPEN_DONE;
ssh->defaultPeerChannelId = peerChannelId;
Expand All @@ -7869,6 +7880,7 @@ static int DoChannelOpenConf(WOLFSSH* ssh,
static int DoChannelOpenFail(WOLFSSH* ssh,
byte* buf, word32 len, word32* idx)
{
WOLFSSH_CHANNEL* channel = NULL;
char desc[80];
word32 begin, channelId, reasonId, descSz, langSz;
int ret = WS_SUCCESS;
Expand Down Expand Up @@ -7902,6 +7914,19 @@ static int DoChannelOpenFail(WOLFSSH* ssh,
WLOG(WS_LOG_INFO, "description: %s", desc);
}

if (ssh->ctx->channelOpenFailCb != NULL) {
channel = ChannelFind(ssh, channelId, WS_CHANNEL_ID_SELF);

if (channel != NULL) {
ret = ssh->ctx->channelOpenFailCb(channel, ssh->channelOpenCtx);
}
else {
ret = WS_INVALID_CHANID;
}
}
}

if (ret == WS_SUCCESS) {
ret = ChannelRemove(ssh, channelId, WS_CHANNEL_ID_SELF);
}

Expand Down Expand Up @@ -7933,6 +7958,12 @@ static int DoChannelEof(WOLFSSH* ssh,
ret = WS_INVALID_CHANID;
}

if (ret == WS_SUCCESS) {
if (ssh->ctx->channelEofCb) {
ssh->ctx->channelEofCb(channel, ssh->channelEofCtx);
}
}

if (ret == WS_SUCCESS) {
channel->eofRxd = 1;
if (!channel->eofTxd) {
Expand Down Expand Up @@ -7966,6 +7997,12 @@ static int DoChannelClose(WOLFSSH* ssh,
ret = WS_INVALID_CHANID;
}

if (ret == WS_SUCCESS) {
if (ssh->ctx->channelCloseCb) {
ssh->ctx->channelCloseCb(channel, ssh->channelCloseCtx);
}
}

if (ret == WS_SUCCESS) {
if (!channel->closeTxd) {
ret = SendChannelClose(ssh, channel->peerChannel);
Expand Down Expand Up @@ -8239,7 +8276,7 @@ static int DoChannelRequest(WOLFSSH* ssh,
word32 typeSz;
char type[32];
byte wantReply;
int ret;
int ret, rej = 0;

WLOG(WS_LOG_DEBUG, "Entering DoChannelRequest()");

Expand Down Expand Up @@ -8268,8 +8305,53 @@ static int DoChannelRequest(WOLFSSH* ssh,
WLOG(WS_LOG_DEBUG, " type = %s", type);
WLOG(WS_LOG_DEBUG, " wantReply = %u", wantReply);

#ifdef WOLFSSH_TERM
if (WSTRNCMP(type, "pty-req", typeSz) == 0) {
if (WSTRNCMP(type, "env", typeSz) == 0) {
char name[WOLFSSH_MAX_NAMESZ];
word32 nameSz;
char value[32];
word32 valueSz;

name[0] = 0;
value[0] = 0;
nameSz = (word32)sizeof(name);
valueSz = (word32)sizeof(value);
ret = GetString(name, &nameSz, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetString(value, &valueSz, buf, len, &begin);

WLOG(WS_LOG_DEBUG, " %s = %s", name, value);
}
else if (WSTRNCMP(type, "shell", typeSz) == 0) {
channel->sessionType = WOLFSSH_SESSION_SHELL;
if (ssh->ctx->channelReqShellCb) {
rej = ssh->ctx->channelReqShellCb(channel, ssh->channelReqCtx);
}
ssh->clientState = CLIENT_DONE;
}
else if (WSTRNCMP(type, "exec", typeSz) == 0) {
ret = GetStringAlloc(ssh->ctx->heap, &channel->command,
buf, len, &begin);
channel->sessionType = WOLFSSH_SESSION_EXEC;
if (ssh->ctx->channelReqExecCb) {
rej = ssh->ctx->channelReqExecCb(channel, ssh->channelReqCtx);
}
ssh->clientState = CLIENT_DONE;

WLOG(WS_LOG_DEBUG, " command = %s", channel->command);
}
else if (WSTRNCMP(type, "subsystem", typeSz) == 0) {
ret = GetStringAlloc(ssh->ctx->heap, &channel->command,
buf, len, &begin);
channel->sessionType = WOLFSSH_SESSION_SUBSYSTEM;
if (ssh->ctx->channelReqSubsysCb) {
rej = ssh->ctx->channelReqSubsysCb(channel, ssh->channelReqCtx);
}
ssh->clientState = CLIENT_DONE;

WLOG(WS_LOG_DEBUG, " subsystem = %s", channel->command);
}
#ifdef WOLFSSH_TERM
else if (WSTRNCMP(type, "pty-req", typeSz) == 0) {
char term[32];
const byte* modes;
word32 termSz, modesSz = 0;
Expand Down Expand Up @@ -8314,54 +8396,8 @@ static int DoChannelRequest(WOLFSSH* ssh,
}
}
}
else
#endif /* WOLFSSH_TERM */
if (WSTRNCMP(type, "env", typeSz) == 0) {
char name[WOLFSSH_MAX_NAMESZ];
word32 nameSz;
char value[32];
word32 valueSz;

name[0] = 0;
value[0] = 0;
nameSz = (word32)sizeof(name);
valueSz = (word32)sizeof(value);
ret = GetString(name, &nameSz, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetString(value, &valueSz, buf, len, &begin);

WLOG(WS_LOG_DEBUG, " %s = %s", name, value);
}
else if (WSTRNCMP(type, "shell", typeSz) == 0) {
channel->sessionType = WOLFSSH_SESSION_SHELL;
ssh->clientState = CLIENT_DONE;
}
else if (WSTRNCMP(type, "exec", typeSz) == 0) {
ret = GetStringAlloc(ssh->ctx->heap, &channel->command,
buf, len, &begin);
channel->sessionType = WOLFSSH_SESSION_EXEC;
ssh->clientState = CLIENT_DONE;

WLOG(WS_LOG_DEBUG, " command = %s", channel->command);
}
else if (WSTRNCMP(type, "subsystem", typeSz) == 0) {
ret = GetStringAlloc(ssh->ctx->heap, &channel->command,
buf, len, &begin);
channel->sessionType = WOLFSSH_SESSION_SUBSYSTEM;
ssh->clientState = CLIENT_DONE;

WLOG(WS_LOG_DEBUG, " subsystem = %s", channel->command);
}
#ifdef WOLFSSH_AGENT
else if (WSTRNCMP(type, "[email protected]", typeSz) == 0) {
WLOG(WS_LOG_AGENT, " ssh-agent");
if (ssh->ctx->agentCb != NULL)
ssh->useAgent = 1;
else
WLOG(WS_LOG_AGENT, "Agent callback not set, not using.");
}
#endif /* WOLFSSH_AGENT */
#if defined(WOLFSSH_SHELL) && defined(WOLFSSH_TERM)
#endif /* WOLFSSH_TERM */
#if defined(WOLFSSH_SHELL) && defined(WOLFSSH_TERM)
else if (WSTRNCMP(type, "window-change", typeSz) == 0) {
word32 widthChar, heightRows, widthPixels, heightPixels;

Expand Down Expand Up @@ -8391,8 +8427,8 @@ static int DoChannelRequest(WOLFSSH* ssh,
}
}
}
#endif /* WOLFSSH_SHELL && WOLFSSH_TERM */
#if defined(WOLFSSH_TERM) || defined(WOLFSSH_SHELL)
#endif /* WOLFSSH_SHELL && WOLFSSH_TERM */
#if defined(WOLFSSH_TERM) || defined(WOLFSSH_SHELL)
else if (WSTRNCMP(type, "exit-status", typeSz) == 0) {
ret = GetUint32(&ssh->exitStatus, buf, len, &begin);
WLOG(WS_LOG_AGENT, "Got exit status %u.", ssh->exitStatus);
Expand Down Expand Up @@ -8425,16 +8461,30 @@ static int DoChannelRequest(WOLFSSH* ssh,
ret = GetString(sig, &sigSz, buf, len, &begin);
}
}
#endif
#endif /* WOLFSSH_TERM or WOLFSSH_SHELL */
#ifdef WOLFSSH_AGENT
else if (WSTRNCMP(type, "[email protected]", typeSz) == 0) {
WLOG(WS_LOG_AGENT, " ssh-agent");
if (ssh->ctx->agentCb != NULL)
ssh->useAgent = 1;
else
WLOG(WS_LOG_AGENT, "Agent callback not set, not using.");
}
#endif /* WOLFSSH_AGENT */
}

if (ret == WS_SUCCESS)
if (ret == WS_SUCCESS) {
*idx = len;
}

if (wantReply) {
int replyRet;

replyRet = SendChannelSuccess(ssh, channelId, (ret == WS_SUCCESS));
if (rej) {
WLOG(WS_LOG_DEBUG, "Callback rejecting channel request.");
}
replyRet = SendChannelSuccess(ssh, channelId,
(ret == WS_SUCCESS && !rej));
if (replyRet != WS_SUCCESS)
ret = replyRet;
}
Expand Down
Loading

0 comments on commit 24884dc

Please sign in to comment.