From bbb103fb748ff87c6645e7280b49643c54345dc7 Mon Sep 17 00:00:00 2001 From: tenox7 Date: Mon, 9 Jul 2018 02:32:04 -0700 Subject: paths cleanup --- fileio.c | 6 ++---- wfm.c | 67 ++++++++++++++++++++++++++++++++++++++-------------------------- wfm.h | 10 +--------- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/fileio.c b/fileio.c index 1f66aac..4c70702 100644 --- a/fileio.c +++ b/fileio.c @@ -262,7 +262,6 @@ void fileio_re_rmdir(char *dirname) { if(!dir) error("Unable to remove directory.."); - direntry=readdir(dir); while(direntry!=0) { if(strncmp(direntry->d_name, ".", 1) && strncmp(direntry->d_name, "..", 2)) { @@ -353,7 +352,6 @@ void fileio_move(void) { error("Unable to move file.
[%d: %s]
[SRC=%s] [DST=%s]", errno, strerror(errno), wp.phys_filename, wp.final_destination); wfm_commit(MOVE, NULL); - } // @@ -441,8 +439,8 @@ void re_dir_ui(char *vdir, int level) { if(strlen(re_phys_dirname)<2 || strlen(re_phys_dirname)>(sizeof(wp.phys_dirname)-2)) error("Invalid directory name."); - if(regexec(&dotdot, re_phys_dirname, 0, 0, 0)==0) error("Invalid directory name."); - if(strlen(re_phys_dirname) < strlen(cfg.homedir)) error("Invalid directory name."); + if(strlen(re_phys_dirname) < strlen(cfg.homedir)) error("Invalid directory name 4."); + if(strstr(re_phys_dirname, "..")) error("Double dots in directory name"); nentr=scandir(re_phys_dirname, &direntry, 0, alphasort); diff --git a/wfm.c b/wfm.c index 1539eec..e1f1bb0 100644 --- a/wfm.c +++ b/wfm.c @@ -205,18 +205,17 @@ void checkfilename(char *inp_filename) { strip(bname, sizeof(wp.virt_filename), VALIDCHRS); strncpy(wp.virt_filename, bname, sizeof(wp.virt_filename)); + wp.virt_filename_urlencoded=url_encode(wp.virt_filename); snprintf(wp.phys_filename, sizeof(wp.phys_filename), "%s/%s", wp.phys_dirname, wp.virt_filename); // Do checks - if(!strlen(wp.phys_filename) || strlen(wp.phys_filename)>(sizeof(wp.phys_filename)-2)) error("Invalid wp.phys_filename lenght [%d]", strlen(wp.phys_filename)); - if(!strlen(wp.virt_filename) || strlen(wp.virt_filename)>(sizeof(wp.virt_filename)-2)) error("Invalid wp.virt_filename lenght [%d]", strlen(wp.virt_filename)); - if(regexec(&dotdot, wp.phys_filename, 0, 0, 0)==0) error("Double dots in pfilename"); - if(regexec(&dotdot, wp.virt_filename, 0, 0, 0)==0) error("Double dots in vfilename"); + if(!strlen(wp.phys_filename) || strlen(wp.phys_filename)>(sizeof(wp.phys_filename)-2)) error("Invalid pfilename lenght [%d]", strlen(wp.phys_filename)); + if(!strlen(wp.virt_filename) || strlen(wp.virt_filename)>(sizeof(wp.virt_filename)-2)) error("Invalid vfilename lenght [%d]", strlen(wp.virt_filename)); + if(strstr(wp.phys_filename, "..")) error("Double dots in pfilename"); + if(strstr(wp.virt_filename, "..")) error("Double dots in vfilename"); strncpy(temp_dirname, wp.phys_filename, sizeof(wp.phys_filename)); - if(strlen(dirname(temp_dirname)) < strlen(cfg.homedir)) error("Invalid directory name."); - - wp.virt_filename_urlencoded=url_encode(wp.virt_filename); + if(strlen(dirname(temp_dirname)) < strlen(cfg.homedir)) error("Basename path too short"); } // @@ -228,16 +227,18 @@ void checkdestination(void) { cgiFormStringNoNewlines("destination", wp.virt_destination, sizeof(wp.virt_filename)); strip(wp.virt_destination, sizeof(wp.virt_filename), VALIDCHRS_DIR); - cgiFormInteger("absdst", &absolute_destination, 0); // move operation relies on absolute paths + + cgiFormInteger("absdst", &absolute_destination, 0); // move operation relies on absolute paths, rename does not if(absolute_destination) snprintf(wp.phys_destination, sizeof(wp.phys_filename), "%s/%s", cfg.homedir, wp.virt_destination); else snprintf(wp.phys_destination, sizeof(wp.phys_filename), "%s/%s", wp.phys_dirname, wp.virt_destination); - if(strlen(wp.phys_destination)<1 || strlen(wp.phys_destination)>(sizeof(wp.phys_filename)-2)) error("Invalid wp.phys_destination lenght [%d]", strlen(wp.phys_destination)); - if(strlen(wp.virt_destination)<1 || strlen(wp.virt_destination)>(sizeof(wp.virt_filename)-2)) error("Invalid wp.virt_destination lenght [%d]", strlen(wp.virt_destination)); - if(regexec(&dotdot, wp.phys_destination, 0, 0, 0)==0) error("Double dots in pfilename"); - if(regexec(&dotdot, wp.virt_destination, 0, 0, 0)==0) error("Double dots in vfilename"); + if(strlen(wp.phys_destination)<1 || strlen(wp.phys_destination)>(sizeof(wp.phys_filename)-2)) error("Invalid pdestination lenght [%d]", strlen(wp.phys_destination)); + if(strlen(wp.virt_destination)<1 || strlen(wp.virt_destination)>(sizeof(wp.virt_filename)-2)) error("Invalid vdestination lenght [%d]", strlen(wp.virt_destination)); + if(strstr(wp.phys_destination, "..")) error("Double dots in pdestination"); + if(strstr(wp.virt_destination, "..")) error("Double dots in vdestination"); + } // @@ -246,25 +247,38 @@ void checkdestination(void) { // void checkdirectory(void) { char temp[sizeof(wp.virt_dirname)]={0}; + char *real; + // virtual directory cgiFormStringNoNewlines("directory", wp.virt_dirname, sizeof(wp.virt_dirname)); strip(wp.virt_dirname, sizeof(wp.virt_dirname), VALIDCHRS_DIR); - snprintf(wp.phys_dirname, sizeof(wp.phys_dirname), "%s/%s", cfg.homedir, wp.virt_dirname); - - if(strlen(wp.phys_dirname)<2 || strlen(wp.phys_dirname)>(sizeof(wp.phys_dirname)-2)) - error("Invalid directory name."); - - if(regexec(&dotdot, wp.phys_dirname, 0, 0, 0)==0) error("Invalid directory name."); - if(strlen(wp.phys_dirname) < strlen(cfg.homedir)) error("Invalid directory name."); - if(!strlen(wp.virt_dirname)) strcpy(wp.virt_dirname, "/"); - wp.virt_dirname_urlencoded=url_encode(wp.virt_dirname); // parent strncpy(temp, wp.virt_dirname, sizeof(wp.virt_dirname)); strncpy(wp.virt_parent, dirname(temp), sizeof(wp.virt_dirname)); wp.virt_parent_urlencoded=url_encode(wp.virt_parent); + + // physical directory + snprintf(wp.phys_dirname, sizeof(wp.phys_dirname), "%s/%s", cfg.homedir, wp.virt_dirname); + + if(strlen(wp.phys_dirname)<2 || strlen(wp.phys_dirname)>(sizeof(wp.phys_dirname)-2)) + error("Invalid directory name lenght 2"); + + if(strlen(wp.phys_dirname) < strlen(cfg.homedir)) error("Invalid directory name 3."); + if(strstr(wp.phys_dirname, "..")) error("Double dots in dirname"); + + real=realpath(wp.phys_dirname, NULL); + + if(!real) + error("Unable to resolve directory path.
%s", strerror(errno)); + + if(strlen(real) > sizeof(wp.phys_dirname)-2) + error("Resolved path too long"); + + strncpy(wp.phys_dirname, real, sizeof(wp.phys_dirname)); + free(real); } @@ -400,6 +414,11 @@ char *buprintf(float v, int bold) { if(v == -1) return " "; + #define P1024_1 1024.0f + #define P1024_2 1048576.0f + #define P1024_3 1073741824.0f + #define P1024_4 1099511627776.0f + if(v >= P1024_1 && v < P1024_2 ) { size = v / P1024_1; unit = 'K'; } else if(v >= P1024_2 && v < P1024_3 ) { size = v / P1024_2; unit = 'M'; } else if(v >= P1024_3 && v < P1024_4 ) { size = v / P1024_3; unit = 'G'; } @@ -525,7 +544,6 @@ void cfgload(void) { checkdirectory(); - // JavaScript check if(strncmp(cgiUserAgent, "Mozilla/5", 9)==0) rt.js=2; else if(strncmp(cgiUserAgent, "Mozilla/4.0 (compatible; MSIE 6", 31)==0) rt.js=2; @@ -550,14 +568,9 @@ int cgiMain(void) { // normal initialization tstart(); - fprintf(cgiOut, "Cache-Control: max-age=0, private\r\nExpires: -1\r\n"); - cfgload(); - - - // main routine - regular actions cgiFormStringNoNewlines("action", action, sizeof(action)); if(cgiFormSubmitClicked("noop")==cgiFormSuccess && rt.access_level >= PERM_RO) dirlist(); else if(cgiFormSubmitClicked("multi_delete_prompt")==cgiFormSuccess && rt.access_level >= PERM_RO) multiprompt_ui("delete"); diff --git a/wfm.h b/wfm.h index 4c1080e..7ac94fe 100644 --- a/wfm.h +++ b/wfm.h @@ -55,7 +55,7 @@ #include #include #include -//#include + #include "md5.h" #include "cgic.h" #include "wfmiconres.h" @@ -63,12 +63,6 @@ #define VALIDCHRS "an ()[]{}-_.,!@#$%^&=+;" #define VALIDCHRS_DIR VALIDCHRS "/" - -#define P1024_1 1024.0f -#define P1024_2 1048576.0f -#define P1024_3 1073741824.0f -#define P1024_4 1099511627776.0f - #define SHM_SIZE 16 struct wfm_paths { @@ -85,8 +79,6 @@ struct wfm_paths { char final_destination[PATH_MAX]; } wp; -regex_t dotdot; - struct config_struct { int users_defined; int edit_by_default; -- cgit v1.2.3