From c4acd86df5ea04abed13ace9db99b0e8d55ef985 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Sun, 2 Mar 2025 15:17:16 -0700 Subject: [PATCH] progress on microchip fs port --- src/io.c | 1 - src/port.c | 37 +++++++++++- src/ssh.c | 6 ++ src/wolfsftp.c | 137 +++++++++++++++++++++++++++++++++++++++++++-- wolfssh/internal.h | 2 +- wolfssh/port.h | 31 ++++++---- 6 files changed, 194 insertions(+), 20 deletions(-) diff --git a/src/io.c b/src/io.c index 91899b69..acc36bce 100644 --- a/src/io.c +++ b/src/io.c @@ -135,7 +135,6 @@ void* wolfSSH_GetIOWriteCtx(WOLFSSH* ssh) static int errno; #elif defined(MICROCHIP_MPLAB_HARMONY) #include "tcpip/tcpip.h" - #include "sys/errno.h" #include #elif defined(WOLFSSL_NUCLEUS) #include "nucleus.h" diff --git a/src/port.c b/src/port.c index 05c80314..bfb9aec6 100644 --- a/src/port.c +++ b/src/port.c @@ -47,6 +47,16 @@ Flags: #if !defined(NO_FILESYSTEM) && !defined(WOLFSSH_USER_FILESYSTEM) && \ !defined(WOLFSSH_ZEPHYR) +#if defined(MICROCHIP_MPLAB_HARMONY) +int wfopen(WFILE* f, const char* filename, SYS_FS_FILE_OPEN_ATTRIBUTES mode) +{ + if (f != NULL) { + *f = SYS_FS_FileOpen(filename, mode); + return *f == WBADFILE; + } + return 1; +} +#else int wfopen(WFILE** f, const char* filename, const char* mode) { #ifdef USE_WINDOWS_API @@ -89,7 +99,7 @@ int wfopen(WFILE** f, const char* filename, const char* mode) return 1; #endif } - +#endif /* If either pread() or pwrite() are missing, use the local versions. */ #if (defined(USE_OSE_API) || \ @@ -107,7 +117,32 @@ int wfopen(WFILE** f, const char* filename, const char* mode) defined(FREESCALE_MQX) || defined(WOLFSSH_ZEPHYR) /* This is current inline in the source. */ + #elif defined(MICROCHIP_MPLAB_HARMONY) + int wPwrite(WFD fd, unsigned char* buf, unsigned int sz, + const unsigned int* shortOffset) + { + int ret; + + ret = (int)WFSEEK(NULL, &fd, shortOffset[0], SYS_FS_SEEK_SET); + if (ret != -1) + ret = (int)WFWRITE(NULL, &fd, buf, sz); + + return ret; + } + + int wPread(WFD fd, unsigned char* buf, unsigned int sz, + const unsigned int* shortOffset) + { + int ret; + + ret = (int)WFSEEK(NULL, &fd, shortOffset[0], SYS_FS_SEEK_SET); + if (ret != -1) + ret = (int)WFREAD(NULL, &fd, buf, sz); + + return ret; + } + #elif defined(WOLFSSH_LOCAL_PREAD_PWRITE) int wPwrite(WFD fd, unsigned char* buf, unsigned int sz, diff --git a/src/ssh.c b/src/ssh.c index 38e07beb..ab0ed7aa 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -1908,8 +1908,14 @@ int wolfSSH_ReadKey_file(const char* name, isPrivate == NULL) return WS_BAD_ARGUMENT; +#ifdef MICROCHIP_MPLAB_HARMONY + ret = WFOPEN(NULL, &file, name, WOLFSSH_O_RDONLY); + if (ret != 0 || *file == WBADFILE) return WS_BAD_FILE_E; +#else ret = WFOPEN(NULL, &file, name, "rb"); if (ret != 0 || file == WBADFILE) return WS_BAD_FILE_E; +#endif + if (WFSEEK(NULL, file, 0, WSEEK_END) != 0) { WFCLOSE(NULL, file); return WS_BAD_FILE_E; diff --git a/src/wolfsftp.c b/src/wolfsftp.c index 24a35329..832de07d 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -3116,6 +3116,26 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out, return WS_SUCCESS; } +#elif defined(MICROCHIP_MPLAB_HARMONY) + +/* helper function that gets file information from reading directory + * + * returns WS_SUCCESS on success + */ +static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out, + char* dirName) +{ + //@TODO + + /* Use attributes and fName to create long name */ + if (SFTP_CreateLongName(out) != WS_SUCCESS) { + WLOG(WS_LOG_DEBUG, "Error creating long name for %s", out->fName); + WFREE(out->fName, out->heap, DYNTYPE_SFTP); + return WS_FATAL_ERROR; + } + return WS_SUCCESS; +} + #else /* helper function that gets file information from reading directory @@ -4846,7 +4866,8 @@ int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz, #elif defined(WOLFSSH_USER_FILESYSTEM) /* User-defined I/O support */ -#else + +#elif defined(MICROCHIP_MPLAB_HARMONY) /* @TODO can be overriden by user for portability * NOTE: if atr->flags is set to a value of 0 then no attributes are set. @@ -4857,6 +4878,104 @@ int SFTP_GetAttributes(void* fs, const char* fileName, WS_SFTP_FILEATRB* atr, byte noFollow, void* heap) { WSTAT_T stats; + WFILE f; + int ret; + + WOLFSSH_UNUSED(heap); + WOLFSSH_UNUSED(fs); + + ret = WFOPEN(NULL, &f, filename, WOLFSSH_O_RDONLY); + + if (noFollow) { + /* Note, for windows, we treat WSTAT and WLSTAT the same. */ + if (WLSTAT(fs, fileName, &stats) != 0) { + return WS_BAD_FILE_E; + } + } + else { + if (WSTAT(fs, fileName, &stats) != 0) { + return WS_BAD_FILE_E; + } + } + WFCLOSE(NULL, &f); + + WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB)); + +// atr->flags |= WOLFSSH_FILEATRB_SIZE; +// atr->sz[0] = (word32)(stats.st_size & 0xFFFFFFFF); +//#if SIZEOF_OFF_T == 8 +// atr->sz[1] = (word32)((stats.st_size >> 32) & 0xFFFFFFFF); +//#endif +// +// atr->flags |= WOLFSSH_FILEATRB_UIDGID; +// atr->uid = (word32)stats.st_uid; +// atr->gid = (word32)stats.st_gid; +// +// atr->flags |= WOLFSSH_FILEATRB_PERM; +// atr->per = (word32)stats.st_mode; +// +// atr->flags |= WOLFSSH_FILEATRB_TIME; +// atr->atime = (word32)stats.st_atime; +// atr->mtime = (word32)stats.st_mtime; + + /* @TODO handle attribute extensions */ + + return WS_SUCCESS; +} + + +/* @TODO can be overriden by user for portability + * Gets attributes based on file descriptor + * NOTE: if atr->flags is set to a value of 0 then no attributes are set. + * Fills out a WS_SFTP_FILEATRB structure + * returns WS_SUCCESS on success + */ +int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz, + WS_SFTP_FILEATRB* atr) +{ + WSTAT_T stats; + + if (handleSz != sizeof(word32)) { + WLOG(WS_LOG_SFTP, "Unexpected handle size SFTP_GetAttributes_Handle()"); + } + + if (WSTAT(ssh->fs, *(int*)handle, &stats) != 0) { + return WS_BAD_FILE_E; + } + + WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB)); + +// atr->flags |= WOLFSSH_FILEATRB_SIZE; +// atr->sz[0] = (word32)(stats.st_size & 0xFFFFFFFF); +//#if SIZEOF_OFF_T == 8 +// atr->sz[1] = (word32)((stats.st_size >> 32) & 0xFFFFFFFF); +//#endif + +// atr->flags |= WOLFSSH_FILEATRB_UIDGID; +// atr->uid = (word32)stats.st_uid; +// atr->gid = (word32)stats.st_gid; +// +// atr->flags |= WOLFSSH_FILEATRB_PERM; +// atr->per = (word32)stats.st_mode; +// +// atr->flags |= WOLFSSH_FILEATRB_TIME; +// atr->atime = (word32)stats.st_atime; +// atr->mtime = (word32)stats.st_mtime; + + WOLFSSH_UNUSED(ssh); + return WS_SUCCESS; +} + +#else + +/* NOTE: if atr->flags is set to a value of 0 then no attributes are set. + * Fills out a WS_SFTP_FILEATRB structure + * returns WS_SUCCESS on success + */ +int SFTP_GetAttributes(void* fs, const char* fileName, WS_SFTP_FILEATRB* atr, + byte noFollow, void* heap) +{ + WSTAT_T stats; WOLFSSH_UNUSED(heap); WOLFSSH_UNUSED(fs); @@ -8656,12 +8775,12 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from, case STATE_GET_OPEN_LOCAL: WLOG(WS_LOG_SFTP, "SFTP GET STATE: OPEN LOCAL"); - #ifndef USE_WINDOWS_API + #ifdef MICROCHIP_MPLAB_HARMONY if (state->gOfst[0] > 0 || state->gOfst[1] > 0) - ret = WFOPEN(ssh->fs, &state->fl, to, "ab"); + ret = WFOPEN(ssh->fs, &state->fl, to, WOLFSSH_O_APPEND); else - ret = WFOPEN(ssh->fs, &state->fl, to, "wb"); - #else /* USE_WINDOWS_API */ + ret = WFOPEN(ssh->fs, &state->fl, to, WOLFSSH_O_WRONLY); + #elif defined(USE_WINDOWS_API) { DWORD desiredAccess = GENERIC_WRITE; if (state->gOfst > 0) @@ -8676,6 +8795,11 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from, state->offset.OffsetHigh = state->gOfst[1]; state->offset.Offset = state->gOfst[0]; } + #else + if (state->gOfst[0] > 0 || state->gOfst[1] > 0) + ret = WFOPEN(ssh->fs, &state->fl, to, "ab"); + else + ret = WFOPEN(ssh->fs, &state->fl, to, "wb"); #endif /* USE_WINDOWS_API */ if (ret != 0) { WLOG(WS_LOG_SFTP, "Unable to open output file"); @@ -8873,7 +8997,8 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume, } } } - ret = WFOPEN(ssh->fs, &state->fl, from, "rb"); + //ret = WFOPEN(ssh->fs, &state->fl, from, "rb"); + ret = WFOPEN(ssh->fs, &state->fl, from, WOLFSSH_O_RDONLY); if (ret != 0) { WLOG(WS_LOG_SFTP, "Unable to open input file"); ssh->error = WS_SFTP_FILE_DNE; diff --git a/wolfssh/internal.h b/wolfssh/internal.h index e29461f8..1225b1a6 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -404,7 +404,7 @@ enum NameIdType { #define MAX_KEY_EXCHANGE 2 #define MAX_PUBLIC_KEY 1 #define MIN_RSA_SIG_SZ 2 -#define MAX_HMAC_SZ WC_SHA512_DIGEST_SIZE +#define MAX_HMAC_SZ WC_MAX_DIGEST_SIZE #define MIN_BLOCK_SZ 8 #define COOKIE_SZ 16 #define PAD_LENGTH_SZ 1 diff --git a/wolfssh/port.h b/wolfssh/port.h index 551d2847..6fe9a520 100644 --- a/wolfssh/port.h +++ b/wolfssh/port.h @@ -390,34 +390,40 @@ extern "C" { #define WCHDIR(fs,b) z_fs_chdir((b)) #elif defined(MICROCHIP_MPLAB_HARMONY) - #include #include + #include "system/fs/sys_fs.h" + #define WFFLUSH(s) SYS_FS_FileSync((s)) #define WFILE SYS_FS_HANDLE #define FLUSH_STD(a) + WOLFSSH_API int wfopen(WFILE* f, const char* filenmae, + SYS_FS_FILE_OPEN_ATTRIBUTES mode); //int z_fs_chdir(const char *path); /* Use wolfCrypt z_fs_open and z_fs_close */ - #define WFOPEN(fs,f,fn,m) (*(f) = SYS_FS_FileOpen((fn), (m))) - #define WFCLOSE(fs,f) SYS_FS_FileClose((f)) - #define WFREAD(fs,b,s,a,f) SYS_FS_FileRead((f),(b),(s)*(a)) - #define WFWRITE(fs,b,s,a,f) SYS_FS_FileWrite((f)), (b), (s)) - #define WFSEEK(fs,s,o,w) SYS_FS_FileSeek((s),(o),(w)) - #define WFTELL(fs,s) SYS_FS_FileTell((s)) - #define WREWIND(fs,s) SYS_FS_FileSeek((s), 0, SYS_FS_SEEK_SET) + #define WFOPEN(fs,f,fn,m) wfopen(*(f),(fn),(m)) + #define WFCLOSE(fs,f) SYS_FS_FileClose(*(f)) + #define WFREAD(fs,b,s,a,f) SYS_FS_FileRead(*(f),(b),(s)*(a)) + #define WFWRITE(fs,b,s,a,f) SYS_FS_FileWrite(*(f),(b),(s)) + #define WFSEEK(fs,s,o,w) SYS_FS_FileSeek(*(s),(o),(w)) + #define WFTELL(fs,s) SYS_FS_FileTell(*(s)) + #define WREWIND(fs,s) SYS_FS_FileSeek(*(s), 0, SYS_FS_SEEK_SET) #define WSEEK_END SYS_FS_SEEK_END - #define WBADFILE NULL + #define WBADFILE SYS_FS_HANDLE_INVALID #define WCHMOD(fs,f,m) (0) /* Not available */ + #define WFCHMOD(fs,fd,m) (0) #undef WFGETS #define WFGETS(b,s,f) SYS_FS_FileStringGet((f), (b), (s)) #undef WFPUTS #define WFPUTS(b,s) SYS_FS_FileStringPut((f), (b), (s)) #define WUTIMES(a,b) (0) /* Not ported yet */ + #define WSETTIME(fs,f,a,m) (0) + #define WFSETTIME(fs,fd,a,m) (0) #define WCHDIR(fs,b) SYS_FS_DirectryChange((b)) #elif defined(WOLFSSH_USER_FILESYSTEM) @@ -1362,8 +1368,8 @@ extern "C" { #define WDIR SYS_FS_HANDLE #define WSTAT_T SYS_FS_FSTAT - #define WOPENDIR(fs,h,c,d) SYS_FS_DirOpen((d)) - #define WCLOSEDIR(fs,d) SYS_FS_DirOpen((d)) + #define WOPENDIR(fs,h,c,d) (*(c) = SYS_FS_DirOpen((d))) + #define WCLOSEDIR(fs,d) SYS_FS_DirClose(*(d)) #define WMKDIR(fs,p,m) SYS_FS_DirectoryMake((p)) #define WRMDIR(fs,d) SYS_FS_FileDirectoryRemove((d)) #define WSTAT(fs,p,b) SYS_FS_FileStat((p),(b)) @@ -1380,6 +1386,9 @@ extern "C" { #define WOLFSSH_O_EXCL 0 /* Our "file descriptor" wrapper */ + + //@TODO maybe this should be int or something to handle DIR to? + #define WFD SYS_FS_HANDLE int wPwrite(WFD, unsigned char*, unsigned int, const unsigned int*); int wPread(WFD, unsigned char*, unsigned int, const unsigned int*); #define WPWRITE(fs,fd,b,s,o) wPwrite((fd),(b),(s),(o))