Skip to content

Commit

Permalink
Merge pull request wolfSSL#713 from ejohnstown/channel-callbacks
Browse files Browse the repository at this point in the history
Channel Callbacks
  • Loading branch information
douzzer authored and jefferyq2 committed Oct 18, 2024
1 parent a84943c commit 23db5c3
Showing 1 changed file with 233 additions and 0 deletions.
233 changes: 233 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8220,6 +8220,24 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
#endif
default:
ret = WS_INVALID_ALGO_ID;
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
if (typeId == ID_CHANTYPE_TCPIP_DIRECT) {
ChannelUpdateForward(newChannel,
host, hostPort, origin, originPort, isDirect);

if (ssh->ctx->fwdCb) {
ret = ssh->ctx->fwdCb(WOLFSSH_FWD_LOCAL_SETUP,
ssh->fwdCbCtx, host, hostPort);
if (ret == WS_SUCCESS) {
ret = ssh->ctx->fwdCb(WOLFSSH_FWD_CHANNEL_ID,
ssh->fwdCbCtx, NULL, newChannel->channel);
}
}
}
Expand Down Expand Up @@ -8254,6 +8272,22 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
}
else if (partialSuccess && hasSig) {
ret = SendUserAuthFailure(ssh, 1);
else {
const char *description = NULL;

if (fail_reason == OPEN_ADMINISTRATIVELY_PROHIBITED)
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");
}
else
ret = SendRequestSuccess(ssh, 0); /* XXX Is this right? */
}

WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestPublicKey(), ret = %d", ret);
Expand Down Expand Up @@ -8331,6 +8365,14 @@ static int DoUserAuthRequest(WOLFSSH* ssh,
}

*idx = begin;
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;
}

WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequest(), ret = %d", ret);
Expand All @@ -8345,6 +8387,9 @@ static int DoUserAuthFailure(WOLFSSH* ssh,
word32 authListSz = 3;
byte partialSuccess;
byte authType = 0;
WOLFSSH_CHANNEL* channel = NULL;
char desc[80];
word32 begin, channelId, reasonId, descSz, langSz;
int ret = WS_SUCCESS;

WLOG(WS_LOG_DEBUG, "Entering DoUserAuthFailure()");
Expand Down Expand Up @@ -8387,6 +8432,20 @@ static int DoUserAuthFailure(WOLFSSH* ssh,
WLOG(WS_LOG_DEBUG, "Did not match any auth IDs in peers list");
ret = WS_USER_AUTH_E;
}
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);
}

if (ret == WS_SUCCESS) {
Expand Down Expand Up @@ -8439,6 +8498,15 @@ static int DoUserAuthBanner(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
if (ret == WS_SUCCESS) {
if (ssh->ctx->showBanner) {
WLOG(WS_LOG_INFO, "%s", banner);
if (ssh->ctx->channelEofCb) {
ssh->ctx->channelEofCb(channel, ssh->channelEofCtx);
}
}

if (ret == WS_SUCCESS) {
channel->eofRxd = 1;
if (!channel->eofTxd) {
ret = SendChannelEof(ssh, channel->peerChannel);
}
}

Expand Down Expand Up @@ -8486,6 +8554,14 @@ static int DoGlobalRequestFwd(WOLFSSH* ssh,
ret = ssh->ctx->fwdCb(isCancel ? WOLFSSH_FWD_REMOTE_CLEANUP :
WOLFSSH_FWD_REMOTE_SETUP,
ssh->fwdCbCtx, bindAddr, bindPort);
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 @@ -8629,6 +8705,8 @@ static int DoChannelOpen(WOLFSSH* ssh,
WOLFSSH_CHANNEL* newChannel = NULL;
int ret = WS_SUCCESS;
word32 fail_reason = OPEN_OK;
byte wantReply;
int ret, rej = 0;

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

Expand Down Expand Up @@ -8710,6 +8788,109 @@ static int DoChannelOpen(WOLFSSH* ssh,
if (typeId == ID_CHANTYPE_TCPIP_DIRECT) {
ChannelUpdateForward(newChannel,
host, hostPort, origin, originPort, isDirect);
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;
word32 widthChar, heightRows, widthPixels, heightPixels;

termSz = (word32)sizeof(term);
ret = GetString(term, &termSz, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&widthChar, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&heightRows, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&widthPixels, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&heightPixels, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetStringRef(&modesSz, &modes, buf, len, &begin);
if (ret == WS_SUCCESS) {
ssh->modes = (byte*)WMALLOC(modesSz,
ssh->ctx->heap, DYNTYPE_STRING);
if (ssh->modes == NULL)
ret = WS_MEMORY_E;
}
if (ret == WS_SUCCESS) {
ssh->modesSz = modesSz;
WMEMCPY(ssh->modes, modes, modesSz);
WLOG(WS_LOG_DEBUG, " term = %s", term);
WLOG(WS_LOG_DEBUG, " widthChar = %u", widthChar);
WLOG(WS_LOG_DEBUG, " heightRows = %u", heightRows);
WLOG(WS_LOG_DEBUG, " widthPixels = %u", widthPixels);
WLOG(WS_LOG_DEBUG, " heightPixels = %u", heightPixels);
ssh->widthChar = widthChar;
ssh->heightRows = heightRows;
ssh->widthPixels = widthPixels;
ssh->heightPixels = heightPixels;
if (ssh->termResizeCb) {
if (ssh->termResizeCb(ssh, widthChar, heightRows,
widthPixels, heightPixels,
ssh->termCtx) != WS_SUCCESS) {
ret = WS_FATAL_ERROR;
}
}
}
}
#endif /* WOLFSSH_TERM */
#if defined(WOLFSSH_SHELL) && defined(WOLFSSH_TERM)
else if (WSTRNCMP(type, "window-change", typeSz) == 0) {
word32 widthChar, heightRows, widthPixels, heightPixels;

ret = GetUint32(&widthChar, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&heightRows, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&widthPixels, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&heightPixels, buf, len, &begin);

if (ssh->ctx->fwdCb) {
ret = ssh->ctx->fwdCb(WOLFSSH_FWD_LOCAL_SETUP,
Expand All @@ -8722,6 +8903,36 @@ static int DoChannelOpen(WOLFSSH* ssh,
}
#endif /* WOLFSSH_FWD */
ChannelAppend(ssh, newChannel);
}
#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);
}
else if (WSTRNCMP(type, "exit-signal", typeSz) == 0) {
char sig[WOLFSSH_MAX_NAMESZ];
word32 sigSz;
byte coreDumped;

WLOG(WS_LOG_AGENT, "Got exit signal, remote command terminated");

sigSz = WOLFSSH_MAX_NAMESZ;
ret = GetString(sig, &sigSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_AGENT, "SIGNAL : %s", sig);
ret = GetBoolean(&coreDumped, buf, len, &begin);
}

if (ret == WS_SUCCESS) {
WLOG(WS_LOG_AGENT, "Core Dumped?: %d", coreDumped);
sigSz = WOLFSSH_MAX_NAMESZ;
ret = GetString(sig, &sigSz, buf, len, &begin);
}

if (ret == WS_SUCCESS) {
WLOG(WS_LOG_AGENT, "Error Msg : %s", sig);
sigSz = WOLFSSH_MAX_NAMESZ;

ssh->clientState = CLIENT_CHANNEL_OPEN_DONE;
}
Expand All @@ -8732,6 +8943,21 @@ static int DoChannelOpen(WOLFSSH* ssh,
}
else {
const char *description = NULL;
#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) {
*idx = len;
}

if (fail_reason == OPEN_ADMINISTRATIVELY_PROHIBITED)
description = "Administratively prohibited.";
Expand All @@ -8746,6 +8972,13 @@ static int DoChannelOpen(WOLFSSH* ssh,
}
else
ret = SendRequestSuccess(ssh, 0); /* XXX Is this right? */
if (rej) {
WLOG(WS_LOG_DEBUG, "Callback rejecting channel request.");
}
replyRet = SendChannelSuccess(ssh, channelId,
(ret == WS_SUCCESS && !rej));
if (replyRet != WS_SUCCESS)
ret = replyRet;
}

#ifdef WOLFSSH_FWD
Expand Down

0 comments on commit 23db5c3

Please sign in to comment.