...
|
...
|
@@ -278,6 +278,7 @@ static int lua_zip_add(lua_State *L) |
278
|
278
|
static int lua_fs_mount(lua_State *L)
|
279
|
279
|
{
|
280
|
280
|
const char *src = luaL_checkstring(L, 1);
|
|
281
|
+ if (!physfs_check_allow_path_read(L, src)) return 0;
|
281
|
282
|
const char *dest = luaL_checkstring(L, 2);
|
282
|
283
|
bool append = lua_toboolean(L, 3);
|
283
|
284
|
|
...
|
...
|
@@ -318,61 +319,148 @@ static int lua_fs_get_real_path(lua_State *L) |
318
|
319
|
return 1;
|
319
|
320
|
}
|
320
|
321
|
|
321
|
|
-#define MAX_WRITE_DIRS 30
|
|
322
|
+#define MAX_READWRITE_DIRS 30
|
322
|
323
|
static bool can_set_allowed_dirs = FALSE;
|
323
|
|
-static char* allowed_dirs[MAX_WRITE_DIRS];
|
324
|
|
-static int nb_allowed_dirs = 0;
|
|
324
|
+static char* allowed_dirs_write[MAX_READWRITE_DIRS];
|
|
325
|
+static char* allowed_dirs_read[MAX_READWRITE_DIRS];
|
|
326
|
+static int nb_allowed_dirs_write = 0;
|
|
327
|
+static int nb_allowed_dirs_read = 0;
|
325
|
328
|
void physfs_reset_dir_allowed(lua_State *L)
|
326
|
329
|
{
|
327
|
330
|
int i;
|
328
|
|
- for (i = 0; i < nb_allowed_dirs; i++) {
|
329
|
|
- free(allowed_dirs[i]);
|
330
|
|
- allowed_dirs[i] = NULL;
|
|
331
|
+ for (i = 0; i < nb_allowed_dirs_write; i++) {
|
|
332
|
+ free(allowed_dirs_write[i]);
|
|
333
|
+ allowed_dirs_write[i] = NULL;
|
331
|
334
|
}
|
332
|
|
- nb_allowed_dirs = 0;
|
|
335
|
+ nb_allowed_dirs_write = 0;
|
|
336
|
+
|
|
337
|
+ for (i = 0; i < nb_allowed_dirs_read; i++) {
|
|
338
|
+ free(allowed_dirs_read[i]);
|
|
339
|
+ allowed_dirs_read[i] = NULL;
|
|
340
|
+ }
|
|
341
|
+ nb_allowed_dirs_read = 0;
|
|
342
|
+
|
333
|
343
|
can_set_allowed_dirs = TRUE;
|
334
|
344
|
}
|
335
|
345
|
|
336
|
346
|
static int lua_fs_done_dir_allowed(lua_State *L) {
|
337
|
|
- can_set_allowed_dirs = FALSE;
|
|
347
|
+ // can_set_allowed_dirs = FALSE;
|
338
|
348
|
|
339
|
349
|
int i;
|
340
|
|
- for (i = 0; i < nb_allowed_dirs; i++) {
|
341
|
|
- printf("%d==WRITEPATH==allowed== %s\n", i, allowed_dirs[i]);
|
|
350
|
+ for (i = 0; i < nb_allowed_dirs_write; i++) {
|
|
351
|
+ printf("%d==WRITEPATH==allowed== %s\n", i, allowed_dirs_write[i]);
|
|
352
|
+ }
|
|
353
|
+ for (i = 0; i < nb_allowed_dirs_read; i++) {
|
|
354
|
+ printf("%d==READPATH==allowed== %s\n", i, allowed_dirs_read[i]);
|
342
|
355
|
}
|
343
|
356
|
return 0;
|
344
|
357
|
}
|
345
|
358
|
|
|
359
|
+static char *sanize_dir_path(const char *dir, size_t len) {
|
|
360
|
+ // Sanity path to remove // and such silliness
|
|
361
|
+ const char *sep = PHYSFS_getDirSeparator();
|
|
362
|
+ size_t sep_len = strlen(sep);
|
|
363
|
+ char *sdir = calloc(len * 2, sizeof(char));
|
|
364
|
+ size_t si = 0;
|
|
365
|
+
|
|
366
|
+ bool was_sep = FALSE;
|
|
367
|
+ for (size_t i = 0; i < len;) {
|
|
368
|
+ // We found a separator
|
|
369
|
+ if (strstr(&dir[i], sep) == &dir[i]) {
|
|
370
|
+ // More than one separator, skip it
|
|
371
|
+ if (was_sep) {
|
|
372
|
+ i += sep_len;
|
|
373
|
+ } else{
|
|
374
|
+ memcpy(&sdir[si], sep, sep_len);
|
|
375
|
+ i += sep_len;
|
|
376
|
+ si += sep_len;
|
|
377
|
+ }
|
|
378
|
+ was_sep = TRUE;
|
|
379
|
+ // Normal data
|
|
380
|
+ } else {
|
|
381
|
+ sdir[si++] = dir[i];
|
|
382
|
+ i++;
|
|
383
|
+ was_sep = FALSE;
|
|
384
|
+ }
|
|
385
|
+ }
|
|
386
|
+ // If we didnt have a last separator, have one, it's on the house
|
|
387
|
+ if (!was_sep) {
|
|
388
|
+ memcpy(&sdir[si], sep, sep_len);
|
|
389
|
+ si += sep_len;
|
|
390
|
+ }
|
|
391
|
+ sdir[si] = '\0';
|
|
392
|
+
|
|
393
|
+ printf("===sanitizing '%s' to '%s'\n", dir, sdir);
|
|
394
|
+ return sdir;
|
|
395
|
+}
|
|
396
|
+
|
346
|
397
|
static int lua_fs_set_dir_allowed(lua_State *L) {
|
347
|
398
|
if (!can_set_allowed_dirs) return 0;
|
348
|
|
- if (nb_allowed_dirs >= MAX_WRITE_DIRS) return 0;
|
|
399
|
+ bool to_write = lua_toboolean(L, 2);
|
|
400
|
+ if (to_write) {
|
|
401
|
+ if (nb_allowed_dirs_write >= MAX_READWRITE_DIRS) return 0;
|
|
402
|
+ } else {
|
|
403
|
+ if (nb_allowed_dirs_read >= MAX_READWRITE_DIRS) return 0;
|
|
404
|
+ }
|
349
|
405
|
|
350
|
|
- const char *dir = luaL_checkstring(L, 1);
|
351
|
|
- allowed_dirs[nb_allowed_dirs] = strdup(dir);
|
352
|
|
- nb_allowed_dirs++;
|
|
406
|
+ size_t len = 0;
|
|
407
|
+ const char *dir = luaL_checklstring(L, 1, &len);
|
|
408
|
+ char *sdir = sanize_dir_path(dir, len);
|
|
409
|
+
|
|
410
|
+ if (to_write) {
|
|
411
|
+ allowed_dirs_write[nb_allowed_dirs_write] = strdup(sdir);
|
|
412
|
+ nb_allowed_dirs_write++;
|
|
413
|
+ }
|
|
414
|
+ allowed_dirs_read[nb_allowed_dirs_read] = sdir;
|
|
415
|
+ nb_allowed_dirs_read++;
|
353
|
416
|
return 0;
|
354
|
417
|
}
|
355
|
418
|
|
356
|
|
-bool physfs_check_allow_path(lua_State *L, const char *path) {
|
357
|
|
- if (can_set_allowed_dirs) return TRUE; // As long as we're stillsetting stuff up we can do any path
|
|
419
|
+bool physfs_check_allow_path_write(lua_State *L, const char *path) {
|
|
420
|
+ if (can_set_allowed_dirs) return TRUE; // As long as we're still setting stuff up we can do any path
|
|
421
|
+
|
|
422
|
+ char *spath = sanize_dir_path(path, strlen(path));
|
|
423
|
+ int i;
|
|
424
|
+ for (i = 0; i < nb_allowed_dirs_write; i++) {
|
|
425
|
+ if (strstr(spath, allowed_dirs_write[i]) == spath) {
|
|
426
|
+ free(spath);
|
|
427
|
+ return TRUE;
|
|
428
|
+ }
|
|
429
|
+ }
|
|
430
|
+ printf("ERROR TRYING TO ACCESS WRITE FORBIDDEN PATH: '%s' (sanitized to '%s')\n", path, spath);
|
|
431
|
+ if (L) {
|
|
432
|
+ lua_pushstring(L, "FORBIDDEN WRITE PATH");
|
|
433
|
+ lua_error(L);
|
|
434
|
+ }
|
|
435
|
+ free(spath);
|
|
436
|
+ return FALSE;
|
|
437
|
+}
|
|
438
|
+
|
|
439
|
+bool physfs_check_allow_path_read(lua_State *L, const char *path) {
|
|
440
|
+ if (can_set_allowed_dirs) return TRUE; // As long as we're still setting stuff up we can do any path
|
|
441
|
+
|
|
442
|
+ char *spath = sanize_dir_path(path, strlen(path));
|
358
|
443
|
int i;
|
359
|
|
- for (i = 0; i < nb_allowed_dirs; i++) {
|
360
|
|
- if (strstr(path, allowed_dirs[i]) == path) {
|
|
444
|
+ for (i = 0; i < nb_allowed_dirs_read; i++) {
|
|
445
|
+ printf("??READTEST?? '%s' <=> '%s'\n", spath, allowed_dirs_read[i]);
|
|
446
|
+ if (strstr(spath, allowed_dirs_read[i]) == spath) {
|
|
447
|
+ free(spath);
|
361
|
448
|
return TRUE;
|
362
|
449
|
}
|
363
|
450
|
}
|
364
|
|
- printf("ERROR TRYING TO ACCESS FORBIDDEN PATH: %s\n", path);
|
|
451
|
+ printf("ERROR TRYING TO ACCESS READ FORBIDDEN PATH: '%s' (sanitized to '%s')\n", path, spath);
|
365
|
452
|
if (L) {
|
366
|
|
- lua_pushstring(L, "FORBIDDEN PATH");
|
|
453
|
+ lua_pushstring(L, "FORBIDDEN READ PATH");
|
367
|
454
|
lua_error(L);
|
368
|
455
|
}
|
|
456
|
+ free(spath);
|
369
|
457
|
return FALSE;
|
370
|
458
|
}
|
371
|
459
|
|
372
|
460
|
static int lua_fs_set_write_dir(lua_State *L)
|
373
|
461
|
{
|
374
|
462
|
const char *src = luaL_checkstring(L, 1);
|
375
|
|
- if (!physfs_check_allow_path(L, src)) return 0;
|
|
463
|
+ if (!physfs_check_allow_path_write(L, src)) return 0;
|
376
|
464
|
const int error = PHYSFS_setWriteDir(src);
|
377
|
465
|
if (error == 0)
|
378
|
466
|
{
|
...
|
...
|
|