forked from wolfSSL/wolfssh
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request wolfSSL#713 from ejohnstown/channel-callbacks
Channel Callbacks
- Loading branch information
Showing
1 changed file
with
233 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
} | ||
} | ||
} | ||
|
@@ -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); | ||
|
@@ -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); | ||
|
@@ -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()"); | ||
|
@@ -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) { | ||
|
@@ -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); | ||
} | ||
} | ||
|
||
|
@@ -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); | ||
} | ||
} | ||
|
||
|
@@ -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()"); | ||
|
||
|
@@ -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, | ||
|
@@ -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; | ||
} | ||
|
@@ -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."; | ||
|
@@ -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 | ||
|