X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=denied.c;h=9044b0384f4d0d2f42b4c23e8603e1bb07774fe8;hb=ffc9b006b8358644c054c5e4c2929791efec7475;hp=ecf276e3c4e5e228eda985f27aa01a337c5fb77b;hpb=4bcb77cf900ead8f2d9ba2f7306bb7eb9a3df2c2;p=thirdparty%2Fsarg.git diff --git a/denied.c b/denied.c index ecf276e..9044b03 100644 --- a/denied.c +++ b/denied.c @@ -1,10 +1,11 @@ /* - * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com - * 1998, 2008 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net + * 1998, 2015 * * SARG donations: * please look at http://sarg.sourceforge.net/donations.php + * Support: + * http://sourceforge.net/projects/sarg/forums/forum/363374 * --------------------------------------------------------------------- * * This program is free software; you can redistribute it and/or modify @@ -24,162 +25,279 @@ */ #include "include/conf.h" +#include "include/defs.h" +#include "include/readlog.h" -void gen_denied_report() +//! Name of the file containing the unsorted denied entries. +static char denied_unsort[MAXLEN]=""; +//! The file handle to write the entries. +static FILE *fp_denied=NULL; +//! \c True if at least one denied entry exists. +static bool denied_exists=false; + +/*! +Open a file to store the denied accesses. + +\return The file handle or NULL if no file is necessary. +*/ +void denied_open(void) +{ + if ((ReportType & REPORT_TYPE_DENIED) == 0) { + if (debugz>=LogLevel_Process) debugaz(__FILE__,__LINE__,_("Denied report not produced as it is not requested\n")); + return; + } + if (Privacy) { + if (debugz>=LogLevel_Process) debugaz(__FILE__,__LINE__,_("Denied report not produced because privacy option is active\n")); + return; + } + + snprintf(denied_unsort,sizeof(denied_unsort),"%s/denied.int_unsort",tmp); + if ((fp_denied=MY_FOPEN(denied_unsort,"w"))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),denied_unsort,strerror(errno)); + exit(EXIT_FAILURE); + } + return; +} + +/*! +Write one entry in the unsorted denied file provided that it is required. + +\param log_entry The entry to write into the log file. +*/ +void denied_write(const struct ReadLogStruct *log_entry) +{ + char date[80]; + + if (fp_denied && strstr(log_entry->HttpCode,"DENIED/403") != 0) { + strftime(date,sizeof(date),"%d/%m/%Y\t%H:%M:%S",&log_entry->EntryTime); + fprintf(fp_denied, "%s\t%s\t%s\t%s\n",date,log_entry->User,log_entry->Ip,log_entry->Url); + denied_exists=true; + } +} + +/*! +Close the file opened by denied_open(). +*/ +void denied_close(void) +{ + if (fp_denied) { + if (fclose(fp_denied)==EOF) { + debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),denied_unsort,strerror(errno)); + exit(EXIT_FAILURE); + } + fp_denied=NULL; + } +} + +/*! +Tell the caller if a denied report exists. + +\return \c True if the report is available or \c false if no report +was generated. +*/ +bool is_denied(void) +{ + return(denied_exists); +} + +static void show_ignored_denied(FILE *fp_ou,int count) +{ + char ignored[80]; + + snprintf(ignored,sizeof(ignored),ngettext("%d more denied access not shown here…","%d more denied accesses not shown here…",count),count); + fprintf(fp_ou,"%s\n",ignored); +} + +/*! +Generate a report containing the denied accesses. +*/ +void gen_denied_report(void) { + FILE *fp_in = NULL, *fp_ou = NULL; + + char *buf; + char *url; + char denied_sort[MAXLEN]; + char report[MAXLEN]; + char ip[MAXLEN]; + char oip[MAXLEN]; + char user[MAXLEN]; + char ouser[MAXLEN]=""; + char ouser2[MAXLEN]=""; + char data[15]; + char hora[15]; + char csort[4098]; + bool z=false; + int count=0; + int day,month,year; + int cstatus; + bool new_user; + struct getwordstruct gwarea; + longline line; + struct userinfostruct *uinfo; + struct tm t; + + if (!denied_exists) { + if (!KeepTempLog && denied_unsort[0]!='\0' && unlink(denied_unsort)) + debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),denied_unsort,strerror(errno)); + denied_unsort[0]='\0'; + if (debugz>=LogLevel_Process) debugaz(__FILE__,__LINE__,_("Denied report not produced because it is empty\n")); + return; + } + if (debugz>=LogLevel_Process) + debuga(__FILE__,__LINE__,_("Creating denied accesses report...\n")); + + if (snprintf(denied_sort,sizeof(denied_sort),"%s/denied.int_log",tmp)>=sizeof(denied_sort)) { + debuga(__FILE__,__LINE__,_("Temporary directory path too long to sort the denied accesses\n")); + exit(EXIT_FAILURE); + } + if (snprintf(csort,sizeof(csort),"sort -T \"%s\" -t \"\t\" -k 3,3 -k 5,5 -o \"%s\" \"%s\"",tmp,denied_sort,denied_unsort)>=sizeof(csort)) { + debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),denied_unsort,denied_sort); + exit(EXIT_FAILURE); + } + cstatus=system(csort); + if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) { + debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus)); + debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort); + exit(EXIT_FAILURE); + } + if (unlink(denied_unsort)) { + debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),denied_unsort,strerror(errno)); + exit(EXIT_FAILURE); + } + denied_unsort[0]='\0'; + + sprintf(report,"%s/denied.html",outdirname); + + if((fp_in=MY_FOPEN(denied_sort,"r"))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),denied_sort,strerror(errno)); + exit(EXIT_FAILURE); + } + + if((fp_ou=MY_FOPEN(report,"w"))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),report,strerror(errno)); + exit(EXIT_FAILURE); + } + + write_html_header(fp_ou,(IndexTree == INDEX_TREE_DATE) ? 3 : 1,_("Denied"),HTML_JS_NONE); + fputs("",fp_ou); + fprintf(fp_ou,_("Period: %s"),period.html); + fputs("\n",fp_ou); + fprintf(fp_ou,"%s\n",_("Denied")); + close_html_header(fp_ou); + + fputs("
\n",fp_ou); + fprintf(fp_ou,"\n",_("USERID"),_("IP/NAME"),_("DATE/TIME"),_("ACCESSED SITE")); + + if ((line=longline_create())==NULL) { + debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),denied_sort); + exit(EXIT_FAILURE); + } + + while((buf=longline_read(fp_in,line))!=NULL) { + getword_start(&gwarea,buf); + if (getword(data,sizeof(data),&gwarea,'\t')<0 || getword(hora,sizeof(hora),&gwarea,'\t')<0 || + getword(user,sizeof(user),&gwarea,'\t')<0 || getword(ip,sizeof(ip),&gwarea,'\t')<0) { + debuga(__FILE__,__LINE__,_("Invalid record in file \"%s\"\n"),denied_sort); + exit(EXIT_FAILURE); + } + if (getword_ptr(buf,&url,&gwarea,'\t')<0) { + debuga(__FILE__,__LINE__,_("Invalid url in file \"%s\"\n"),denied_sort); + exit(EXIT_FAILURE); + } + if (sscanf(data,"%d/%d/%d",&day,&month,&year)!=3) continue; + computedate(year,month,day,&t); + strftime(data,sizeof(data),"%x",&t); - FILE *fp_in = NULL, *fp_ou = NULL; - - char url[MAXLEN]; - char html2[MAXLEN]; - char denied_in[MAXLEN]; - char per[MAXLEN]; - char report[MAXLEN]; - char period[100]; - char ip[MAXLEN]; - char oip[MAXLEN]; - char user[MAXLEN]; - char ouser[MAXLEN]; - char ouser2[MAXLEN]; - char data[15]; - char hora[15]; - char *str; - int z=0; - int count=0; - - ouser[0]='\0'; - - sprintf(denied_in,"%s/sarg/denied.log",TempDir); - if(!denied_count) { - unlink(denied_in); - return; - } - - sprintf(per,"%s/sarg-period",dirname); - sprintf(report,"%s/denied.html",dirname); - - if ((fp_in = fopen(per, "r")) == 0) { - fprintf(stderr, "SARG: (denied) %s: %s\n",text[45],per); - exit(1); - } - - fgets(period,sizeof(period),fp_in); - fclose(fp_in); - - if((fp_in=fopen(denied_in,"r"))==NULL) { - fprintf(stderr, "SARG: (denied) %s: %s\n",text[8],denied_in); - exit(1); - } - - if((fp_ou=fopen(report,"w"))==NULL) { - fprintf(stderr, "SARG: (denied) %s: %s\n",text[8],report); - exit(1); - } - - fprintf(fp_ou, "\n\n\n \n",CharSet); - css(fp_ou); - fputs("\n",fp_ou); - fprintf(fp_ou,"\n",BgColor,TxColor,BgImage); - if(strlen(LogoImage) > 0) fprintf(fp_ou, "
%s%s%s%s
\n\n\n
 %s
\n",LogoImage,Width,Height,LogoText); - - if(strcmp(IndexTree,"date") == 0) - show_sarg(fp_ou, "../../.."); - else - show_sarg(fp_ou, ".."); - - fputs("
\n",fp_ou); - sprintf(url,"\n",Title); - fputs(url,fp_ou); - - sprintf(url,"\n",text[89],period); - fputs(url,fp_ou); - sprintf(url,"\n",text[46]); - fputs(url,fp_ou); - fputs("
%s
%s: %s
%s
\n",fp_ou); - - fputs("
\n",fp_ou); - fputs("\n",fp_ou); - sprintf(url,"\n",text[98],text[111],text[110],text[91]); - fputs(url,fp_ou); - - while(fgets(buf,sizeof(buf),fp_in)!=NULL) { - if (getword(data,sizeof(data),buf,' ')<0 || getword(hora,sizeof(hora),buf,' ')<0 || - getword(user,sizeof(user),buf,' ')<0 || getword(ip,sizeof(ip),buf,' ')<0 || - getword(url,sizeof(url),buf,' ')<0) { - printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",denied_in); - exit(1); - } - - if((str=(char *) strstr(user, "_")) != (char *) NULL ) { - if((str=(char *) strstr(str+1, "_")) != (char *) NULL ) - fixip(user); - } - - if(strcmp(Ip2Name,"yes") == 0) - ip2name(ip); - - if(!z) { - strcpy(ouser,user); - strcpy(oip,ip); - z++; - } else { - if(strcmp(ouser,user) == 0) - user[0]='\0'; - if(user[0] != '\0') - strcpy(ouser,user); - if(strcmp(oip,ip) == 0) - ip[0]='\0'; - if(ip[0] != '\0') - strcpy(oip,ip); - } - - if(UserTabFile[0] != '\0') { - sprintf(warea,":%s:",user); - if((str=(char *) strstr(userfile,warea)) != (char *) NULL ) { - z1=0; - str2=(char *) strstr(str+1,":"); - str2++; - bzero(name, MAXLEN); - while(str2[z1] != ':') { - name[z1]=str2[z1]; - z1++; - } - } else strcpy(name,user); - } else strcpy(name,user); - - if(dotinuser && strstr(name,"_")) { - str2=(char *)subs(name,"_","."); - strcpy(name,str2); - } - - if(DeniedReportLimit) { - if(strcmp(ouser2,name) == 0) { - count++; - } else { - count=1; - strcpy(ouser2,name); - } - if(count >= DeniedReportLimit) - continue; - } - - if(strlen(BlockIt) > 0) - sprintf(BlockImage," ",wwwDocumentRoot,BlockIt,url,ImageFile); - else BlockImage[0]='\0'; - - sprintf(html2,"\n",name,ip,data,hora,BlockImage,url,url); - fputs(html2,fp_ou); - } - - fputs("
%s%s%s%s
%s%s%s-%s%s%s
\n",fp_ou); - - show_info(fp_ou); - fputs("\n",fp_ou); - - fclose(fp_in); - fclose(fp_ou); - - unlink(denied_in); - - return; + uinfo=userinfo_find_from_id(user); + if (!uinfo) { + debuga(__FILE__,__LINE__,_("Unknown user ID %s in file \"%s\"\n"),user,denied_sort); + exit(EXIT_FAILURE); + } + + new_user=false; + if(!z) { + strcpy(ouser,user); + strcpy(oip,ip); + z=true; + new_user=true; + } else { + if(strcmp(ouser,user) != 0) { + strcpy(ouser,user); + new_user=true; + } + if(strcmp(oip,ip) != 0) { + strcpy(oip,ip); + new_user=true; + } + } + + if(DeniedReportLimit) { + if(strcmp(ouser2,uinfo->label) == 0) { + count++; + } else { + if(count>DeniedReportLimit && DeniedReportLimit>0) + show_ignored_denied(fp_ou,count-DeniedReportLimit); + count=1; + strcpy(ouser2,uinfo->label); + } + if(count > DeniedReportLimit) + continue; + } + + fputs("",fp_ou); + if (new_user) { + if (uinfo->topuser) + fprintf(fp_ou,"%s%s",uinfo->filename,uinfo->filename,uinfo->label,ip); + else + fprintf(fp_ou,"%s%s",uinfo->label,ip); + } else + fputs("",fp_ou); + fprintf(fp_ou,"%s-%s",data,hora); + if(BlockIt[0] != '\0' && url[0]!=ALIAS_PREFIX) { + fprintf(fp_ou," ",ImageFile); + } + output_html_link(fp_ou,url,100); + fputs("\n",fp_ou); + } + if (fclose(fp_in)==EOF) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),denied_sort,strerror(errno)); + exit(EXIT_FAILURE); + } + longline_destroy(&line); + + if(count>DeniedReportLimit && DeniedReportLimit>0) + show_ignored_denied(fp_ou,count-DeniedReportLimit); + + fputs("
\n",fp_ou); + write_html_trailer(fp_ou); + if (fclose(fp_ou)==EOF) { + debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),report,strerror(errno)); + exit(EXIT_FAILURE); + } + + if (!KeepTempLog && unlink(denied_sort)==-1) + debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),denied_sort,strerror(errno)); + + return; +} + +/*! +Remove any temporary file left by the denied module. +*/ +void denied_cleanup(void) +{ + if (fp_denied){ + if (fclose(fp_denied)==EOF) { + debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),denied_unsort,strerror(errno)); + exit(EXIT_FAILURE); + } + fp_denied=NULL; + } + if (!KeepTempLog && denied_unsort[0]) { + if (unlink(denied_unsort)==-1) + debuga(__FILE__,__LINE__,_("Failed to delete \"%s\": %s\n"),denied_unsort,strerror(errno)); + } }