From a6e8c59b9742d1f71dfd76eb84cf4eec43d43976 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 23 May 2018 16:54:17 -0600 Subject: [PATCH] scp modifications from embedded port --- src/internal.c | 29 +++++++++++++------- src/ssh.c | 6 ++--- src/wolfscp.c | 71 ++++++++++++++++++++++++++++++++++++++----------- wolfssh/error.h | 3 ++- 4 files changed, 80 insertions(+), 29 deletions(-) diff --git a/src/internal.c b/src/internal.c index 4a246ee6..051d7fce 100644 --- a/src/internal.c +++ b/src/internal.c @@ -215,6 +215,9 @@ const char* GetErrorString(int err) case WS_SCP_COMPLETE: return "scp operation complete"; + case WS_SCP_INIT: + return "scp operation verified"; + default: return "Unknown error code"; } @@ -330,10 +333,11 @@ WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, byte side, void* heap) #endif /* WOLFSSH_USER_IO */ ctx->highwaterMark = DEFAULT_HIGHWATER_MARK; ctx->highwaterCb = wsHighwater; -#ifdef WOLFSSH_SCP +#if defined(WOLFSSH_SCP) && !defined(WOLFSSH_SCP_USER_CALLBACKS) && \ + !defined(NO_FILESYSTEM) ctx->scpRecvCb = wsScpRecvCallback; ctx->scpSendCb = wsScpSendCallback; -#endif +#endif /* WOLFSSH_SCP */ #ifdef DEBUG_WOLFSSH ctx->banner = cannedBanner; ctx->bannerSz = cannedBannerSz; @@ -356,6 +360,11 @@ void CtxResourceFree(WOLFSSH_CTX* ctx) WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx) { +#if defined(STM32F2) || defined(STM32F4) + /* avoid name conflict in "stm32fnnnxx.h" */ + #undef RNG + #define RNG WC_RNG +#endif HandshakeInfo* handshake; RNG* rng; void* heap; @@ -2134,7 +2143,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { byte* pubKey = NULL; word32 pubKeySz; - byte* f; + byte* f = NULL; word32 fSz; byte* sig; word32 sigSz; @@ -2920,7 +2929,7 @@ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk, word32 publicKeyTypeSz = 0; byte* n; word32 nSz = 0; - byte* e; + byte* e = NULL; word32 eSz = 0; word32 i = 0; int ret = WS_SUCCESS; @@ -3039,7 +3048,7 @@ static int DoUserAuthRequestEcc(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk, byte* curveName; word32 curveNameSz = 0; mp_int r, s; - byte* q; + byte* q = NULL; word32 sz, qSz; word32 i = 0; int ret = WS_SUCCESS; @@ -4784,13 +4793,13 @@ static const word32 cannedNoneNamesSz = sizeof(cannedNoneNames) - 1; int SendKexInit(WOLFSSH* ssh) { - byte* output; - byte* payload; + byte* output = NULL; + byte* payload = NULL; word32 idx = 0; - word32 payloadSz; + word32 payloadSz = 0; int ret = WS_SUCCESS; - const char* cannedKeyAlgoNames; - word32 cannedKeyAlgoNamesSz; + const char* cannedKeyAlgoNames = NULL; + word32 cannedKeyAlgoNamesSz = 0; WLOG(WS_LOG_DEBUG, "Entering SendKexInit()"); diff --git a/src/ssh.c b/src/ssh.c index 9757d9a6..3a3e9bf9 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -597,14 +597,14 @@ int wolfSSH_shutdown(WOLFSSH* ssh) WLOG(WS_LOG_DEBUG, "Entering wolfSSH_shutdown()"); - if (ssh == NULL) + if (ssh == NULL || ssh->channelList == NULL) ret = WS_BAD_ARGUMENT; if (ret == WS_SUCCESS) - ret = SendChannelEof(ssh, 0); + ret = SendChannelEof(ssh, ssh->channelList->peerChannel); if (ret == WS_SUCCESS) - ret = SendChannelClose(ssh, 0); + ret = SendChannelClose(ssh, ssh->channelList->peerChannel); if (ret == WS_SUCCESS) ret = SendDisconnect(ssh, WOLFSSH_DISCONNECT_BY_APPLICATION); diff --git a/src/wolfscp.c b/src/wolfscp.c index 9bbe3d6c..c9ef23b3 100644 --- a/src/wolfscp.c +++ b/src/wolfscp.c @@ -466,7 +466,7 @@ int DoScpSource(WOLFSSH* ssh) ssh->scpNextState = SCP_DONE; continue; - } else if (ssh->scpConfirm > 0) { + } else if (ssh->scpConfirm >= 0) { /* transfer buffered file data */ ssh->scpBufferedSz = ssh->scpConfirm; @@ -654,13 +654,19 @@ int DoScpRequest(WOLFSSH* ssh) case SCP_SINK: WLOG(WS_LOG_DEBUG, scpState, "SCP_SINK"); - ret = DoScpSink(ssh); - break; + if ( (ssh->error = DoScpSink(ssh)) < WS_SUCCESS) { + WLOG(WS_LOG_ERROR, scpError, "SCP_SINK", ssh->error); + ret = WS_FATAL_ERROR; + break; + } case SCP_SOURCE: WLOG(WS_LOG_DEBUG, scpState, "SCP_SOURCE"); - ret = DoScpSource(ssh); - break; + if ( (ssh->error = DoScpSource(ssh)) < WS_SUCCESS) { + WLOG(WS_LOG_ERROR, scpError, "SCP_SOURCE", ssh->error); + ret = WS_FATAL_ERROR; + break; + } } } @@ -745,10 +751,16 @@ static int GetScpFileMode(WOLFSSH* ssh, byte* buf, word32 bufSz, word32* inOutIdx) { int ret; - mp_int tmp; word32 idx; byte modeOctet[SCP_MODE_OCTET_LEN]; +#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ + defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \ + defined(WOLFSSL_PUBLIC_MP) + mp_int tmp; char decimalString[SCP_MODE_OCTET_LEN + 1]; +#else + int mode, i; +#endif if (ssh == NULL || buf == NULL || inOutIdx == NULL || bufSz < (SCP_MODE_OCTET_LEN + 1)) @@ -764,6 +776,9 @@ static int GetScpFileMode(WOLFSSH* ssh, byte* buf, word32 bufSz, WMEMCPY(modeOctet, buf + idx, sizeof(modeOctet)); idx += SCP_MODE_OCTET_LEN; +#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ + defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \ + defined(WOLFSSL_PUBLIC_MP) ret = mp_init(&tmp); if (ret == MP_OKAY) { ret = mp_read_radix(&tmp, (const char*)modeOctet, 8); @@ -789,6 +804,31 @@ static int GetScpFileMode(WOLFSSH* ssh, byte* buf, word32 bufSz, } mp_clear(&tmp); +#else + ret = WS_SUCCESS; + /* convert octal string to int without mp_read_radix() */ + mode = 0; + + for (i = 0; i < SCP_MODE_OCTET_LEN; i++) + { + if (modeOctet[i] < '0' || modeOctet[0] > '7') { + ret = WS_BAD_ARGUMENT; + break; + } + mode <<= 3; + mode |= (modeOctet[i] - '0'); + } + + if (ret == WS_SUCCESS) { + /* store file mode */ + ssh->scpFileMode = mode; + /* eat trailing space */ + if (bufSz >= (word32)(idx +1)) + idx++; + ret = WS_SUCCESS; + *inOutIdx = idx; + } +#endif return ret; } @@ -1491,13 +1531,14 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath, WFCLOSE(fp); /* set timestamp info */ - if (mTime != 0 || aTime != 0) + if (mTime != 0 || aTime != 0) { ret = SetTimestampInfo(fileName, mTime, aTime); - if (ret == WS_SUCCESS) { - ret = WS_SCP_CONTINUE; - } else { - ret = WS_SCP_ABORT; + if (ret == WS_SUCCESS) { + ret = WS_SCP_CONTINUE; + } else { + ret = WS_SCP_ABORT; + } } break; @@ -1523,7 +1564,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath, case WOLFSSH_SCP_END_DIR: /* cd out of directory */ - if (WCHDIR("../") != 0) { + if (WCHDIR("..") != 0) { wolfSSH_SetScpErrorMsg(ssh, "unable to cd out of directory"); ret = WS_SCP_ABORT; } @@ -1545,8 +1586,8 @@ static int ExtractFileName(const char* filePath, char* fileName, word32 fileNameSz) { int ret = WS_SUCCESS; - word32 pathLen, fileLen; - word32 idx = 0, separator = 0; + word32 fileLen; + int idx = 0, pathLen, separator = -1; if (filePath == NULL || fileName == NULL) return WS_BAD_ARGUMENT; @@ -1560,7 +1601,7 @@ static int ExtractFileName(const char* filePath, char* fileName, idx++; } - if (separator == 0) + if (separator < 0) return WS_BAD_ARGUMENT; fileLen = pathLen - separator - 1; diff --git a/wolfssh/error.h b/wolfssh/error.h index 5202af2e..6e5124f1 100644 --- a/wolfssh/error.h +++ b/wolfssh/error.h @@ -86,8 +86,9 @@ enum WS_ErrorCodes { WS_SCP_EXIT_DIR = -46, WS_SCP_EXIT_DIR_FINAL = -47, WS_SCP_COMPLETE = -48, /* SCP transfer complete */ + WS_SCP_INIT = -49, /* SCP transfer verified */ - WS_LAST_E = -48 /* Update this to indicate last error */ + WS_LAST_E = -49 /* Update this to indicate last error */ };