diff --git a/ide/mplabx/README.md b/ide/mplabx/README.md
index cdb6d339b..158ee02aa 100644
--- a/ide/mplabx/README.md
+++ b/ide/mplabx/README.md
@@ -1,54 +1,145 @@
# wolfSSH MPLABX
-This is example project to create a wolfSSH library and example code for adding
-a wolfSSH echoserver to a MPLABX project.
+This is an example project demonstrating how to build the `wolfSSH` library and
+ use it to add a SSH server to an MPLABX project.
-Tested on a ATSAMV71Q21B with MPLABX version 6.20.
+Tested on an **ATSAMV71Q21B** using **MPLABX version 6.20**.
-### Building wolfSSH library
+---
-The library project is located at ide/mplabx/wolfssh.X
+## Building the wolfSSH Library
-- First open wolfssh.X with MPLABX IDE then click on "CM" content manager and
-import the ide/mplabx/wolfssh.X/mcc-manifest-generated-success.yml file.
-- Click apply.
-- Next click "MCC" and "generate".
-- To build from the command line, do the following after the XC32 toolchain has
-been installed.
+The library project is located at:
```
+
+ide/mplabx/wolfssh.X
+
+```
+
+### Using MPLABX IDE
+
+1. Open the `wolfssh.X` project in MPLABX.
+2. Click **CM (Content Manager)** and import the manifest:
+
+```
+
+ide/mplabx/wolfssh.X/mcc-manifest-generated-success.yml
+
+````
+
+3. Click **Apply**.
+4. Click **MCC** and then **Generate**.
+5. Build the project via the IDE (hammer icon or `Run → Build Project`).
+
+### Using the Command Line
+
+After installing the XC32 toolchain:
+
+```sh
cd ide/mplabx/wolfssh.X
make
+````
+
+This produces:
+
+```
+ide/mplabx/wolfssh.X/dist/default/production/wolfssh.X.a
```
-- To build using the IDE open the project ide/mplabx/wolfssh.X and click build.
+> **Important:** The application and wolfSSL must be built using the **same**
+ `user_settings.h` as used for the wolfSSH library. Mismatched macros can result
+ in undefined behavior or crashes.
+---
-This will produce a wolfssh.X.a library in the directory
-ide/mplabx/wolfssh.X/dist/default/production/wolfssh.X.a
+## Building the Example Application
+
+### Steps:
+
+1. **Set Preprocessor Macros**:
+
+ * Define `WOLFSSL_USER_SETTINGS`.
+ * Add include path to `ide/mplabx/user_settings.h`.
+
+2. **Remove** the generated `app.c` from Source Files.
+
+3. **Link the wolfSSH Library**:
+
+ * Go to **Project Properties → Libraries → Add Library/Object File**.
+ * Select `wolfssh.X.a`.
-The application and wolfSSL must be built with the same user_settings.h as the
-wolfSSH library was built with! Differences in macro's defined for
-configuration will cause undefined behavior and potential crashes.
+4. **Add Source File**:
-### Building an example app
+ * Right-click the project → **Add Existing Item**.
+ * Select `ide/mplabx/wolfssh.c`.
-1) Adjust the "Preprocessor macros" to include WOLFSSL_USER_SETTINGS and add an
- include path to ide/mplabx/user_settings.h.
-2) Remove the generated app.c from Source File
-3) Link to the wolfssh.X.a library. Properties->Libraries->Add Library/Object
- File...
-4) Right click on the project and add existing item. Select ide/mplabx/wolfssh.c
-5) Increase the heap size to 200,000 by right clicking on the project, selecting
- "Properties"->"x32-ld"
+5. **Increase Heap Size**:
+
+ * Right-click the project → **Properties → XC32-ld**.
+ * Set heap size to at least **200,000**.
+
+### Notes
+
+* Tested with heap and stack sizes of **200,000**.
+* TX buffer size: **1024 bytes**.
+* Tested with `wolfSSH version 1.4.20`.
+
+After flashing the board, a wolfSSH server will be listening on port **22**.
+You can connect using the provided client:
+
+```sh
+./examples/client/client -u jill -P upthehill -h 192.168.1.120 -p 22
+```
+
+---
+
+## Overriding the File System for SFTP
+
+This example shows how to override the SFTP file system interface and apply
+ restrictions based on the logged-in user. It uses Microchip's file system but
+ the approach is generic.
+
+### Enabling a Custom File System
+
+1. **Define `WOLFSSH_USER_FILESYSTEM`** in `user_settings.h`.
+
+2. **Provide `myFilesystem.h`**:
+
+ * Required when `WOLFSSH_USER_FILESYSTEM` is defined.
+ * Ensure it's in your include path (e.g., move it to the wolfSSH `include/` directory).
+
+3. **Add `myFilesystem.c`** to the wolfSSH project.
+
+4. **Recompile** the library.
+
+### Example File Operation Categories
+
+* **Safe operations**: Navigation, file downloads.
+* **Restricted operations**: Modifying or deleting files.
+
+Set the custom file system handle as follows:
+
+```c
+wolfSSH_SetFilesystemHandle(ssh, (void*)ssh);
+```
+
+### Integration Example (in `wolfssh.c`)
+
+```c
+case APP_SSH_SFTP_START:
+ SYS_CONSOLE_PRINT("Setting starting SFTP directory to [%s]\r\n", "/mnt/myDrive1");
+ if (wolfSSH_SFTP_SetDefaultPath(ssh, "/mnt/myDrive1") != WS_SUCCESS) {
+ SYS_CONSOLE_PRINT("Error setting starting directory\r\n");
+ SYS_CONSOLE_PRINT("Error = %d\r\n", wolfSSH_get_error(ssh));
+ appData.state = APP_SSH_CLEANUP;
+ }
+ wolfSSH_SetFilesystemHandle(ssh, (void*)ssh);
+ appData.state = APP_SSH_SFTP;
+ break;
+```
-Notes:
+### Privileged Access
-For the current project this was tested with the heap and stack set to 200,000
- each. This was not trimed to see the minumum possible heap and stack usage yet.
- The TX buffer size used was set to 1024. The example was developed with wolfssh
- version 1.4.20.
+Logging in as user `admin` with password `fetchapail` enables restricted operations.
-After building and flashing the board a wolfSSH echoserver will be open on port
- 22 which can be connected to by using the example client bundled with wolfSSH.
- ```./examples/client/client -u jill -P upthehill -h 192.168.1.120 -p 22```
diff --git a/ide/mplabx/myFilesystem.c b/ide/mplabx/myFilesystem.c
new file mode 100644
index 000000000..10995b708
--- /dev/null
+++ b/ide/mplabx/myFilesystem.c
@@ -0,0 +1,319 @@
+/* myFilesystem.c
+ *
+ * Copyright (C) 2014-2025 wolfSSL Inc.
+ *
+ *
+ * wolfSSH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wolfSSH. If not, see .
+ */
+
+#include "myFilesystem.h"
+#include
+#include
+#include
+#include
+#include
+#include "system/fs/sys_fs.h"
+
+#ifdef WOLFSSH_USER_FILESYSTEM
+/*******************************************************************************
+ Restricted function implementations
+*******************************************************************************/
+
+/* helper function to check if the user is allowed to do an operation */
+static int isUserAllowed(void* fs)
+{
+ char* currentUser;
+ WOLFSSH* ssh = (WOLFSSH*)fs;
+
+ if (ssh == NULL) {
+ return 0;
+ }
+
+ currentUser = wolfSSH_GetUsername(ssh);
+ if (currentUser && XSTRCMP(currentUser, "admin") == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+
+int wFwrite(void *fs, unsigned char* b, int s, int a, WFILE* f)
+{
+ if (isUserAllowed(fs)) {
+ return SYS_FS_FileWrite(*f, b, s * a);
+ }
+ else {
+ return -1;
+ }
+}
+
+
+int wChmod(void* fs, const char* path, int mode)
+{
+ SYS_FS_RESULT ret;
+ SYS_FS_FILE_DIR_ATTR attr = 0;
+
+ if (isUserAllowed(fs)) {
+ /* mode is the octal value i.e 666 is 0x1B6 */
+ if ((mode & 0x180) != 0x180) { /* not octal 6XX read only */
+ attr |= SYS_FS_ATTR_RDO;
+ }
+
+ /* toggle the read only attribute */
+ ret = SYS_FS_FileDirectoryModeSet(path, attr, SYS_FS_ATTR_RDO);
+ if (ret != SYS_FS_RES_SUCCESS) {
+ return -1;
+ }
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+
+int wPwrite(void* fs, WFD fd, unsigned char* buf, unsigned int sz,
+ const unsigned int* shortOffset)
+{
+ int ret = -1;
+
+ if (isUserAllowed(fs)) {
+ ret = (int)WFSEEK(NULL, &fd, shortOffset[0], SYS_FS_SEEK_SET);
+ if (ret != -1) {
+ ret = (int)WFWRITE(NULL, buf, 1, sz, &fd);
+ }
+ }
+
+ return ret;
+}
+
+int wMkdir(void* fs, unsigned char* path)
+{
+ if (isUserAllowed(fs)) {
+ return SYS_FS_DirectoryMake(path);
+ }
+ else {
+ return -1;
+ }
+}
+
+
+int wRmdir(void* fs, unsigned char* dir)
+{
+ if (isUserAllowed(fs)) {
+ return SYS_FS_FileDirectoryRemove(dir);
+ }
+ else {
+ return -1;
+ }
+}
+
+int wRemove(void* fs, unsigned char* dir)
+{
+ if (isUserAllowed(fs)) {
+ return SYS_FS_FileDirectoryRemove(dir);
+ }
+ else {
+ return -1;
+ }
+}
+
+
+int wRename(void* fs, unsigned char* orig, unsigned char* newName)
+{
+ if (isUserAllowed(fs)) {
+ return SYS_FS_FileDirectoryRenameMove(orig, newName);
+ }
+ else {
+ return -1;
+ }
+}
+
+
+/*******************************************************************************
+ "SAFE" function implementations any user is ok
+*******************************************************************************/
+int wDirOpen(void* heap, WDIR* dir, const char* path)
+{
+ *dir = SYS_FS_DirOpen(path);
+ if (*dir == SYS_FS_HANDLE_INVALID) {
+ return -1;
+ }
+ return 0;
+}
+
+int wStat(const char* path, WSTAT_T* stat)
+{
+ int ret;
+
+ WMEMSET(stat, 0, sizeof(WSTAT_T));
+ ret = SYS_FS_FileStat(path, stat);
+
+ if (ret != SYS_FS_RES_SUCCESS) {
+ WLOG(WS_LOG_SFTP,
+ "Return from SYS_FS_fileStat [%s] = %d, expecting %d",
+ path, ret, SYS_FS_RES_SUCCESS);
+ WLOG(WS_LOG_SFTP, "SYS error reason = %d", SYS_FS_Error());
+ return -1;
+ }
+ else {
+ return 0;
+ }
+ return 0;
+}
+
+char* wGetCwd(char *r, int rSz)
+{
+ SYS_FS_RESULT ret;
+ ret = SYS_FS_CurrentWorkingDirectoryGet(r, rSz);
+ if (ret != SYS_FS_RES_SUCCESS) {
+ return r;
+ }
+ return r;
+}
+
+
+int wfopen(WFILE* f, const char* filename, SYS_FS_FILE_OPEN_ATTRIBUTES mode)
+{
+ if (f != NULL) {
+ *f = SYS_FS_FileOpen(filename, mode);
+ if (*f == WBADFILE) {
+ WLOG(WS_LOG_SFTP, "Failed to open file %s", filename);
+ return 1;
+ }
+ else {
+ WLOG(WS_LOG_SFTP, "Opened file %s", filename);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+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, buf, 1, sz, &fd);
+
+ return ret;
+}
+
+
+/*******************************************************************************
+ File attribute functions
+*******************************************************************************/
+
+typedef struct WS_HANDLE_LIST {
+ byte handle[WOLFSSH_MAX_HANDLE];
+ word32 handleSz;
+ char name[WOLFSSH_MAX_FILENAME];
+ struct WS_HANDLE_LIST* next;
+ struct WS_HANDLE_LIST* prev;
+} WS_HANDLE_LIST;
+
+int SFTP_GetAttributesStat(void* atrIn, void* statsIn)
+{
+ WS_SFTP_FILEATRB* atr = (WS_SFTP_FILEATRB*)atrIn;
+ WSTAT_T* stats = (WSTAT_T*)statsIn;
+ /* file size */
+ atr->flags |= WOLFSSH_FILEATRB_SIZE;
+ atr->sz[0] = (word32)stats->fsize;
+ atr->sz[1] = (word32)(0);
+
+ /* file permissions */
+ atr->flags |= WOLFSSH_FILEATRB_PERM;
+ if ((stats->fattrib & SYS_FS_ATTR_DIR) & SYS_FS_ATTR_MASK) {
+ atr->per |= 0x41ED; /* 755 with directory */
+ }
+ else {
+ atr->per |= 0x8000;
+ }
+
+ /* check for read only */
+ if ((stats->fattrib & SYS_FS_ATTR_RDO) & SYS_FS_ATTR_MASK) {
+ atr->per |= 0x124; /* octal 444 */
+ }
+ else {
+ atr->per |= 0x1ED; /* octal 755 */
+ }
+
+ /* last modified time */
+ atr->mtime = stats->ftime;
+
+ return WS_SUCCESS;
+}
+
+
+static int SFTP_GetAttributesHelper(WS_SFTP_FILEATRB* atr, const char* fName)
+{
+ WSTAT_T stats;
+ SYS_FS_RESULT res;
+ char buffer[255];
+
+ WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
+ WMEMSET(buffer, 0, sizeof(buffer));
+ res = SYS_FS_CurrentDriveGet(buffer);
+ if (res == SYS_FS_RES_SUCCESS) {
+ if (WSTRCMP(fName, buffer) == 0) {
+ atr->flags |= WOLFSSH_FILEATRB_PERM;
+ atr->per |= 0x41ED; /* 755 with directory */
+ atr->per |= 0x1ED; /* octal 755 */
+
+ atr->flags |= WOLFSSH_FILEATRB_SIZE;
+ atr->sz[0] = 0;
+ atr->sz[1] = 0;
+
+ atr->mtime = 30912;
+ WLOG(WS_LOG_SFTP, "Setting mount point as directory");
+ return WS_SUCCESS;
+ }
+ }
+
+ if (WSTAT(ssh->fs, fName, &stats) != 0) {
+ WLOG(WS_LOG_SFTP, "Issue with WSTAT call");
+ return WS_BAD_FILE_E;
+ }
+ return SFTP_GetAttributesStat(atr, &stats);
+}
+
+
+/* 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, void* atr,
+ byte noFollow, void* heap)
+{
+ WOLFSSH_UNUSED(heap);
+ WOLFSSH_UNUSED(fs);
+
+ return SFTP_GetAttributesHelper((WS_SFTP_FILEATRB*)atr, fileName);
+}
+
+
+/* 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(void* ssh, unsigned char* handle, int handleSz,
+ char* name, void* atr)
+{
+ return SFTP_GetAttributesHelper((WS_SFTP_FILEATRB*)atr, name);
+}
+#endif /* WOLFSSH_USER_FILESYSTEM */
\ No newline at end of file
diff --git a/ide/mplabx/myFilesystem.h b/ide/mplabx/myFilesystem.h
new file mode 100644
index 000000000..cdf8f94ef
--- /dev/null
+++ b/ide/mplabx/myFilesystem.h
@@ -0,0 +1,143 @@
+/* myFilesystem.h
+ *
+ * Copyright (C) 2014-2025 wolfSSL Inc.
+ *
+ *
+ * wolfSSH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wolfSSH. If not, see .
+ */
+
+
+/*
+ * The port module wraps standard C library functions with macros to
+ * cover portability issues when building in environments that rename
+ * those functions. This module also provides local versions of some
+ * standard C library functions that are missing on some platforms.
+ */
+
+
+#ifndef MY_FILESYSTEM_H
+#define MY_FILESYSTEM_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include "system/fs/sys_fs.h"
+
+/*******************************************************************************
+ mapping of file handles and modes
+*******************************************************************************/
+#define WDIR SYS_FS_HANDLE
+#define WSTAT_T SYS_FS_FSTAT
+#define WS_DELIM '/'
+#define WFFLUSH(s) SYS_FS_FileSync((s))
+#define WFILE SYS_FS_HANDLE
+#define WSEEK_END SYS_FS_SEEK_END
+#define WBADFILE SYS_FS_HANDLE_INVALID
+#define WOLFSSH_O_RDWR SYS_FS_FILE_OPEN_READ_PLUS
+#define WOLFSSH_O_RDONLY SYS_FS_FILE_OPEN_READ
+#define WOLFSSH_O_WRONLY SYS_FS_FILE_OPEN_WRITE_PLUS
+#define WOLFSSH_O_APPEND SYS_FS_FILE_OPEN_APPEND
+#define WOLFSSH_O_CREAT SYS_FS_FILE_OPEN_WRITE_PLUS
+#define WOLFSSH_O_TRUNC 0
+#define WOLFSSH_O_EXCL 0
+#define FLUSH_STD(a)
+
+/*******************************************************************************
+ function declerations for operations that do not have a user check
+*******************************************************************************/
+#define WFD SYS_FS_HANDLE
+int wPread(WFD, unsigned char*, unsigned int, const unsigned int*);
+char* wGetCwd(char *r, int rSz);
+int wStat(const char* path, WSTAT_T* stat);
+int wDirOpen(void* heap, WDIR* dir, const char* path);
+
+
+/*******************************************************************************
+ mapping "SAFE" operations, any user can do
+*******************************************************************************/
+#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 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 WCHDIR(fs,b) SYS_FS_DirectryChange((b))
+#define WOPENDIR(fs,h,c,d) wDirOpen((h), (c),(d))
+#define WCLOSEDIR(fs,d) SYS_FS_DirClose(*(d))
+#define WSTAT(fs,p,b) wStat((p), (b))
+#define WPREAD(fs,fd,b,s,o) wPread((fd),(b),(s),(o))
+#define WGETCWD(fs,r,rSz) wGetCwd(r,(rSz))
+
+
+/*******************************************************************************
+ function declerations for operations that have a user check before running
+*******************************************************************************/
+int wPwrite(void* fs, WFD, unsigned char*, unsigned int, const unsigned int*);
+int wRename(void* fs, unsigned char* orig, unsigned char* newName);
+int wRemove(void* fs, unsigned char* dir);
+int wRmdir(void* fs, unsigned char* dir);
+int wMkdir(void* fs, unsigned char* path);
+int wChmod(void* fs, const char* path, int mode);
+int wFwrite(void *fs, unsigned char* b, int s, int a, WFILE* f);
+int wFread(void *fs, unsigned char* b, int s, int a, WFILE* f);
+
+
+/*******************************************************************************
+ mapping of operations that have a user check before running
+*******************************************************************************/
+#define WFWRITE(fs,b,s,a,f) wFwrite((fs),(b),(s),(a),(f))
+#define WCHMOD(fs,f,m) wChmod((fs),(f),(m))
+#define WMKDIR(fs,p,m) wMkdir((fs),(p))
+#define WRMDIR(fs,d) wRmdir((fs),(d))
+#define WREMOVE(fs,d) wRemove((fs),(d))
+#define WRENAME(fs,o,n) wRename((fs),(o),(n))
+#define WPWRITE(fs,fd,b,s,o) wPwrite((fs),(fd),(b),(s),(o))
+
+
+/*******************************************************************************
+ FPUTS/FGETS only used in SFTP client example
+*******************************************************************************/
+#undef WFGETS
+#define WFGETS(b,s,f) SYS_FS_FileStringGet((f), (b), (s))
+#undef WFPUTS
+#define WFPUTS(b,f) SYS_FS_FileStringPut((f), (b))
+
+
+/*******************************************************************************
+ Operations that do not have a port for
+*******************************************************************************/
+#define WUTIMES(a,b) (0)
+#define WSETTIME(fs,f,a,m) (0)
+#define WFSETTIME(fs,fd,a,m) (0)
+#define WFCHMOD(fs,fd,m) (0)
+
+
+/*******************************************************************************
+ File attribute functions
+*******************************************************************************/
+int SFTP_GetAttributesStat(void* atr, void* stats);
+int SFTP_GetAttributes_Handle(void* ssh, unsigned char* handle, int handleSz,
+ char* name, void* atr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MY_FILESYSTEM_H */
+
diff --git a/ide/mplabx/user_settings.h b/ide/mplabx/user_settings.h
index 486edc9cd..5afb291f5 100644
--- a/ide/mplabx/user_settings.h
+++ b/ide/mplabx/user_settings.h
@@ -44,4 +44,9 @@
/* allow signature wrapper api for wolfSSH use */
#undef NO_SIG_WRAPPER
+/* using example of overriding file system to apply custom restrictions on
+ operations */
+#undef WOLFSSH_USER_FILESYSTEM
+#define WOLFSSH_USER_FILESYSTEM
+
#endif
diff --git a/ide/mplabx/wolfssh.X/nbproject/configurations.xml b/ide/mplabx/wolfssh.X/nbproject/configurations.xml
index 953744c0d..b8a06fcc4 100644
--- a/ide/mplabx/wolfssh.X/nbproject/configurations.xml
+++ b/ide/mplabx/wolfssh.X/nbproject/configurations.xml
@@ -596,6 +596,7 @@
../src/third_party/wolfssl/wolfssl/sniffer.h
../user_settings.h
+ ../myFilesystem.h
../src/config/default/pin_configurations.csv
../src/main.c
+ ../myFilesystem.c
@@ -954,670 +956,3106 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ide/mplabx/wolfssh.c b/ide/mplabx/wolfssh.c
index cb8fb5e13..fceacb795 100644
--- a/ide/mplabx/wolfssh.c
+++ b/ide/mplabx/wolfssh.c
@@ -115,7 +115,7 @@ static const char echoserverBanner[] = "wolfSSH Example Echo Server\n";
*/
static const char samplePasswordBuffer[] =
"jill:upthehill\n"
- "jack:fetchapail\n";
+ "admin:fetchapail\n";
/* These are example public key authentication options. */
@@ -749,6 +749,9 @@ void APP_Tasks ( void )
SYS_CONSOLE_PRINT("Error = %d\r\n", wolfSSH_get_error(ssh));
appData.state = APP_SSH_CLEANUP;
}
+ #ifdef WOLFSSH_USER_FILESYSTEM
+ wolfSSH_SetFilesystemHandle(ssh, (void*)ssh);
+ #endif
appData.state = APP_SSH_SFTP;
break;