diff --git a/src/internal.c b/src/internal.c index b3386e68..27ed19d3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -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, "auth-agent-req@openssh.com", 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