diff --git a/src/wolfsftp.c b/src/wolfsftp.c index 7f7d29739..3a7e4bceb 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -403,7 +403,7 @@ typedef struct WS_SFTP_RENAME_STATE { static int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz); -static int SFTP_ParseAtributes_buffer(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr, +static int SFTP_ParseAttributes_buffer(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr, byte* buf, word32* idx, word32 maxIdx); static WS_SFTPNAME* wolfSSH_SFTPNAME_new(void* heap); @@ -913,7 +913,7 @@ static int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz, /* returns the size of buffer needed to hold attributes */ -static int SFTP_AtributesSz(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr) +static int SFTP_AttributesSz(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr) { word32 sz = 0; @@ -1283,6 +1283,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data, int ret = 0; byte* out; word32 outSz = 0; + const byte* str; WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_REALPATH"); @@ -1291,17 +1292,11 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data, return WS_BAD_ARGUMENT; } - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ + if (GetStringRef(&rSz, &str, data, (word32)maxSz, &lidx) != WS_SUCCESS + || rSz >= WOLFSSH_MAX_FILENAME) { return WS_BUFFER_E; } - - ato32(data + lidx, &rSz); - if (rSz >= WOLFSSH_MAX_FILENAME || (int)(rSz + UINT32_SZ) > maxSz) { - return WS_BUFFER_E; - } - lidx += UINT32_SZ; - WMEMCPY(r, data + lidx, rSz); + WMEMCPY(r, str, rSz); r[rSz] = '\0'; WLOG(WS_LOG_SFTP, "Real Path Request = %s", r); @@ -1367,7 +1362,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data, /* send response */ outSz = WOLFSSH_SFTP_HEADER + (UINT32_SZ * 3) + (sSz * 2); WMEMSET(&atr, 0, sizeof(WS_SFTP_FILEATRB)); - outSz += SFTP_AtributesSz(ssh, &atr); + outSz += SFTP_AttributesSz(ssh, &atr); lidx = 0; /* reuse state buffer if large enough */ @@ -1766,7 +1761,8 @@ static int GetAndCleanPath(const char* defaultPath, */ int wolfSSH_SFTP_RecvRMDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) { - word32 sz; + word32 strSz; + const byte* str; int ret = 0; char dir[WOLFSSH_MAX_FILENAME]; word32 idx = 0; @@ -1784,18 +1780,12 @@ int wolfSSH_SFTP_RecvRMDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_RMDIR"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } ret = GetAndCleanPath(ssh->sftpDefaultPath, - data + idx, sz, dir, sizeof(dir)); + str, strSz, dir, sizeof(dir)); if (ret == 0) { #ifndef USE_WINDOWS_API @@ -1845,7 +1835,9 @@ int wolfSSH_SFTP_RecvRMDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) */ int wolfSSH_SFTP_RecvMKDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) { - word32 sz; + word32 attrFlags; + word32 strSz; + const byte* str; int ret; char dir[WOLFSSH_MAX_FILENAME]; word32 mode = 0; @@ -1864,38 +1856,28 @@ int wolfSSH_SFTP_RecvMKDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_MKDIR"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } ret = GetAndCleanPath(ssh->sftpDefaultPath, - data + idx, sz, dir, sizeof(dir)); + str, strSz, dir, sizeof(dir)); if (ret != WS_SUCCESS) { return ret; } - idx += sz; - if (idx + UINT32_SZ > maxSz) { + if (GetUint32(&attrFlags, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } - - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { - return WS_BUFFER_E; - } - if (sz != UINT32_SZ) { - WLOG(WS_LOG_SFTP, "Attribute size larger than 4 not yet supported"); + if (attrFlags != WOLFSSH_FILEATRB_PERM) { + WLOG(WS_LOG_SFTP, "Only permission attribute supported"); WLOG(WS_LOG_SFTP, "Skipping over attribute and using default"); - mode = 0x41ED; + mode = 040755; } else { - ato32(data + idx, &mode); + if (GetUint32(&mode, data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } } #ifndef USE_WINDOWS_API @@ -2030,7 +2012,6 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) { WS_SFTP_FILEATRB atr; WFD fd; - word32 sz; char dir[WOLFSSH_MAX_FILENAME]; word32 reason; word32 idx = 0; @@ -2041,6 +2022,8 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) word32 outSz = sizeof(WFD) + UINT32_SZ + WOLFSSH_SFTP_HEADER; byte* out = NULL; + word32 strSz; + const byte* str; char* res = NULL; char ier[] = "Internal Failure"; @@ -2067,29 +2050,26 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) return WS_FATAL_ERROR; } - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { - return WS_BUFFER_E; + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { + ret = WS_BUFFER_E; + goto cleanup; } if (GetAndCleanPath(ssh->sftpDefaultPath, - data + idx, sz, dir, sizeof(dir)) != WS_SUCCESS) { + str, strSz, dir, sizeof(dir)) != WS_SUCCESS) { WLOG(WS_LOG_SFTP, "Creating path for file to open failed"); ret = WS_FATAL_ERROR; goto cleanup; } - idx += sz; /* get reason for opening file */ - ato32(data + idx, &reason); idx += UINT32_SZ; + if (GetUint32(&reason, data, maxSz, &idx) != WS_SUCCESS) { + ret = WS_BUFFER_E; + goto cleanup; + } /* @TODO handle attributes */ - SFTP_ParseAtributes_buffer(ssh, &atr, data, &idx, maxSz); + SFTP_ParseAttributes_buffer(ssh, &atr, data, &idx, maxSz); if ((reason & WOLFSSH_FXF_READ) && (reason & WOLFSSH_FXF_WRITE)) { WLOG(WS_LOG_SFTP, "Opening file with WOLFSSH_O_RDWR"); m |= WOLFSSH_O_RDWR; @@ -2242,7 +2222,6 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) { /* WS_SFTP_FILEATRB atr;*/ HANDLE fileHandle; - word32 sz; char dir[WOLFSSH_MAX_FILENAME]; word32 reason; word32 idx = 0; @@ -2255,6 +2234,8 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) word32 outSz = sizeof(HANDLE) + UINT32_SZ + WOLFSSH_SFTP_HEADER; byte* out = NULL; + word32 strSz; + const byte* str; char* res = NULL; char ier[] = "Internal Failure"; @@ -2276,30 +2257,27 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) return WS_FATAL_ERROR; } - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { - return WS_BUFFER_E; + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { + ret = WS_BUFFER_E; + goto cleanup; } - if (GetAndCleanPath(ssh->sftpDefaultPath, data + idx, sz, dir, sizeof(dir)) - != WS_SUCCESS) { + if (GetAndCleanPath(ssh->sftpDefaultPath, + str, strSz, dir, sizeof(dir)) != WS_SUCCESS) { WLOG(WS_LOG_SFTP, "Creating path for file to open failed"); ret = WS_FATAL_ERROR; goto cleanup; } - idx += sz; /* get reason for opening file */ - ato32(data + idx, &reason); idx += UINT32_SZ; + if (GetUint32(&reason, data, maxSz, &idx) != WS_SUCCESS) { + ret = WS_BUFFER_E; + goto cleanup; + } #if 0 /* @TODO handle attributes */ - SFTP_ParseAtributes_buffer(ssh, &atr, data, &idx, maxSz); + SFTP_ParseAttributes_buffer(ssh, &atr, data, &idx, maxSz); #endif if (reason & WOLFSSH_FXF_READ) { @@ -2428,7 +2406,8 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) #ifndef USE_WINDOWS_API { WDIR ctx; - word32 sz; + word32 strSz; + const byte* str; char dir[WOLFSSH_MAX_FILENAME]; word32 idx = 0; int ret = WS_SUCCESS; @@ -2449,19 +2428,13 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) return WS_FATAL_ERROR; } - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get directory name */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } if (GetAndCleanPath(ssh->sftpDefaultPath, - data + idx, sz, dir, sizeof(dir)) < 0) { + str, strSz, dir, sizeof(dir)) < 0) { return WS_BUFFER_E; } @@ -3436,7 +3409,7 @@ static int wolfSSH_SFTP_SendName(WOLFSSH* ssh, WS_SFTPNAME* list, word32 count, WS_SUCCESS) { return WS_FATAL_ERROR; } - idx += SFTP_AtributesSz(ssh, &cur->atrb); + idx += SFTP_AttributesSz(ssh, &cur->atrb); cur = cur->next; } @@ -3475,14 +3448,9 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) dir = INVALID_HANDLE_VALUE; #endif - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get directory handle */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) { + if (GetSize(&sz, data, maxSz, &idx) != WS_SUCCESS + || sz > WOLFSSH_MAX_HANDLE) { return WS_BUFFER_E; } @@ -3490,8 +3458,10 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Unexpected handle size"); return WS_FATAL_ERROR; } - ato32(data + idx, &handle[0]); - ato32(data + idx + UINT32_SZ, &handle[1]); + if (GetUint32(&handle[0], data, maxSz, &idx) != WS_SUCCESS + || GetUint32(&handle[1], data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } /* find DIR given handle */ while (cur != NULL) { @@ -3517,7 +3487,7 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) if (ret == WS_SUCCESS || ret == WS_NEXT_ERROR) { count++; outSz += name->fSz + name->lSz + (UINT32_SZ * 2); - outSz += SFTP_AtributesSz(ssh, &name->atrb); + outSz += SFTP_AttributesSz(ssh, &name->atrb); name->next = list; list = name; } @@ -3645,13 +3615,14 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) #ifndef USE_WINDOWS_API { WFD fd; - word32 sz; int ret = WS_SUCCESS; word32 idx = 0; word32 ofst[2] = {0,0}; word32 outSz = 0; byte* out = NULL; + const byte* str; + word32 strSz; char suc[] = "Write File Success"; char err[] = "Write File Error"; @@ -3664,14 +3635,9 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_WRITE"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file handle */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE || sz != sizeof(WFD)) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_HANDLE || strSz != sizeof(WFD)) { WLOG(WS_LOG_SFTP, "Error with file handle size"); res = err; type = WOLFSSH_FTP_FAILURE; @@ -3680,19 +3646,20 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) if (ret == WS_SUCCESS) { WMEMSET((byte*)&fd, 0, sizeof(WFD)); - WMEMCPY((byte*)&fd, data + idx, sz); idx += sz; + WMEMCPY((byte*)&fd, str, strSz); /* get offset into file */ - ato32(data + idx, &ofst[1]); idx += UINT32_SZ; - ato32(data + idx, &ofst[0]); idx += UINT32_SZ; + if (GetUint32(&ofst[1], data, maxSz, &idx) != WS_SUCCESS + || GetUint32(&ofst[0], data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } /* get length to be written */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } - ret = WPWRITE(ssh->fs, fd, data + idx, sz, ofst); + ret = WPWRITE(ssh->fs, fd, (byte*)str, strSz, ofst); if (ret < 0) { #if defined(WOLFSSL_NUCLEUS) && defined(DEBUG_WOLFSSH) if (ret == NUF_NOSPC) { @@ -3709,9 +3676,6 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) } } - if (sz > maxSz - idx) { - return WS_BUFFER_E; - } if (wolfSSH_SFTP_CreateStatus(ssh, type, reqId, res, "English", NULL, &outSz) != WS_SIZE_ONLY) { return WS_FATAL_ERROR; @@ -3735,12 +3699,13 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) OVERLAPPED offset; HANDLE fd; DWORD bytesWritten; - word32 sz; int ret = WS_SUCCESS; word32 idx = 0; word32 outSz = 0; byte* out = NULL; + const byte* str; + word32 strSz; char suc[] = "Write File Success"; char err[] = "Write File Error"; @@ -3753,15 +3718,9 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_WRITE"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file handle */ - ato32(data + idx, &sz); - idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE || sz != sizeof(HANDLE)) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_HANDLE || strSz != sizeof(HANDLE)) { WLOG(WS_LOG_SFTP, "Error with file handle size"); res = err; type = WOLFSSH_FTP_FAILURE; @@ -3770,26 +3729,25 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) if (ret == WS_SUCCESS) { WMEMSET((byte*)&fd, 0, sizeof(HANDLE)); - WMEMCPY((byte*)&fd, data + idx, sz); - idx += sz; + WMEMCPY((byte*)&fd, str, strSz); /* get offset into file */ WMEMSET(&offset, 0, sizeof(OVERLAPPED)); - ato32(data + idx, &sz); - idx += UINT32_SZ; - offset.OffsetHigh = (DWORD)sz; - ato32(data + idx, &sz); - idx += UINT32_SZ; - offset.Offset = (DWORD)sz; + if (GetUint32(&strSz, data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } + offset.OffsetHigh = (DWORD)strSz; + if (GetUint32(&strSz, data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } + offset.Offset = (DWORD)strSz; /* get length to be written */ - ato32(data + idx, &sz); - idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } - if (WriteFile(fd, data + idx, sz, &bytesWritten, &offset) == 0) { + if (WriteFile(fd, str, strSz, &bytesWritten, &offset) == 0) { WLOG(WS_LOG_SFTP, "Error writing to file"); res = err; type = WOLFSSH_FTP_FAILURE; @@ -3830,13 +3788,14 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) #ifndef USE_WINDOWS_API { WFD fd; - word32 sz; int ret; word32 idx = 0; word32 ofst[2] = {0, 0}; byte* out; word32 outSz = 0; + const byte* str; + word32 strSz; char* res = NULL; char err[] = "Read File Error"; @@ -3849,38 +3808,38 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READ"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file handle */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE || sz != sizeof(WFD)) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_HANDLE || strSz != sizeof(WFD)) { return WS_BUFFER_E; } WMEMSET((byte*)&fd, 0, sizeof(WFD)); - WMEMCPY((byte*)&fd, data + idx, sz); idx += sz; + WMEMCPY((byte*)&fd, str, strSz); /* get offset into file */ - ato32(data + idx, &ofst[1]); idx += UINT32_SZ; - ato32(data + idx, &ofst[0]); idx += UINT32_SZ; + if (GetUint32(&ofst[1], data, maxSz, &idx) != WS_SUCCESS + || GetUint32(&ofst[0], data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } /* get length to be read */ - ato32(data + idx, &sz); - if (sz > maxSz - WOLFSSH_SFTP_HEADER - UINT32_SZ - idx) { + if (GetUint32(&strSz, data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } + if (strSz > maxSz - WOLFSSH_SFTP_HEADER - idx) { return WS_BUFFER_E; } /* read from handle and send data back to client */ - out = (byte*)WMALLOC(sz + WOLFSSH_SFTP_HEADER + UINT32_SZ, + out = (byte*)WMALLOC(strSz + WOLFSSH_SFTP_HEADER + UINT32_SZ, ssh->ctx->heap, DYNTYPE_BUFFER); if (out == NULL) { return WS_MEMORY_E; } - ret = WPREAD(ssh->fs, fd, out + UINT32_SZ + WOLFSSH_SFTP_HEADER, sz, ofst); - if (ret < 0 || (word32)ret > sz) { + ret = WPREAD(ssh->fs, fd, + out + UINT32_SZ + WOLFSSH_SFTP_HEADER, strSz, ofst); + if (ret < 0 || (word32)ret > strSz) { WLOG(WS_LOG_SFTP, "Error reading from file"); res = err; type = WOLFSSH_FTP_FAILURE; @@ -3904,7 +3863,7 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER); return WS_FATAL_ERROR; } - if (outSz > sz) { + if (outSz > strSz) { /* need to increase buffer size for holding status packet */ WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER); out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER); @@ -3931,12 +3890,13 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) OVERLAPPED offset; HANDLE fd; DWORD bytesRead; - word32 sz; int ret; word32 idx = 0; byte* out; word32 outSz = 0; + const byte* str; + word32 strSz; char* res = NULL; char err[] = "Read File Error"; @@ -3949,43 +3909,42 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READ"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file handle */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx || sz > WOLFSSH_MAX_HANDLE || sz != sizeof(HANDLE)) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_HANDLE || strSz != sizeof(HANDLE)) { return WS_BUFFER_E; } WMEMSET((byte*)&fd, 0, sizeof(HANDLE)); - WMEMCPY((byte*)&fd, data + idx, sz); idx += sz; + WMEMCPY((byte*)&fd, str, strSz); WMEMSET(&offset, 0, sizeof(OVERLAPPED)); /* get offset into file */ - ato32(data + idx, &sz); - idx += UINT32_SZ; - offset.OffsetHigh = (DWORD)sz; - ato32(data + idx, &sz); - idx += UINT32_SZ; - offset.Offset = (DWORD)sz; + if (GetUint32(&strSz, data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } + offset.OffsetHigh = (DWORD)strSz; + if (GetUint32(&strSz, data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } + offset.Offset = (DWORD)strSz; /* get length to be read */ - ato32(data + idx, &sz); - if (sz > maxSz - WOLFSSH_SFTP_HEADER - UINT32_SZ - idx) { + if (GetUint32(&strSz, data, maxSz, &idx) != WS_SUCCESS) { + return WS_BUFFER_E; + } + if (strSz > maxSz - WOLFSSH_SFTP_HEADER - idx) { return WS_BUFFER_E; } /* read from handle and send data back to client */ - out = (byte*)WMALLOC(sz + WOLFSSH_SFTP_HEADER + UINT32_SZ, + out = (byte*)WMALLOC(strSz + WOLFSSH_SFTP_HEADER + UINT32_SZ, ssh->ctx->heap, DYNTYPE_BUFFER); if (out == NULL) { return WS_MEMORY_E; } - if (ReadFile(fd, out + UINT32_SZ + WOLFSSH_SFTP_HEADER, sz, + if (ReadFile(fd, out + UINT32_SZ + WOLFSSH_SFTP_HEADER, strSz, &bytesRead, &offset) == 0) { if (GetLastError() == ERROR_HANDLE_EOF) { ret = 0; /* return 0 for end of file */ @@ -4019,7 +3978,7 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) &outSz) != WS_SIZE_ONLY) { return WS_FATAL_ERROR; } - if (outSz > sz) { + if (outSz > strSz) { /* need to increase buffer size for holding status packet */ WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER); out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER); @@ -4053,7 +4012,8 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) #ifndef USE_WINDOWS_API { WFD fd; - word32 sz; + word32 strSz; + const byte* str; word32 idx = 0; int ret = WS_FATAL_ERROR; @@ -4071,27 +4031,22 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_CLOSE"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file handle */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_HANDLE) { return WS_BUFFER_E; } #ifndef NO_WOLFSSH_DIR /* check if is a handle for a directory */ - if (sz == (sizeof(word32) * 2)) { - ret = wolfSSH_SFTP_RecvCloseDir(ssh, data + idx, sz); + if (strSz == (sizeof(word32) * 2)) { + ret = wolfSSH_SFTP_RecvCloseDir(ssh, (byte*)str, strSz); } if (ret != WS_SUCCESS) { #endif /* NO_WOLFSSH_DIR */ - if (sz == sizeof(WFD)) { + if (strSz == sizeof(WFD)) { WMEMSET((byte*)&fd, 0, sizeof(WFD)); - WMEMCPY((byte*)&fd, data + idx, sz); + WMEMCPY((byte*)&fd, str, strSz); #ifdef MICROCHIP_MPLAB_HARMONY ret = WFCLOSE(ssh->fs, &fd); @@ -4099,7 +4054,7 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) ret = WCLOSE(ssh->fs, fd); #endif #ifdef WOLFSSH_STOREHANDLE - if (SFTP_RemoveHandleNode(ssh, data + idx, sz) != WS_SUCCESS) { + if (SFTP_RemoveHandleNode(ssh, (byte*)str, strSz) != WS_SUCCESS) { WLOG(WS_LOG_SFTP, "Unable to remove handle from list"); ret = WS_FATAL_ERROR; } @@ -4144,7 +4099,8 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) #else /* USE_WINDOWS_API */ { HANDLE fd; - word32 sz; + word32 strSz; + const byte* str; word32 idx = 0; int ret = WS_FATAL_ERROR; @@ -4162,31 +4118,26 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_CLOSE"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file handle */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_HANDLE) { return WS_BUFFER_E; } #ifndef NO_WOLFSSH_DIR /* check if is a handle for a directory */ - if (sz == (sizeof(word32) * 2)) { - ret = wolfSSH_SFTP_RecvCloseDir(ssh, data + idx, sz); + if (strSz == (sizeof(word32) * 2)) { + ret = wolfSSH_SFTP_RecvCloseDir(ssh, (byte*)str, strSz); } if (ret != WS_SUCCESS) { #endif /* NO_WOLFSSH_DIR */ - if (sz == sizeof(HANDLE)) { + if (strSz == sizeof(HANDLE)) { WMEMSET((byte*)&fd, 0, sizeof(HANDLE)); - WMEMCPY((byte*)&fd, data + idx, sz); + WMEMCPY((byte*)&fd, str, strSz); CloseHandle(fd); ret = WS_SUCCESS; #ifdef WOLFSSH_STOREHANDLE - if (SFTP_RemoveHandleNode(ssh, data + idx, sz) != WS_SUCCESS) { + if (SFTP_RemoveHandleNode(ssh, (byte*)str, strSz) != WS_SUCCESS) { WLOG(WS_LOG_SFTP, "Unable to remove handle from list"); ret = WS_FATAL_ERROR; } @@ -4238,7 +4189,8 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) */ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) { - word32 sz; + word32 strSz; + const byte* str; char name[WOLFSSH_MAX_FILENAME]; word32 idx = 0; int ret = WS_SUCCESS; @@ -4257,18 +4209,13 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_REMOVE"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file name */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_FILENAME) { return WS_BUFFER_E; } - ret = GetAndCleanPath(ssh->sftpDefaultPath, data + idx, sz, + ret = GetAndCleanPath(ssh->sftpDefaultPath, str, strSz, name, sizeof(name)); if (ret == WS_SUCCESS) { @@ -4328,7 +4275,6 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) */ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) { - word32 sz = 0; char old[WOLFSSH_MAX_FILENAME]; char name[WOLFSSH_MAX_FILENAME]; word32 idx = 0; @@ -4336,6 +4282,8 @@ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) byte* out; word32 outSz; + const byte* str; + word32 strSz; byte type = WOLFSSH_FTP_OK; char suc[] = "Renamed File"; @@ -4348,30 +4296,22 @@ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_RENAME"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get old file name */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { ret = WS_BUFFER_E; } if (ret == WS_SUCCESS) { - ret = GetAndCleanPath(ssh->sftpDefaultPath, data + idx, sz, + ret = GetAndCleanPath(ssh->sftpDefaultPath, str, strSz, old, sizeof(old)); } if (ret == WS_SUCCESS) { - idx += sz; /* get new file name */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { ret = WS_BUFFER_E; } } if (ret == WS_SUCCESS) { - ret = GetAndCleanPath(ssh->sftpDefaultPath, data + idx, sz, + ret = GetAndCleanPath(ssh->sftpDefaultPath, str, strSz, name, sizeof(name)); } @@ -5272,7 +5212,7 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WS_SFTP_FILEATRB atr; word32 handleSz; word32 sz = 0; - byte* handle; + const byte* handle; word32 idx = 0; int ret = WS_SUCCESS; char* name = NULL; @@ -5286,17 +5226,10 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_FSTAT"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ + if (GetStringRef(&handleSz, &handle, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(data + idx, &handleSz); idx += UINT32_SZ; - if (handleSz + idx > maxSz) { - return WS_BUFFER_E; - } - handle = data + idx; - #ifdef WOLFSSH_STOREHANDLE if (handleSz != sizeof(word32)) { WLOG(WS_LOG_SFTP, "Unexpected handle size for stored handles"); @@ -5304,7 +5237,7 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) else { WS_HANDLE_LIST* cur; - cur = SFTP_GetHandleNode(ssh, handle, handleSz); + cur = SFTP_GetHandleNode(ssh, (byte*)handle, handleSz); if (cur == NULL) { WLOG(WS_LOG_SFTP, "Unknown handle"); @@ -5316,7 +5249,7 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) /* try to get file attributes and send back to client */ WMEMSET((byte*)&atr, 0, sizeof(WS_SFTP_FILEATRB)); - if (SFTP_GetAttributes_Handle(ssh, handle, handleSz, name, &atr) + if (SFTP_GetAttributes_Handle(ssh, (byte*)handle, handleSz, name, &atr) != WS_SUCCESS) { WLOG(WS_LOG_SFTP, "Unable to get fstat of file/directory"); if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, @@ -5326,7 +5259,7 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) ret = WS_BAD_FILE_E; } else { - sz = SFTP_AtributesSz(ssh, &atr); + sz = SFTP_AttributesSz(ssh, &atr); outSz = sz + WOLFSSH_SFTP_HEADER; } @@ -5367,6 +5300,7 @@ int wolfSSH_SFTP_RecvSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) int ret = WS_SUCCESS; word32 sz; + const byte* str; word32 idx = 0; byte* out = NULL; @@ -5378,19 +5312,13 @@ int wolfSSH_SFTP_RecvSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_STAT"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&sz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } /* try to get file attributes and send back to client */ if (GetAndCleanPath(ssh->sftpDefaultPath, - data + idx, sz, name, sizeof(name)) < 0) { + str, sz, name, sizeof(name)) < 0) { if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, "STAT error", "English", NULL, &outSz) != WS_SIZE_ONLY) { return WS_FATAL_ERROR; @@ -5410,7 +5338,7 @@ int wolfSSH_SFTP_RecvSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) ret = WS_BAD_FILE_E; } else { - sz = SFTP_AtributesSz(ssh, &atr); + sz = SFTP_AttributesSz(ssh, &atr); outSz = sz + WOLFSSH_SFTP_HEADER; } } @@ -5452,6 +5380,8 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) int ret = WS_SUCCESS; word32 sz; + word32 strSz; + const byte* str; word32 idx = 0; byte* out = NULL; @@ -5462,18 +5392,13 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) } WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_LSTAT"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } if (GetAndCleanPath(ssh->sftpDefaultPath, - data + idx, sz, name, sizeof(name)) < 0) { + str, strSz, name, sizeof(name)) < 0) { WLOG(WS_LOG_SFTP, "Unable to clean path"); if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, "LSTAT error", "English", NULL, &outSz) != WS_SIZE_ONLY) { @@ -5496,7 +5421,7 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) ret = WS_BAD_FILE_E; } else { - sz = SFTP_AtributesSz(ssh, &atr); + sz = SFTP_AttributesSz(ssh, &atr); outSz = sz + WOLFSSH_SFTP_HEADER; } } @@ -5648,7 +5573,8 @@ int wolfSSH_SFTP_RecvSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) char name[WOLFSSH_MAX_FILENAME]; int ret = WS_SUCCESS; - word32 sz; + word32 strSz; + const byte* str; word32 idx = 0; byte* out = NULL; @@ -5666,25 +5592,18 @@ int wolfSSH_SFTP_RecvSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_SETSTAT"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz > maxSz - idx) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) { return WS_BUFFER_E; } /* plus one to make sure is null terminated */ if (GetAndCleanPath(ssh->sftpDefaultPath, - data + idx, sz, name, sizeof(name)) < 0) { + str, strSz, name, sizeof(name)) < 0) { ret = WS_BUFFER_E; } - idx += sz; if (ret == WS_SUCCESS && - SFTP_ParseAtributes_buffer(ssh, &atr, data, &idx, maxSz) != 0) { + SFTP_ParseAttributes_buffer(ssh, &atr, data, &idx, maxSz) != 0) { type = WOLFSSH_FTP_FAILURE; res = per; ret = WS_BAD_FILE_E; @@ -5730,7 +5649,8 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) int ret = WS_SUCCESS; WFD fd; - word32 sz; + word32 strSz; + const byte* str; word32 idx = 0; byte* out = NULL; @@ -5748,21 +5668,16 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_FSETSTAT"); - if (maxSz < UINT32_SZ) { - /* not enough for an ato32 call */ - return WS_BUFFER_E; - } - /* get file handle */ - ato32(data + idx, &sz); idx += UINT32_SZ; - if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE || sz != sizeof(WFD)) { + if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS + || strSz > WOLFSSH_MAX_HANDLE || strSz != sizeof(WFD)) { return WS_BUFFER_E; } WMEMSET((byte*)&fd, 0, sizeof(WFD)); - WMEMCPY((byte*)&fd, data + idx, sz); idx += sz; + WMEMCPY((byte*)&fd, str, strSz); if (ret == WS_SUCCESS && - SFTP_ParseAtributes_buffer(ssh, &atr, data, &idx, maxSz) != 0) { + SFTP_ParseAttributes_buffer(ssh, &atr, data, &idx, maxSz) != 0) { type = WOLFSSH_FTP_FAILURE; res = per; ret = WS_BAD_FILE_E; @@ -6094,68 +6009,45 @@ static int wolfSSH_SFTP_DoStatus(WOLFSSH* ssh, word32 reqId, WS_SFTP_BUFFER* buffer) { word32 sz; + const byte* str; word32 status = WOLFSSH_FTP_FAILURE; word32 localIdx = wolfSSH_SFTP_buffer_idx(buffer); word32 maxIdx = wolfSSH_SFTP_buffer_size(buffer); byte* buf = wolfSSH_SFTP_buffer_data(buffer); WOLFSSH_UNUSED(reqId); - if (localIdx + UINT32_SZ > maxIdx) { + if (GetUint32(&status, buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_FATAL_ERROR; } - ato32(buf + localIdx, &status); - localIdx += UINT32_SZ; /* read error message */ - if (localIdx + UINT32_SZ > maxIdx) { + if (GetStringRef(&sz, &str, buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_FATAL_ERROR; } - ato32(buf + localIdx, &sz); - localIdx += UINT32_SZ; - if (sz > 0) { - byte* s; - - if (sz > maxIdx - localIdx) { - return WS_FATAL_ERROR; - } - s = (byte*)WMALLOC(sz + 1, ssh->ctx->heap, DYNTYPE_BUFFER); + byte* s = (byte*)WMALLOC(sz + 1, ssh->ctx->heap, DYNTYPE_BUFFER); if (s == NULL) { return WS_MEMORY_E; } - - /* make sure is null terminated string */ - WMEMCPY(s, buf + localIdx, sz); + WMEMCPY(s, str, sz); s[sz] = '\0'; WLOG(WS_LOG_SFTP, "Status Recv : %s", s); WFREE(s, ssh->ctx->heap, DYNTYPE_BUFFER); - localIdx += sz; } /* read language tag */ - if (localIdx + UINT32_SZ > maxIdx) { + if (GetStringRef(&sz, &str, buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_FATAL_ERROR; } - ato32(buf + localIdx, &sz); - localIdx += UINT32_SZ; - if (sz > 0) { - byte* s; - - if (sz > maxIdx - localIdx) { - return WS_FATAL_ERROR; - } - s = (byte*)WMALLOC(sz + 1, ssh->ctx->heap, DYNTYPE_BUFFER); + byte* s = (byte*)WMALLOC(sz + 1, ssh->ctx->heap, DYNTYPE_BUFFER); if (s == NULL) { return WS_MEMORY_E; } - - /* make sure is null terminated string */ - WMEMCPY(s, buf + localIdx, sz); + WMEMCPY(s, str, sz); s[sz] = '\0'; WLOG(WS_LOG_SFTP, "Status Language : %s", s); WFREE(s, ssh->ctx->heap, DYNTYPE_BUFFER); - localIdx += sz; } wolfSSH_SFTP_buffer_seek(buffer, 0, localIdx); @@ -6209,93 +6101,69 @@ void wolfSSH_SFTPNAME_list_free(WS_SFTPNAME* n) * * returns WS_SUCCESS on success */ -int SFTP_ParseAtributes_buffer(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr, byte* buf, +int SFTP_ParseAttributes_buffer(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr, byte* buf, word32* idx, word32 maxIdx) { word32 localIdx = *idx; WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB)); - if (localIdx + UINT32_SZ > maxIdx) { + /* get flags */ + if (GetUint32(&atr->flags, buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_BUFFER_E; } - /* get flags */ - ato32(buf + localIdx, &atr->flags); localIdx += UINT32_SZ; - /* check if size attribute present */ if (atr->flags & WOLFSSH_FILEATRB_SIZE) { - if (localIdx + (2*UINT32_SZ) > maxIdx) { + if (GetUint32(&atr->sz[1], buf, maxIdx, &localIdx) != WS_SUCCESS + || GetUint32(&atr->sz[0], buf, maxIdx, &localIdx) + != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(buf + localIdx, &atr->sz[1]); localIdx += UINT32_SZ; - ato32(buf + localIdx, &atr->sz[0]); localIdx += UINT32_SZ; } /* check if uid and gid attribute present */ if (atr->flags & WOLFSSH_FILEATRB_UIDGID) { - if (localIdx + (2*UINT32_SZ) > maxIdx) { + if (GetUint32(&atr->uid, buf, maxIdx, &localIdx) != WS_SUCCESS + || GetUint32(&atr->gid, buf, maxIdx, &localIdx) + != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(buf + localIdx, &atr->uid); localIdx += UINT32_SZ; - ato32(buf + localIdx, &atr->gid); localIdx += UINT32_SZ; } /* check if permissions attribute present */ if (atr->flags & WOLFSSH_FILEATRB_PERM) { - if (localIdx + UINT32_SZ > maxIdx) { + if (GetUint32(&atr->per, buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(buf + localIdx, &atr->per); localIdx += UINT32_SZ; } /* check if time attribute present */ if (atr->flags & WOLFSSH_FILEATRB_TIME) { - if (localIdx + (2*UINT32_SZ) > maxIdx) { + if (GetUint32(&atr->atime, buf, maxIdx, &localIdx) != WS_SUCCESS + || GetUint32(&atr->mtime, buf, maxIdx, &localIdx) + != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(buf + localIdx, &atr->atime); localIdx += UINT32_SZ; - ato32(buf + localIdx, &atr->mtime); localIdx += UINT32_SZ; } /* check if extended attributes are present */ if (atr->flags & WOLFSSH_FILEATRB_EXT) { word32 i; - word32 sz; - if (localIdx + UINT32_SZ > maxIdx) { + if (GetUint32(&atr->extCount, buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(buf + localIdx, &atr->extCount); localIdx += UINT32_SZ; for (i = 0; i < atr->extCount; i++) { - /* @TODO in the process of storing attributes */ - if (localIdx + UINT32_SZ > maxIdx) { + /* @TODO extension type, in the process of storing attributes */ + if (GetSkip(buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(buf + localIdx, &sz); localIdx += UINT32_SZ; - - if (sz > 0) { - if (localIdx + sz > maxIdx) { - return WS_BUFFER_E; - } - /* @TODO extension type */ - localIdx += sz; - } - - /* @TODO in the process of storing attributes */ - if (localIdx + UINT32_SZ > maxIdx) { + /* @TODO extension data, in the process of storing attributes */ + if (GetSkip(buf, maxIdx, &localIdx) != WS_SUCCESS) { return WS_BUFFER_E; } - ato32(buf + localIdx, &sz); localIdx += UINT32_SZ; - - if (sz > 0) { - if (localIdx + sz > maxIdx) { - return WS_BUFFER_E; - } - /* @TODO extension data */ - localIdx += sz; - } } } @@ -6310,7 +6178,7 @@ int SFTP_ParseAtributes_buffer(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr, byte* buf, * * returns WS_SUCCESS on success */ -int SFTP_ParseAtributes(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr) +int SFTP_ParseAttributes(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr) { byte buf[UINT32_SZ * 2]; int ret; @@ -6546,6 +6414,9 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh) while (count > 0) { word32 sz; + const byte* str; + byte* nameBuf = wolfSSH_SFTP_buffer_data(&state->buffer); + word32 nameMax = wolfSSH_SFTP_buffer_size(&state->buffer); WS_SFTPNAME* tmp = wolfSSH_SFTPNAME_new(ssh->ctx->heap); count--; @@ -6562,8 +6433,9 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh) n = tmp; /* get filename size and name */ - if (wolfSSH_SFTP_buffer_ato32(&state->buffer, &sz) != - WS_SUCCESS) { + localIdx = wolfSSH_SFTP_buffer_idx(&state->buffer); + if (GetStringRef(&sz, &str, nameBuf, nameMax, &localIdx) + != WS_SUCCESS) { ret = WS_BUFFER_E; break; } @@ -6575,24 +6447,13 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh) ret = WS_MEMORY_E; break; } - - if (wolfSSH_SFTP_buffer_idx(&state->buffer) + sz > - wolfSSH_SFTP_buffer_size(&state->buffer)) { - ret = WS_FATAL_ERROR; - break; - } - WMEMCPY(tmp->fName, - wolfSSH_SFTP_buffer_data(&state->buffer) + - wolfSSH_SFTP_buffer_idx(&state->buffer), - sz); - wolfSSH_SFTP_buffer_seek(&state->buffer, - wolfSSH_SFTP_buffer_idx(&state->buffer), sz); + WMEMCPY(tmp->fName, str, sz); tmp->fName[sz] = '\0'; } /* get longname size and name */ - if (wolfSSH_SFTP_buffer_ato32(&state->buffer, &sz) != - WS_SUCCESS) { + if (GetStringRef(&sz, &str, nameBuf, nameMax, &localIdx) + != WS_SUCCESS) { ret = WS_BUFFER_E; break; } @@ -6604,27 +6465,13 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh) ret = WS_MEMORY_E; break; } - - if (wolfSSH_SFTP_buffer_idx(&state->buffer) + sz > - wolfSSH_SFTP_buffer_size(&state->buffer)) { - ret = WS_FATAL_ERROR; - break; - } - WMEMCPY(tmp->lName, - wolfSSH_SFTP_buffer_data(&state->buffer) + - wolfSSH_SFTP_buffer_idx(&state->buffer), - sz); - wolfSSH_SFTP_buffer_seek(&state->buffer, - wolfSSH_SFTP_buffer_idx(&state->buffer), sz); + WMEMCPY(tmp->lName, str, sz); tmp->lName[sz] = '\0'; } /* get attributes */ - localIdx = wolfSSH_SFTP_buffer_idx(&state->buffer); - ret = SFTP_ParseAtributes_buffer(ssh, &tmp->atrb, - wolfSSH_SFTP_buffer_data(&state->buffer), - &localIdx, - wolfSSH_SFTP_buffer_size(&state->buffer)); + ret = SFTP_ParseAttributes_buffer(ssh, &tmp->atrb, + nameBuf, &localIdx, nameMax); wolfSSH_SFTP_buffer_seek(&state->buffer, 0, localIdx); if (ret != WS_SUCCESS) { break; @@ -7121,7 +6968,7 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type) wolfSSH_SFTP_buffer_rewind(&state->buffer); if (state->type == WOLFSSH_FTP_ATTRS) { localIdx = wolfSSH_SFTP_buffer_idx(&state->buffer); - ret = SFTP_ParseAtributes_buffer(ssh, atr, + ret = SFTP_ParseAttributes_buffer(ssh, atr, wolfSSH_SFTP_buffer_data(&state->buffer), &localIdx, wolfSSH_SFTP_buffer_size(&state->buffer)); @@ -7236,7 +7083,7 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr) switch (state->state) { case STATE_SET_ATR_INIT: dirSz = (int)WSTRLEN(dir); - atrSz = SFTP_AtributesSz(ssh, atr); + atrSz = SFTP_AttributesSz(ssh, atr); if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, dirSz + atrSz + WOLFSSH_SFTP_HEADER + UINT32_SZ) != WS_SUCCESS) {