Commit 1f677d22add7878c72ec78ae9236ed5d5d72c3b3

Authored by DarkGod
1 parent efd1ffae

test

... ... @@ -29,12 +29,19 @@ if __SELFEXE then
29 29 print("SelfExe gave us app directory of:", dir)
30 30 fs.mount(dir..fs.getPathSeparator().."game"..fs.getPathSeparator().."thirdparty", "/", true)
31 31 fs.mount(dir..fs.getPathSeparator().."game", "/", true)
  32 + fs.setPathAllowed(dir..fs.getPathSeparator().."game", false)
32 33 else
33 34 print("No SelfExe, using basic path")
34 35 fs.mount("game"..fs.getPathSeparator().."thirdparty", "/", true)
35 36 fs.mount("game", "/", true)
36 37 end
37 38
  39 +fs.setPathAllowed(fs.getRealPath("/engines/"), false)
  40 +fs.setPathAllowed(fs.getRealPath("/thirdparty/"), false)
  41 +fs.setPathAllowed(fs.getRealPath("/addons/"), true)
  42 +if fs.getRealPath("/dlcs/") then fs.setPathAllowed(fs.getRealPath("/dlcs/"), true) end
  43 +fs.setPathAllowed(fs.getRealPath("/modules/"), true)
  44 +
38 45 -- Look for a core
39 46 function get_core(coretype, id)
40 47 coretype = coretype or "te4core"
... ...
... ... @@ -45,10 +45,10 @@ fs.mkdir(fs.getHomePath().."/4.0/")
45 45 fs.mkdir(fs.getHomePath().."/4.0/profiles/")
46 46 fs.mkdir(fs.getHomePath().."/4.0/settings/")
47 47
48   -fs.setPathAllowed(engine.homepath)
49   -fs.setPathAllowed(fs.getRealPath("/addons/"))
50   -if fs.getRealPath("/dlcs/") then fs.setPathAllowed(fs.getRealPath("/dlcs/")) end
51   -fs.setPathAllowed(fs.getRealPath("/modules/"))
  48 +fs.setPathAllowed(engine.homepath, true)
  49 +fs.setPathAllowed(fs.getRealPath("/addons/"), true)
  50 +if fs.getRealPath("/dlcs/") then fs.setPathAllowed(fs.getRealPath("/dlcs/"), true) end
  51 +fs.setPathAllowed(fs.getRealPath("/modules/"), true)
52 52 fs.doneSettingPathAllowed()
53 53 fs.setWritePath(engine.homepath)
54 54
... ...
... ... @@ -1138,6 +1138,7 @@ void boot_lua(int state, bool rebooting, int argc, char *argv[])
1138 1138 /***************** Physfs Init *****************/
1139 1139 PHYSFS_init(argv[0]);
1140 1140
  1141 + bool bootstrap_mounted = FALSE;
1141 1142 selfexe = get_self_executable(argc, argv);
1142 1143 if (selfexe && PHYSFS_mount(selfexe, "/", 1))
1143 1144 {
... ... @@ -1146,6 +1147,7 @@ void boot_lua(int state, bool rebooting, int argc, char *argv[])
1146 1147 {
1147 1148 printf("NO SELFEXE: bootstrapping from CWD\n");
1148 1149 PHYSFS_mount("bootstrap", "/bootstrap", 1);
  1150 + bootstrap_mounted = TRUE;
1149 1151 }
1150 1152
1151 1153 /***************** Lua Init *****************/
... ... @@ -1222,6 +1224,16 @@ void boot_lua(int state, bool rebooting, int argc, char *argv[])
1222 1224 printf("WARNING: No bootstrap code found, defaulting to working directory for engine code!\n");
1223 1225 PHYSFS_mount("game/thirdparty", "/", 1);
1224 1226 PHYSFS_mount("game/", "/", 1);
  1227 + luaL_loadstring(L,
  1228 + "fs.setPathAllowed(fs.getRealPath('/addons/', true)) " \
  1229 + "if fs.getRealPath('/dlcs/') then fs.setPathAllowed(fs.getRealPath('/dlcs/', true)) end " \
  1230 + "fs.setPathAllowed(fs.getRealPath('/modules/', true)) "
  1231 + );
  1232 + lua_pcall(L, 0, 0, 0);
  1233 + }
  1234 +
  1235 + if (bootstrap_mounted) {
  1236 + PHYSFS_removeFromSearchPath("bootstrap");
1225 1237 }
1226 1238
1227 1239 if (te4_web_init) te4_web_init(L);
... ...
... ... @@ -85,7 +85,8 @@ extern void del_lua_error();
85 85 extern core_boot_type *core_def;
86 86
87 87 extern void physfs_reset_dir_allowed(lua_State *L);
88   -extern bool physfs_check_allow_path(lua_State *L, const char *path);
  88 +extern bool physfs_check_allow_path_read(lua_State *L, const char *path);
  89 +extern bool physfs_check_allow_path_write(lua_State *L, const char *path);
89 90
90 91 #ifdef STEAM_TE4
91 92 #include "steam-te4.h"
... ...
... ... @@ -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 {
... ...
... ... @@ -200,7 +200,7 @@ static int lua_web_download_action(lua_State *L) {
200 200 long id = lua_tonumber(L, 2);
201 201 if (lua_isstring(L, 3)) {
202 202 const char *path = lua_tostring(L, 3);
203   - if (!physfs_check_allow_path(L, path)) return 0;
  203 + if (!physfs_check_allow_path_write(L, path)) return 0;
204 204 te4_web_download_action(view, id, path);
205 205 } else {
206 206 te4_web_download_action(view, id, NULL);
... ...