Skip to content

Commit 3978649

Browse files
move file system override example to wolfSSH ide directory
1 parent b19ecb5 commit 3978649

5 files changed

Lines changed: 2909 additions & 1 deletion

File tree

ide/mplabx/myFilesystem.c

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
/* myFilesystem.c
2+
*
3+
* Copyright (C) 2014-2025 wolfSSL Inc.
4+
*
5+
*
6+
* wolfSSH is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* wolfSSH is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wolfSSH. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include "myFilesystem.h"
21+
#include <wolfssh/ssh.h>
22+
#include <wolfssh/wolfsftp.h>
23+
#include <wolfssh/log.h>
24+
#include <stdlib.h>
25+
#include <stdio.h>
26+
#include "system/fs/sys_fs.h"
27+
28+
#ifdef WOLFSSH_USER_FILESYSTEM
29+
/*******************************************************************************
30+
Restricted function implementations
31+
*******************************************************************************/
32+
33+
/* helper function to check if the user is allowed to do an operation */
34+
static int isUserAllowed(void* fs)
35+
{
36+
char* currentUser;
37+
WOLFSSH* ssh = (WOLFSSH*)fs;
38+
39+
if (ssh == NULL) {
40+
return 0;
41+
}
42+
43+
currentUser = wolfSSH_GetUsername(ssh);
44+
if (currentUser && XSTRCMP(currentUser, "admin") == 0) {
45+
return 1;
46+
}
47+
return 0;
48+
}
49+
50+
51+
int wFwrite(void *fs, unsigned char* b, int s, int a, WFILE* f)
52+
{
53+
if (isUserAllowed(fs)) {
54+
return SYS_FS_FileWrite(*f, b, s * a);
55+
}
56+
else {
57+
return -1;
58+
}
59+
}
60+
61+
62+
int wChmod(void* fs, const char* path, int mode)
63+
{
64+
SYS_FS_RESULT ret;
65+
SYS_FS_FILE_DIR_ATTR attr = 0;
66+
67+
if (isUserAllowed(fs)) {
68+
/* mode is the octal value i.e 666 is 0x1B6 */
69+
if ((mode & 0x180) != 0x180) { /* not octal 6XX read only */
70+
attr |= SYS_FS_ATTR_RDO;
71+
}
72+
73+
/* toggle the read only attribute */
74+
ret = SYS_FS_FileDirectoryModeSet(path, attr, SYS_FS_ATTR_RDO);
75+
if (ret != SYS_FS_RES_SUCCESS) {
76+
return -1;
77+
}
78+
return 0;
79+
}
80+
else {
81+
return -1;
82+
}
83+
}
84+
85+
86+
int wPwrite(void* fs, WFD fd, unsigned char* buf, unsigned int sz,
87+
const unsigned int* shortOffset)
88+
{
89+
int ret = -1;
90+
91+
if (isUserAllowed(fs)) {
92+
ret = (int)WFSEEK(NULL, &fd, shortOffset[0], SYS_FS_SEEK_SET);
93+
if (ret != -1) {
94+
ret = (int)WFWRITE(NULL, buf, 1, sz, &fd);
95+
}
96+
}
97+
98+
return ret;
99+
}
100+
101+
int wMkdir(void* fs, unsigned char* path)
102+
{
103+
if (isUserAllowed(fs)) {
104+
return SYS_FS_DirectoryMake(path);
105+
}
106+
else {
107+
return -1;
108+
}
109+
}
110+
111+
112+
int wRmdir(void* fs, unsigned char* dir)
113+
{
114+
if (isUserAllowed(fs)) {
115+
return SYS_FS_FileDirectoryRemove(dir);
116+
}
117+
else {
118+
return -1;
119+
}
120+
}
121+
122+
int wRemove(void* fs, unsigned char* dir)
123+
{
124+
if (isUserAllowed(fs)) {
125+
return SYS_FS_FileDirectoryRemove(dir);
126+
}
127+
else {
128+
return -1;
129+
}
130+
}
131+
132+
133+
int wRename(void* fs, unsigned char* orig, unsigned char* newName)
134+
{
135+
if (isUserAllowed(fs)) {
136+
return SYS_FS_FileDirectoryRenameMove(orig, newName);
137+
}
138+
else {
139+
return -1;
140+
}
141+
}
142+
143+
144+
/*******************************************************************************
145+
"SAFE" function implementations any user is ok
146+
*******************************************************************************/
147+
int wDirOpen(void* heap, WDIR* dir, const char* path)
148+
{
149+
*dir = SYS_FS_DirOpen(path);
150+
if (*dir == SYS_FS_HANDLE_INVALID) {
151+
return -1;
152+
}
153+
return 0;
154+
}
155+
156+
int wStat(const char* path, WSTAT_T* stat)
157+
{
158+
int ret;
159+
160+
WMEMSET(stat, 0, sizeof(WSTAT_T));
161+
ret = SYS_FS_FileStat(path, stat);
162+
163+
if (ret != SYS_FS_RES_SUCCESS) {
164+
WLOG(WS_LOG_SFTP,
165+
"Return from SYS_FS_fileStat [%s] = %d, expecting %d",
166+
path, ret, SYS_FS_RES_SUCCESS);
167+
WLOG(WS_LOG_SFTP, "SYS error reason = %d", SYS_FS_Error());
168+
return -1;
169+
}
170+
else {
171+
return 0;
172+
}
173+
return 0;
174+
}
175+
176+
char* wGetCwd(char *r, int rSz)
177+
{
178+
SYS_FS_RESULT ret;
179+
ret = SYS_FS_CurrentWorkingDirectoryGet(r, rSz);
180+
if (ret != SYS_FS_RES_SUCCESS) {
181+
return r;
182+
}
183+
return r;
184+
}
185+
186+
187+
int wfopen(WFILE* f, const char* filename, SYS_FS_FILE_OPEN_ATTRIBUTES mode)
188+
{
189+
if (f != NULL) {
190+
*f = SYS_FS_FileOpen(filename, mode);
191+
if (*f == WBADFILE) {
192+
WLOG(WS_LOG_SFTP, "Failed to open file %s", filename);
193+
return 1;
194+
}
195+
else {
196+
WLOG(WS_LOG_SFTP, "Opened file %s", filename);
197+
return 0;
198+
}
199+
}
200+
return 1;
201+
}
202+
203+
204+
int wPread(WFD fd, unsigned char* buf, unsigned int sz,
205+
const unsigned int* shortOffset)
206+
{
207+
int ret;
208+
209+
ret = (int)WFSEEK(NULL, &fd, shortOffset[0], SYS_FS_SEEK_SET);
210+
if (ret != -1)
211+
ret = (int)WFREAD(NULL, buf, 1, sz, &fd);
212+
213+
return ret;
214+
}
215+
216+
217+
/*******************************************************************************
218+
File attribute functions
219+
*******************************************************************************/
220+
221+
typedef struct WS_HANDLE_LIST {
222+
byte handle[WOLFSSH_MAX_HANDLE];
223+
word32 handleSz;
224+
char name[WOLFSSH_MAX_FILENAME];
225+
struct WS_HANDLE_LIST* next;
226+
struct WS_HANDLE_LIST* prev;
227+
} WS_HANDLE_LIST;
228+
229+
int SFTP_GetAttributesStat(void* atrIn, void* statsIn)
230+
{
231+
WS_SFTP_FILEATRB* atr = (WS_SFTP_FILEATRB*)atrIn;
232+
WSTAT_T* stats = (WSTAT_T*)statsIn;
233+
/* file size */
234+
atr->flags |= WOLFSSH_FILEATRB_SIZE;
235+
atr->sz[0] = (word32)stats->fsize;
236+
atr->sz[1] = (word32)(0);
237+
238+
/* file permissions */
239+
atr->flags |= WOLFSSH_FILEATRB_PERM;
240+
if ((stats->fattrib & SYS_FS_ATTR_DIR) & SYS_FS_ATTR_MASK) {
241+
atr->per |= 0x41ED; /* 755 with directory */
242+
}
243+
else {
244+
atr->per |= 0x8000;
245+
}
246+
247+
/* check for read only */
248+
if ((stats->fattrib & SYS_FS_ATTR_RDO) & SYS_FS_ATTR_MASK) {
249+
atr->per |= 0x124; /* octal 444 */
250+
}
251+
else {
252+
atr->per |= 0x1ED; /* octal 755 */
253+
}
254+
255+
/* last modified time */
256+
atr->mtime = stats->ftime;
257+
258+
return WS_SUCCESS;
259+
}
260+
261+
262+
static int SFTP_GetAttributesHelper(WS_SFTP_FILEATRB* atr, const char* fName)
263+
{
264+
WSTAT_T stats;
265+
SYS_FS_RESULT res;
266+
char buffer[255];
267+
268+
WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
269+
WMEMSET(buffer, 0, sizeof(buffer));
270+
res = SYS_FS_CurrentDriveGet(buffer);
271+
if (res == SYS_FS_RES_SUCCESS) {
272+
if (WSTRCMP(fName, buffer) == 0) {
273+
atr->flags |= WOLFSSH_FILEATRB_PERM;
274+
atr->per |= 0x41ED; /* 755 with directory */
275+
atr->per |= 0x1ED; /* octal 755 */
276+
277+
atr->flags |= WOLFSSH_FILEATRB_SIZE;
278+
atr->sz[0] = 0;
279+
atr->sz[1] = 0;
280+
281+
atr->mtime = 30912;
282+
WLOG(WS_LOG_SFTP, "Setting mount point as directory");
283+
return WS_SUCCESS;
284+
}
285+
}
286+
287+
if (WSTAT(ssh->fs, fName, &stats) != 0) {
288+
WLOG(WS_LOG_SFTP, "Issue with WSTAT call");
289+
return WS_BAD_FILE_E;
290+
}
291+
return SFTP_GetAttributesStat(atr, &stats);
292+
}
293+
294+
295+
/* NOTE: if atr->flags is set to a value of 0 then no attributes are set.
296+
* Fills out a WS_SFTP_FILEATRB structure
297+
* returns WS_SUCCESS on success
298+
*/
299+
int SFTP_GetAttributes(void* fs, const char* fileName, void* atr,
300+
byte noFollow, void* heap)
301+
{
302+
WOLFSSH_UNUSED(heap);
303+
WOLFSSH_UNUSED(fs);
304+
305+
return SFTP_GetAttributesHelper((WS_SFTP_FILEATRB*)atr, fileName);
306+
}
307+
308+
309+
/* Gets attributes based on file descriptor
310+
* NOTE: if atr->flags is set to a value of 0 then no attributes are set.
311+
* Fills out a WS_SFTP_FILEATRB structure
312+
* returns WS_SUCCESS on success
313+
*/
314+
int SFTP_GetAttributes_Handle(void* ssh, unsigned char* handle, int handleSz,
315+
char* name, void* atr)
316+
{
317+
return SFTP_GetAttributesHelper((WS_SFTP_FILEATRB*)atr, name);
318+
}
319+
#endif /* WOLFSSH_USER_FILESYSTEM */

0 commit comments

Comments
 (0)