]> git.ipfire.org Git - thirdparty/sarg.git/blame - download.c
Remove string copies and protect against possible buffer overflow
[thirdparty/sarg.git] / download.c
CommitLineData
25697a35 1/*
94ff9470 2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
1164c474 3 * 1998, 2010
25697a35
GS
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
1164c474
FM
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
25697a35
GS
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26
27#include "include/conf.h"
5f3cfd1d 28#include "include/defs.h"
25697a35 29
6e792ade
FM
30static char *DownloadSuffix=NULL;
31static char **DownloadSuffixIndex=NULL;
32static int NDownloadSuffix=0;
33
32e71fa4 34void download_report(void)
25697a35
GS
35{
36
37 FILE *fp_in = NULL, *fp_ou = NULL;
4157aa09 38
ac422f9b 39 char *buf;
e5b2c6f0 40 char *url;
25697a35 41 char report_in[MAXLEN];
25697a35
GS
42 char wdirname[MAXLEN];
43 char report[MAXLEN];
d6e703cc 44 char period[100];
25697a35
GS
45 char ip[MAXLEN];
46 char oip[MAXLEN];
47 char user[MAXLEN];
48 char ouser[MAXLEN];
49 char ouser2[MAXLEN];
50 char data[15];
51 char hora[15];
25697a35
GS
52 char *str;
53 int z=0;
54 int count=0;
dfb337be 55 int i;
9c7c6346 56 struct getwordstruct gwarea;
ac422f9b 57 struct longlinestruct line;
25697a35
GS
58
59 ouser[0]='\0';
4157aa09 60 ouser2[0]='\0';
25697a35
GS
61
62 sprintf(report_in,"%s/sarg/download.log",TempDir);
63 if(access(report_in, R_OK) != 0)
64 return;
65
66 strcpy(wdirname,dirname);
67 sprintf(report,"%s/download.html",wdirname);
68 strcat(wdirname,"/");
d6e703cc 69 strcat(wdirname,"sarg-period");
25697a35
GS
70
71 if ((fp_in = fopen(wdirname, "r")) == 0) {
72 fprintf(stderr, "SARG: (download) %s: %s\n",text[45],wdirname);
73 exit(1);
74 }
75
05b90947
FM
76 if (!fgets(period,sizeof(period),fp_in)) {
77 fprintf(stderr,"SARG: (download) read error in %s\n",wdirname);
78 exit(1);
79 }
25697a35
GS
80 fclose(fp_in);
81
936c9905 82 if((fp_in=MY_FOPEN(report_in,"r"))==NULL) {
25697a35
GS
83 fprintf(stderr, "SARG: (download) %s: %s\n",text[8],report_in);
84 exit(1);
85 }
86
936c9905 87 if((fp_ou=MY_FOPEN(report,"w"))==NULL) {
25697a35
GS
88 fprintf(stderr, "SARG: (download) %s: %s\n",text[8],report);
89 exit(1);
90 }
91
c0ec9cc7 92 write_html_header(fp_ou,(IndexTree == INDEX_TREE_DATE) ? 3 : 1,_("Downloads"));
b18ce4a0
FM
93 fprintf(fp_ou,"<tr><td class=\"header_l\">%s: %s</td></tr>\n",text[89],period);
94 fprintf(fp_ou,"<tr><th class=\"header_c\">%s</th></tr>\n",text[125]);
c0ec9cc7 95 close_html_header(fp_ou);
25697a35 96
c0ec9cc7 97 fputs("<div class=\"report\"><table cellpadding=\"0\" cellspacing=\"2\">\n",fp_ou);
25697a35 98 fputs("<tr><td></td></tr>\n",fp_ou);
b18ce4a0 99 fprintf(fp_ou,"<tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th></tr>\n",text[98],text[111],text[110],text[91]);
25697a35 100
ac422f9b
FM
101 if (longline_prepare(&line)<0) {
102 debuga(_("Not enough memory to read the downloaded files"));
103 exit(1);
104 }
105
106 while((buf=longline_read(fp_in,&line))!=NULL) {
9c7c6346
FM
107 getword_start(&gwarea,buf);
108 if (getword(data,sizeof(data),&gwarea,'\t')<0 || getword(hora,sizeof(hora),&gwarea,'\t')<0 ||
e5b2c6f0
FM
109 getword(user,sizeof(user),&gwarea,'\t')<0 || getword(ip,sizeof(ip),&gwarea,'\t')<0) {
110 debuga(_("Maybe you have a broken record or garbage in your %s file"),report_in);
111 exit(1);
112 }
113 if (getword_ptr(buf,&url,&gwarea,'\t')<0) {
114 debuga(_("Maybe you have a broken url in your %s file"),report_in);
4bcb77cf
FM
115 exit(1);
116 }
dfb337be 117
25697a35
GS
118 if((str=(char *) strstr(user, "_")) != (char *) NULL ) {
119 if((str=(char *) strstr(str+1, "_")) != (char *) NULL )
120 fixip(user);
121 }
122
246c8489 123 if(Ip2Name)
a1c55d8c 124 ip2name(ip,sizeof(ip));
25697a35
GS
125
126 if(!z) {
127 strcpy(ouser,user);
128 strcpy(oip,ip);
129 z++;
130 } else {
131 if(strcmp(ouser,user) == 0)
132 user[0]='\0';
133 if(user[0] != '\0')
134 strcpy(ouser,user);
4157aa09 135 if(strcmp(oip,ip) == 0)
25697a35
GS
136 ip[0]='\0';
137 if(ip[0] != '\0')
138 strcpy(oip,ip);
139 }
140
965c4a6f 141 user_find(name, sizeof(name), user);
25697a35 142
48864d28
FM
143 if(dotinuser && strchr(name,'_')) {
144 subs(name,sizeof(name),"_",".");
94ff9470
GS
145 }
146
147 if(DownloadReportLimit) {
25697a35 148 if(strcmp(ouser2,name) == 0) {
4157aa09 149 count++;
25697a35
GS
150 } else {
151 count=1;
152 strcpy(ouser2,name);
153 }
94ff9470 154 if(count >= DownloadReportLimit)
25697a35
GS
155 continue;
156 }
157
dfb337be 158 for (i=strlen(url)-1 ; i>=0 && (unsigned char)url[i]<' ' ; i--) url[i]=0;
25697a35 159
dfb337be 160 fprintf(fp_ou,"<tr><td class=\"data\">%s</td><td class=\"data\">%s</td><td class=\"data\">%s-%s</td><td class=\"data2\">",name,ip,data,hora);
ac422f9b
FM
161 if(BlockIt[0]!='\0') {
162 fprintf(fp_ou,"<a href=\"%s%s?url=\"",wwwDocumentRoot,BlockIt);
163 output_html_url(fp_ou,url);
164 fprintf(fp_ou,"\"><img src=\"%s/sarg-squidguard-block.png\"></a>&nbsp;",ImageFile);
165 }
e5b2c6f0 166 fputs("<a href=\"html://",fp_ou);
ac422f9b
FM
167 output_html_url(fp_ou,url);
168 fputs("\">",fp_ou);
169 output_html_string(fp_ou,url,100);
dfb337be 170 fputs("</a></td></tr>\n",fp_ou);
25697a35 171 }
25697a35 172 fclose(fp_in);
ac422f9b 173 longline_free(&line);
c0ec9cc7
FM
174
175 fputs("</table></div>\n",fp_ou);
176 write_html_trailer(fp_ou);
25697a35
GS
177 fclose(fp_ou);
178
179 unlink(report_in);
180
181 return;
182}
6e792ade
FM
183
184void free_download(void)
185{
186 if (DownloadSuffix) {
187 free(DownloadSuffix);
188 DownloadSuffix=NULL;
189 }
190 if (DownloadSuffixIndex) {
191 free(DownloadSuffixIndex);
192 DownloadSuffixIndex=NULL;
193 }
194 NDownloadSuffix=0;
195}
196
197void set_download_suffix(const char *list)
198{
199 char *str;
200 int i, j, k;
201 int cmp;
202
203 free_download();
204
205 DownloadSuffix=strdup(list);
206 if (!DownloadSuffix) {
207 fprintf(stderr,"SARG: Download suffix list too long\n");
208 exit(1);
209 }
210 j = 1;
211 for (i=0 ; list[i] ; i++)
212 if (list[i] == ',') j++;
213 DownloadSuffixIndex=malloc(j*sizeof(char *));
214 if (!DownloadSuffixIndex) {
215 fprintf(stderr,"SARG: Too many download suffixes\n");
216 exit(1);
217 }
218
219 str = DownloadSuffix;
220 for (i=0 ; DownloadSuffix[i] ; i++) {
221 if (DownloadSuffix[i] == ',') {
222 DownloadSuffix[i] = '\0';
223 if (*str) {
fabbc7cc 224 cmp = -1;
6e792ade
FM
225 for (j=0 ; j<NDownloadSuffix && (cmp=strcasecmp(str,DownloadSuffixIndex[j]))>0 ; j++);
226 if (cmp != 0) {
227 for (k=NDownloadSuffix ; k>j ; k--)
228 DownloadSuffixIndex[k]=DownloadSuffixIndex[k-1];
229 NDownloadSuffix++;
230 DownloadSuffixIndex[j]=str;
231 }
232 }
233 str=DownloadSuffix+i+1;
234 }
235 }
236
237 if (*str) {
fabbc7cc 238 cmp = -1;
6e792ade
FM
239 for (j=0 ; j<NDownloadSuffix && (cmp=strcasecmp(str,DownloadSuffixIndex[j]))>0 ; j++);
240 if (cmp != 0) {
241 for (k=NDownloadSuffix ; k>j ; k--)
242 DownloadSuffixIndex[k]=DownloadSuffixIndex[k-1];
243 NDownloadSuffix++;
244 DownloadSuffixIndex[j]=str;
245 }
246 }
247}
248
249int is_download_suffix(const char *url)
250{
251 int urllen;
252 int i;
253 int down, up, center;
254 const char *suffix;
255 int cmp;
256 const int max_suffix=10;
257
fabbc7cc 258 if (DownloadSuffix == NULL || NDownloadSuffix == 0) return(0);
6e792ade
FM
259
260 urllen=strlen(url)-1;
261 if (urllen<=0) return(0);
262 if (url[urllen] == '.') return(0); //reject a single trailing dot
8947bb9b
FM
263 for (i=0 ; i<urllen && (url[i]!='/' || url[i+1]=='/') && url[i]!='?' ; i++);
264 if (i>=urllen) return(0); // url is a hostname without any path or file to download
6e792ade
FM
265
266 for (i=0 ; i<=max_suffix && i<urllen && url[urllen-i]!='.' ; i++)
8947bb9b 267 if (url[urllen-i] == '/' || url[urllen-i] == '?') return(0);
6e792ade
FM
268 if (i>max_suffix || i>=urllen) return(0);
269
270 suffix=url+urllen-i+1;
271 down=0;
272 up=NDownloadSuffix-1;
273 while (down<=up) {
274 center=(down+up)/2;
275 cmp=strcasecmp(suffix,DownloadSuffixIndex[center]);
276 if (cmp == 0) return(1);
277 if (cmp < 0)
278 up = center-1;
279 else
280 down = center+1;
281 }
282 return(0);
283}
284