From: Frédéric Marchal Date: Sun, 27 Dec 2009 14:38:26 +0000 (+0000) Subject: Protect the creation of the index against invalid directories. X-Git-Tag: v2_2_7~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=06ced8583c2eebe4c886f2f347b2aeff1294e641;p=thirdparty%2Fsarg.git Protect the creation of the index against invalid directories. Only copy the files when creating the directory with the images to link the reports to. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index efb79a4..7982770 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ PROJECT(sarg C) SET(sarg_VERSION 2) SET(sarg_REVISION 2) SET(sarg_BUILD "7rc1") -SET(sarg_BUILDDATE "Dec-23-2009") +SET(sarg_BUILDDATE "Dec-27-2009") INCLUDE(AddFileDependencies) INCLUDE(CheckIncludeFile) diff --git a/ChangeLog b/ChangeLog index 18fdf6a..7b064f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ SARG ChangeLog -Dec-23-2009 Version 2.2.7 +Dec-27-2009 Version 2.2.7 - Extra compile and run time protection (FORTIFY_SOURCE) fixed in configure. - Use tabulations as columns separator in intermediary files to avoid problems when a field of the log contains a space. - Input log file type detection partly rewritten to clearly distinguish which type is processed where. @@ -13,6 +13,8 @@ Dec-23-2009 Version 2.2.7 - Use boolean to enable the options instead of string compares. - Accept an absolute path for the language file in sarg.conf. - Experimental: Can show the backtrace of the program when a getword loop is detected to help in locating the origin of the error. + - Protect the creation of the index against invalid directories. + - Only copy the files when creating the directory with the images to link the reports to. Dec-17-2009 Version 2.2.6.1 - Remove unecessary dependency on off_t. diff --git a/documentation/index.txt b/documentation/index.txt new file mode 100644 index 0000000..783b0c7 --- /dev/null +++ b/documentation/index.txt @@ -0,0 +1,38 @@ +/*!\file index.c +\brief Create the HTML index of the reports +*/ + + + + +/*! \fn void make_index(void) +Create the main HTML index of the available reports. +*/ + + + + + +/*! \fn static void file_index_to_date_index(const char *entry) +Convert a report from the file tree into a report for a date tree. + +This function is invoked for each directory entry when ::IndexTree request a date index. +The function has to opportunity to convert a previous entry created when ::IndexTree was +requesting a file index. + +\param entry The directory name that may require to be converted. +*/ + + + + + +/*! \fn static void date_index_to_file_index(const char *entry) +Convert a report from the date tree into a report for a file tree. + +This function is invoked for each directory entry when ::IndexTree request a file index. +The function has to opportunity to convert a previous entry created when ::IndexTree was +requesting a date index. + +\param entry The directory name that may require to be converted. +*/ diff --git a/documentation/util.txt b/documentation/util.txt index 7db97af..4b032e9 100644 --- a/documentation/util.txt +++ b/documentation/util.txt @@ -422,6 +422,15 @@ in the connection directory. +/*! \fn static void copy_images(void) +Copy the images (in fact all the files) from the directory ::IMAGEDIR into the output directory +whose name is in ::outdir. +*/ + + + + + /*! \fn void vrfydir(const char *per1, const char *addr, const char *site, const char *us, const char *form) Create a directory to generate a report for the specified connection data and populate it with the a sarg-date file containing the current date. diff --git a/include/conf.h b/include/conf.h index 560c08b..9ec03fc 100755 --- a/include/conf.h +++ b/include/conf.h @@ -147,7 +147,6 @@ char per_hour[128]; char code[MAXLEN]; char code2[MAXLEN]; char tmp[MAXLEN]; -char tmp2[MAXLEN]; char tmp3[MAXLEN]; char tmp4[MAXLEN]; char tmp5[MAXLEN]; diff --git a/include/info.h b/include/info.h index 43d86d3..fe1969c 100755 --- a/include/info.h +++ b/include/info.h @@ -1,3 +1,3 @@ -#define VERSION PACKAGE_VERSION" Dec-23-2009" +#define VERSION PACKAGE_VERSION" Dec-27-2009" #define PGM PACKAGE_NAME #define URL "http://sarg.sourceforge.net" diff --git a/index.c b/index.c index f708770..11f07ed 100644 --- a/index.c +++ b/index.c @@ -26,9 +26,11 @@ #include "include/conf.h" #include "include/defs.h" +static void file_index_to_date_index(const char *entry); +static void date_index_to_file_index(const char *entry); + void make_index(void) { - FILE *fp_ou, *fp_ou2, *fp_ou3, *fp_tmp, *fp_tmp2, *fp_tmp3; DIR *dirp, *dirp2, *dirp3; struct dirent *direntp; @@ -49,11 +51,9 @@ void make_index(void) char ftime[128]; char day[16], mon[16], year[40], hour[10]; char *str; + char tmp2[MAXLEN]; int cstatus; int iyear, imonth, iday, ihour, iminute, isecond, idst; - char y1[5], y2[5]; - char d1[3], d2[3]; - char m1[4], m2[4]; struct getwordstruct gwarea; if(LastLog[0] != '\0') mklastlog(outdir); @@ -70,124 +70,31 @@ void make_index(void) if(debug) debuga("%s",text[53]); - // Root dir + // convert any old report hierarchy dirp = opendir(outdir); while ((direntp = readdir( dirp )) != NULL) { - if(strcmp(IndexTree,"date") == 0) { - if(!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1])) continue; - if(strlen(direntp->d_name) > 4) { - bzero(y1,5); - bzero(y2,5); - bzero(m1,4); - bzero(m2,4); - bzero(d1,3); - bzero(d2,3); - if(strcmp(df,"u") == 0) { - strncpy(y1,direntp->d_name,4); - strncpy(m1,direntp->d_name+4,3); - strncpy(d1,direntp->d_name+7,2); - strncpy(y2,direntp->d_name+10,4); - strncpy(m2,direntp->d_name+14,3); - strncpy(d2,direntp->d_name+17,2); - } else if(strcmp(df,"e") == 0) { - strncpy(y1,direntp->d_name+5,4); - strncpy(m1,direntp->d_name+2,3); - strncpy(d1,direntp->d_name,2); - strncpy(y2,direntp->d_name+15,4); - strncpy(m2,direntp->d_name+12,3); - strncpy(d2,direntp->d_name+10,2); - } - conv_month(m1); - conv_month(m2); - } - sprintf(val1,"%s%s",outdir,y1); - if(access(val1, R_OK) != 0) mkdir(val1,0755); - if(strcmp(m1,m2) != 0) sprintf(val2,"%s/%s-%s",val1,m1,m2); - else sprintf(val2,"%s/%s",val1,m1); - if(access(val2, R_OK) != 0) mkdir(val2,0755); - if(strcmp(d1,d2) != 0) sprintf(val3,"%s/%s-%s",val2,d1,d2); - else sprintf(val3,"%s/%s",val2,d1); - sprintf(val4,"%s%s",outdir,direntp->d_name); - rename(val4,val3); - sprintf(val5,"%s/images",val2); - if(access(val5, R_OK) != 0) { - sprintf(val5,"ln -s \"%simages\" \"%s/images\"",outdir,val2); - cstatus=system(val5); - if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) { - fprintf(stderr, "SARG: command return status %d\n",WEXITSTATUS(cstatus)); - fprintf(stderr, "SARG: command: %s\n",val5); - exit(1); - } - } - } else { - if(!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1])) continue; - if(strlen(direntp->d_name) == 4) { - strcpy(y1,direntp->d_name); - sprintf(val1,"%s%s",outdir,direntp->d_name); - dirp2 = opendir(val1); - while ((direntp2 = readdir( dirp2 )) != NULL) { - if(!isdigit(direntp2->d_name[0]) && !isdigit(direntp2->d_name[1])) continue; - sprintf(val2,"%s/%s",val1,direntp2->d_name); - dirp3 = opendir(val2); - while ((direntp3 = readdir( dirp3 )) != NULL) { - if(!isdigit(direntp3->d_name[0]) && !isdigit(direntp3->d_name[1])) continue; - bzero(newname,512); - strcpy(warea,direntp2->d_name); - if((str = strchr(warea,'-')) != 0) { - *str++ = '\0'; - strcpy(m1,warea); - strcpy(m2,str); - conv_month_name(m1); - conv_month_name(m2); - } else { - strcpy(m1,warea); - conv_month_name(m1); - strcpy(m2,m1); - } - strcpy(warea,direntp3->d_name); - if((str = strchr(warea,'-')) != 0) { - *str++ = '\0'; - strcpy(d1,warea); - strcpy(d2,warea); - } else { - strcpy(d1,warea); - strcpy(d2,warea); - } - if(strcmp(df,"u") == 0) sprintf(val4,"%s%s%s%s-%s%s%s",outdir,y1,m1,d1,y1,m2,d2); - else if(strcmp(df,"e") == 0) sprintf(val4,"%s%s%s%s-%s%s%s",outdir,d1,m1,y1,d2,m2,y1); - sprintf(val5,"%s%s/%s/%s",outdir,y1,direntp2->d_name,direntp3->d_name); - if(rename(val5,val4)) { - fprintf(stderr, "SARG: (index) rename error - %s\n",strerror(errno)); - exit(1); - } - } - (void)rewinddir( dirp3 ); - (void)closedir( dirp3 ); - } - (void)rewinddir( dirp2 ); - (void)closedir( dirp2 ); - } -// sprintf(cmd,"rm -rf %s%s\n",outdir,direntp->d_name); -// system(cmd); + if(isdigit(direntp->d_name[0]) && isdigit(direntp->d_name[1])) { + if(strcmp(IndexTree,"date") == 0) + file_index_to_date_index(direntp->d_name); + else + date_index_to_file_index(direntp->d_name); } } - (void)rewinddir( dirp ); - (void)closedir( dirp ); if((fp_tmp=fopen(wdir_tmp,"w"))==NULL) { fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp); exit(1); } - dirp = opendir(outdir); + rewinddir(dirp); while ((direntp = readdir( dirp )) != NULL) { if(strcmp(IndexTree,"date") == 0) { - if(strlen(direntp->d_name) > 4 || (!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1]))) continue; + if(strlen(direntp->d_name) > 4 || !isdigit(direntp->d_name[0]) || !isdigit(direntp->d_name[1]) || + !isdigit(direntp->d_name[2]) || !isdigit(direntp->d_name[3])) continue; fprintf(fp_tmp,"%s\t%s\n",direntp->d_name,get_size(outdir,direntp->d_name)); - continue; } else { - if(strstr(direntp->d_name,"-") == 0) continue; - bzero(newname, 512); + if(strchr(direntp->d_name,'-') == 0) continue; + bzero(newname, sizeof(newname)); if(strcmp(df,"u") == 0) { strncat(newname,direntp->d_name,4); strncpy(month,direntp->d_name+4,3); @@ -241,15 +148,11 @@ void make_index(void) buildymd(day,mon,year,ftime); fprintf(fp_tmp,"%s%02d%02d%02d;%s;%s;%s;%s;%s;%s\n",ftime, ihour, iminute, isecond, direntp->d_name, data, tuser, tbytes, media,newname); } - continue; } } - if(fp_tmp) fclose(fp_tmp); - if(strcmp(IndexTree,"file") == 0) { - (void)rewinddir( dirp ); - (void)closedir( dirp ); - } + fclose(fp_tmp); + (void)closedir( dirp ); if(strcmp(IndexTree,"date") == 0) { if(strcmp(IndexSortOrder,"A") == 0) sprintf(warea,"sort -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2); @@ -288,11 +191,10 @@ void make_index(void) } dirp2 = opendir(tmp2); while ((direntp2 = readdir( dirp2 )) != NULL) { - if(!isdigit(direntp2->d_name[0]) && !isdigit(direntp2->d_name[1])) continue; + if(!isdigit(direntp2->d_name[0]) || !isdigit(direntp2->d_name[1])) continue; fprintf(fp_ou2,"%s\n",direntp2->d_name); } if(fp_ou2) fclose(fp_ou2); - (void)rewinddir(dirp2); (void)closedir(dirp2); sprintf(wdir_tmp3,"%s%s/index.sort",outdir,tmp4); if(strcmp(IndexSortOrder,"A") == 0) sprintf(csort,"sort -n \"%s\" -o \"%s\"", tmp3, wdir_tmp3); @@ -381,8 +283,6 @@ void make_index(void) write_html_trailer(fp_ou2); if(fp_ou2) fclose(fp_ou2); } - (void)rewinddir(dirp); - (void)closedir(dirp); if(fp_tmp) fclose(fp_tmp); unlink(tmp6); unlink(wdir_tmp2); @@ -442,3 +342,174 @@ void make_index(void) write_html_trailer(fp_ou); if(fp_ou) fclose(fp_ou); } + +static void file_index_to_date_index(const char *entry) +{ + int y1, y2, d1, d2; + int i, j; + int ndirlen; + char m1[8], m2[8]; + char olddir[MAXLEN], newdir[MAXLEN]; + + if(strlen(entry) < 19) return; + + y1=0; + y2=0; + memset(m1,0,sizeof(m1)); + memset(m2,0,sizeof(m2)); + d1=0; + d2=0; + i=0; + if(strcmp(df,"u") == 0) { + for (j=0 ; entry[i] && isdigit(entry[i]) ; j++) + y1=y1*10+(entry[i++]-'0'); + if (j!=4) return; + for (j=0 ; jd_name[0]) || !isdigit(direntp2->d_name[1])) continue; + i=0; + str=direntp2->d_name; + for (j=0 ; j=sizeof(m1)) continue; + m1[j]='\0'; + conv_month_name(m1); + if (str[i]=='-') { + i++; + for (j=0 ; j=sizeof(m2)) continue; + m2[j]='\0'; + conv_month_name(m2); + } else if (!str[i]) { + strcpy(m2,m1); + } else { + continue; + } + + sprintf(val1+val1len,"/%s",direntp2->d_name); + dirp3 = opendir(val1); + if (!dirp3) continue; + while ((direntp3 = readdir( dirp3 )) != NULL) { + if(!isdigit(direntp3->d_name[0]) || !isdigit(direntp3->d_name[1])) continue; + i=0; + str=direntp3->d_name; + d1=0; + for (j=0 ; str[i] && isdigit(str[i]) ; j++) + d1=d1*10+(str[i++]-'0'); + if (j!=2) continue; + if (str[i]=='-') { + i++; + d2=0; + for (j=0 ; str[i] && isdigit(str[i]) ; j++) + d2=d2*10+(str[i++]-'0'); + if (j!=2) continue; + } else if (!str[i]) { + d2=d1; + } else { + continue; + } + + if(strcmp(df,"u") == 0) sprintf(newdir,"%s%04d%s%02d-%04d%s%02d",outdir,y1,m1,d1,y1,m2,d2); + else if(strcmp(df,"e") == 0) sprintf(newdir,"%s%02d%s%04d-%02d%s%04d",outdir,d1,m1,y1,d2,m2,y1); + else continue; + sprintf(olddir,"%s%04d/%s/%s",outdir,y1,direntp2->d_name,direntp3->d_name); + if(rename(olddir,newdir)) { + fprintf(stderr, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir,newdir,strerror(errno)); + exit(1); + } + } + (void)closedir( dirp3 ); + } + (void)closedir( dirp2 ); +} + diff --git a/log.c b/log.c index 62a853b..a159326 100644 --- a/log.c +++ b/log.c @@ -103,6 +103,7 @@ int main(int argc,char *argv[]) char *str; char bufz[MAXLEN]; char bufy[MAXLEN]; + char tmp2[MAXLEN]; enum InputLogFormat ilf; int ilf_count[ILF_Last]; int ch; @@ -1102,6 +1103,7 @@ int main(int argc,char *argv[]) if(testvaliduserchar(user)) continue; +#if 0 if((str = strstr(user,"%20")) != NULL) { /* Why is it necessary to truncate the user name at the first space ? @@ -1123,6 +1125,7 @@ int main(int argc,char *argv[]) *str='.'; for (x=3 ; str[x] ; x++) str[x-2]=str[x]; } +#endif for(str=user; *str; str++) { if(*str=='.') dotinuser++; diff --git a/useragent.c b/useragent.c index c98d1fc..7ce1634 100644 --- a/useragent.c +++ b/useragent.c @@ -37,6 +37,7 @@ void useragent(void) char agent_old[MAXLEN]="$#%0a3bc6"; char hfile[MAXLEN]; char idate[MAXLEN], fdate[MAXLEN]; + char tmp2[MAXLEN]; int agentot=0, agentot2=0, agentdif=0, cont=0, nagent; unsigned long totregsl=0; int cstatus; diff --git a/util.c b/util.c index 13bb78b..aa393d9 100644 --- a/util.c +++ b/util.c @@ -351,7 +351,6 @@ void conv_month(char *month) for(x=0; x<12 && strcmp(mtab1[x],month)!=0; x++); sprintf(month,"%02d",x+1); - } @@ -794,18 +793,70 @@ void gperiod(const char *dirname, const char *period) } -void vrfydir(const char *per1, const char *addr, const char *site, const char *us, const char *form) +static void copy_images(void) { FILE *img_in, *img_ou; + char images[512]; + char imgdir[MAXLEN]; + char srcfile[MAXLEN]; + char dstfile[MAXLEN]; + DIR *dirp; + struct dirent *direntp; + char buffer[MAXLEN]; + size_t nread; + struct stat info; + + if (snprintf(images,sizeof(images),"%simages",outdir)>=sizeof(images)) { + fprintf(stderr,"SARG: Cannot copy images to target directory %simages\n",outdir); + exit(1); + } + if (access(images,R_OK)!=0) { + mkdir(images,0755); + } + + strcpy(imgdir,IMAGEDIR); + dirp = opendir(imgdir); + if(dirp==NULL) { + fprintf(stderr, "SARG: (util) %s %s: %s\n","Can't open directory", imgdir,strerror(errno)); + return; + } + while ((direntp = readdir( dirp )) != NULL ){ + if(direntp->d_name[0]=='.') + continue; + sprintf(srcfile,"%s/%s",imgdir,direntp->d_name); + if (stat(srcfile,&info)) { + fprintf(stderr,"SARG: Cannot stat \"%s\" - %s\n",srcfile,strerror(errno)); + continue; + } + if (S_ISREG(info.st_mode)) { + sprintf(dstfile,"%s/%s",images,direntp->d_name); + img_in = fopen(srcfile, "rb"); + if(img_in!=NULL) { + img_ou = fopen(dstfile, "wb"); + if(img_ou!=NULL) { + while ((nread = fread(buffer,1,sizeof(buffer),img_in))>0) { + fwrite(buffer,1,nread,img_ou); + } + fclose(img_ou); + } else + fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open/create file", dstfile, strerror(errno)); + fclose(img_in); + } else + fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open file", srcfile, strerror(errno)); + } + } + (void) closedir(dirp); + + return; +} + +void vrfydir(const char *per1, const char *addr, const char *site, const char *us, const char *form) +{ FILE *fp_ou; int num=1, count=0; - int c; char wdir[MAXLEN]; char per2[MAXLEN]; char dirname2[MAXLEN]; - char images[512]; - DIR *dirp; - struct dirent *direntp; char y1[5], y2[5]; char d1[3], d2[3]; char m1[8], m2[8]; @@ -946,8 +997,6 @@ void vrfydir(const char *per1, const char *addr, const char *site, const char *u } strcpy(dirname2,wdir); - sprintf(images,"%simages",outdir); - mkdir(images,0755); sprintf(wdir,"%s/sarg-date",dirname); if ((fp_ou = fopen(wdir, "wt")) == 0) { @@ -962,41 +1011,9 @@ void vrfydir(const char *per1, const char *addr, const char *site, const char *u fprintf(fp_ou,"%s %d\n",wdir,loctm->tm_isdst); fclose(fp_ou); - strcpy(per2,IMAGEDIR); - - dirp = opendir(per2); - if(dirp==NULL) { - fprintf(stderr, "SARG: (util) %s %s: %s\n","Can't open directory", per2,strerror(errno)); - return; - } - while ((direntp = readdir( dirp )) != NULL ){ - if(strncmp(direntp->d_name,".",1) == 0) - continue; - sprintf(val10,"%s/%s",per2,direntp->d_name); - sprintf(val11,"%s/%s",images,direntp->d_name); - img_in = fopen(val10, "rb"); - if(img_in!=NULL) { - img_ou = fopen(val11, "wb"); - if(img_ou!=NULL) { - while ((c = fgetc(img_in))!=EOF) { - fputc(c,img_ou); - } - fclose(img_ou); - } else - fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open/create file", val11, strerror(errno)); - fclose(img_in); - } else - fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open file", val10, strerror(errno)); - } - (void) rewinddir(dirp); - (void) closedir(dirp); - - return; - - + copy_images(); } - void strip_latin(char *line) { int i,j;