]>
Commit | Line | Data |
---|---|---|
25697a35 | 1 | /* |
c37945ed | 2 | * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com |
e3af0ae9 | 3 | * 1998, 2009 |
94ff9470 | 4 | * SARG Squid Analysis Report Generator http://sarg.sourceforge.net |
25697a35 GS |
5 | * |
6 | * SARG donations: | |
7 | * please look at http://sarg.sourceforge.net/donations.php | |
8 | * --------------------------------------------------------------------- | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; either version 2 of the License, or | |
13 | * (at your option) any later version. | |
14 | * | |
15 | * This program is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | * GNU General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU General Public License | |
21 | * along with this program; if not, write to the Free Software | |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
23 | * | |
24 | */ | |
25 | ||
26 | #include "include/conf.h" | |
5f3cfd1d | 27 | #include "include/defs.h" |
25697a35 | 28 | |
d6e703cc FM |
29 | static char **files_done = NULL; |
30 | static int nfiles_done = 0; | |
31 | ||
32 | ||
5f3cfd1d | 33 | static void read_log(const char *wentp, FILE *fp_ou) |
491b862f GS |
34 | { |
35 | FILE *fp_in = NULL; | |
36 | char bufbsf[255]; | |
37 | char leks[5], sep[2], res[MAXLEN]; | |
38 | char mon[10], hour[15]; | |
39 | char list[MAXLEN]; | |
40 | char wdata[127]; | |
41 | int idata=0; | |
d6e703cc | 42 | int i; |
06e3cc62 | 43 | char *str; |
491b862f GS |
44 | |
45 | if(debug) { | |
46 | strcpy(buf,text[7]); | |
4bcb77cf FM |
47 | if (getword(urly,sizeof(urly),buf,' ')<0 || getword(href,sizeof(href),buf,' ')<0) { |
48 | printf("SARG: Maybe you have a broken record or garbage in your %s string.\n",text[7]); | |
49 | exit(1); | |
50 | } | |
d2fe0c32 | 51 | debuga("%s squidGuard %s: %s",urly,buf,wentp); |
491b862f | 52 | } |
d6e703cc FM |
53 | |
54 | /* With squidGuard, you can log groups in only one log file. | |
55 | We must parse each log files only one time. Example : | |
56 | dest porn { | |
57 | domainlist porn/domains | |
58 | urllist porn/urls | |
59 | log file1.log | |
60 | } | |
61 | dest aggressive { | |
62 | domainlist aggressive/domains | |
63 | urllist aggressive/urls | |
64 | log file2.log | |
65 | } | |
66 | dest audio-video { | |
67 | domainlist audio-video/domains | |
68 | urllist audio-video/urls | |
69 | log file1.log | |
70 | } | |
71 | */ | |
72 | for (i=0; i<nfiles_done; i++) | |
73 | if (!strcmp(wentp, files_done[i])) return; | |
06e3cc62 | 74 | |
d6e703cc FM |
75 | nfiles_done++; |
76 | files_done = realloc(files_done, nfiles_done*sizeof(char *)); | |
77 | if (!files_done) { | |
78 | perror("parse squidGuard - realloc"); | |
79 | exit(EXIT_FAILURE); | |
80 | } | |
81 | files_done[nfiles_done-1] = strdup(wentp); | |
82 | if (!files_done[nfiles_done-1]) { | |
83 | perror("parse squidGuard - strdup"); | |
84 | exit(EXIT_FAILURE); | |
85 | } | |
86 | ||
491b862f GS |
87 | if ((fp_in=fopen(wentp,"r"))==NULL) { |
88 | fprintf(stderr, "SARG: (squidguard) %s: %s\n",text[8],wentp); | |
89 | exit(1); | |
90 | } | |
06e3cc62 | 91 | |
491b862f GS |
92 | while (fgets(buf,sizeof(buf),fp_in) != NULL) { |
93 | if(strlen(SquidGuardLogFormat) > 0) { | |
94 | strcpy(bufbsf,SquidGuardLogFormat); | |
95 | leks[0]='\0'; | |
4bcb77cf FM |
96 | if (getword(leks,sizeof(leks),bufbsf,'#')<0) { |
97 | printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp); | |
98 | exit(1); | |
99 | } | |
491b862f | 100 | while(strcmp(leks,"end") != 0) { |
4bcb77cf FM |
101 | if (getword(leks,sizeof(leks),bufbsf,'#')<0 || getword(sep,sizeof(sep),bufbsf,'#')<0) { |
102 | printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp); | |
103 | exit(1); | |
104 | } | |
491b862f | 105 | if(strcmp(leks,"end") != 0) { |
4bcb77cf FM |
106 | if (getword(res,sizeof(res),buf,sep[0])<0) { |
107 | printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp); | |
108 | exit(1); | |
109 | } | |
491b862f GS |
110 | if(strcmp(leks,"year") == 0) |
111 | strcpy(year,res); | |
112 | else if(strcmp(leks,"year") == 0) | |
113 | strcpy(year,res); | |
114 | else if(strcmp(leks,"mon") == 0) | |
115 | strcpy(mon,res); | |
116 | else if(strcmp(leks,"day") == 0) | |
117 | strcpy(day,res); | |
118 | else if(strcmp(leks,"hour") == 0) | |
119 | strcpy(hour,res); | |
120 | else if(strcmp(leks,"list") == 0) | |
121 | strcpy(list,res); | |
122 | else if(strcmp(leks,"ip") == 0) | |
123 | strcpy(ip,res); | |
124 | else if(strcmp(leks,"user") == 0) | |
125 | strcpy(user,res); | |
126 | else if(strcmp(leks,"url") == 0) | |
127 | strcpy(url,res); | |
128 | } | |
129 | } | |
130 | } else { | |
4bcb77cf FM |
131 | if (getword(year,sizeof(year),buf,'-')<0 || getword(mon,sizeof(mon),buf,'-')<0 || |
132 | getword(day,sizeof(day),buf,' ')<0 || getword(hour,sizeof(hour),buf,' ')<0 || | |
133 | getword(list,sizeof(list),buf,'/')<0 || getword(list,sizeof(list),buf,'/')<0 || | |
134 | getword(tmp5,sizeof(tmp5),buf,'/')<0 || getword(tmp5,sizeof(tmp5),buf,'/')<0 || | |
06e3cc62 | 135 | getword(url,sizeof(url),buf,' ')<0 || |
4bcb77cf FM |
136 | getword(ip,sizeof(ip),buf,'/')<0 || getword(user,sizeof(user),buf,' ')<0 || |
137 | getword(user,sizeof(user),buf,' ')<0) { | |
138 | printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp); | |
139 | exit(1); | |
140 | } | |
06e3cc62 FM |
141 | str=strchr(url,'/'); |
142 | if (str) *str='\0'; | |
491b862f GS |
143 | } |
144 | ||
145 | sprintf(warea,"%s%s%s",year,mon,day); | |
146 | sprintf(wdata,"%s%s%s",year,mon,day); | |
147 | idata = atoi(wdata); | |
148 | ||
149 | if(strcmp(SquidguardIgnoreDate,"on") == 0) { | |
28e2bf65 | 150 | if(idata < dfrom || idata > duntil) |
491b862f GS |
151 | continue; |
152 | } | |
153 | ||
154 | if (strcmp(user,"-") == 0) { | |
155 | strcpy(user,ip); | |
05b90947 | 156 | memset(ip,0,sizeof(ip)); |
491b862f | 157 | } |
120d768c | 158 | fprintf(fp_ou,"%s\t%s%s%s\t%s\t%s\t%s\t%s\n",user,year,mon,day,hour,ip,url,list); |
491b862f GS |
159 | squidguard_count++; |
160 | } | |
161 | if (fp_in) fclose(fp_in); | |
162 | return; | |
163 | } | |
164 | ||
165 | ||
32e71fa4 | 166 | void squidguard_log(void) |
25697a35 | 167 | { |
491b862f | 168 | FILE *fp_ou = NULL, *fp_guard = NULL; |
25697a35 GS |
169 | char guard_in[MAXLEN]; |
170 | char guard_ou[MAXLEN]; | |
171 | char logdir[MAXLEN]; | |
491b862f | 172 | char year[10], day[10], mon[10]; |
25697a35 | 173 | char user[MAXLEN]; |
5f3cfd1d | 174 | int y; |
456d78a5 | 175 | int cstatus; |
5f3cfd1d FM |
176 | char *str; |
177 | char *str2; | |
25697a35 | 178 | |
d6e703cc FM |
179 | str2 = user; |
180 | ||
491b862f | 181 | if(strlen(SquidGuardConf) < 1 && strlen(SquidGuardLogAlternate) < 1) |
25697a35 GS |
182 | return; |
183 | ||
491b862f GS |
184 | if (strlen(SquidGuardLogAlternate) > 0) |
185 | SquidGuardConf[0]='\0'; | |
25697a35 GS |
186 | |
187 | sprintf(guard_in,"%s/squidguard.unsort",tmp); | |
188 | sprintf(guard_ou,"%s/squidguard.log",tmp); | |
25697a35 GS |
189 | if((fp_ou=fopen(guard_in,"a"))==NULL) { |
190 | fprintf(stderr, "SARG: (squidguard) %s: %s\n",text[8],guard_in); | |
191 | exit(1); | |
192 | } | |
193 | ||
491b862f GS |
194 | bzero(day, 3); |
195 | bzero(mon, 4); | |
196 | bzero(year, 5); | |
197 | ||
198 | if(strcmp(SquidguardIgnoreDate,"on") == 0) { | |
199 | if(strcmp(df,"e") == 0) { | |
d6e703cc FM |
200 | strncpy(day,period,2); |
201 | strncpy(mon,period+2,3); | |
202 | strncpy(year,period+5,4); | |
491b862f GS |
203 | conv_month(mon); |
204 | sprintf(warea,"%s%s%s",year,mon,day); | |
205 | dfrom=atoi(warea); | |
d6e703cc FM |
206 | strncpy(day,period+10,2); |
207 | strncpy(mon,period+12,3); | |
208 | strncpy(year,period+15,4); | |
491b862f GS |
209 | conv_month(mon); |
210 | sprintf(warea,"%s%s%s",year,mon,day); | |
211 | duntil=atoi(warea); | |
212 | } else { | |
d6e703cc FM |
213 | strncpy(day,period+7,2); |
214 | strncpy(mon,period+4,3); | |
215 | strncpy(year,period,4); | |
491b862f GS |
216 | conv_month(mon); |
217 | sprintf(warea,"%s%s%s",year,mon,day); | |
218 | dfrom=atoi(warea); | |
d6e703cc FM |
219 | strncpy(day,period+17,2); |
220 | strncpy(mon,period+14,3); | |
221 | strncpy(year,period+10,4); | |
491b862f GS |
222 | conv_month(mon); |
223 | sprintf(warea,"%s%s%s",year,mon,day); | |
224 | duntil=atoi(warea); | |
25697a35 | 225 | } |
491b862f | 226 | } |
25697a35 | 227 | |
120d768c | 228 | if(SquidGuardConf[0] != 0) { |
491b862f | 229 | if(access(SquidGuardConf, R_OK) != 0) { |
d2fe0c32 | 230 | debuga("Cannot open squidGuard config file: %s",SquidGuardConf); |
491b862f GS |
231 | exit(1); |
232 | } | |
25697a35 | 233 | |
491b862f GS |
234 | if((fp_guard=fopen(SquidGuardConf,"r"))==NULL) { |
235 | fprintf(stderr, "SARG: (squidguard) %s: %s\n",text[8],SquidGuardConf); | |
236 | exit(1); | |
237 | } | |
5f3cfd1d FM |
238 | |
239 | logdir[0]=0; | |
491b862f GS |
240 | while(fgets(buf,sizeof(buf),fp_guard)!=NULL) { |
241 | if(strstr(buf,"\n") != 0) | |
242 | buf[strlen(buf)-1]='\0'; | |
5f3cfd1d FM |
243 | if((str=get_param_value("logdir",buf))!=NULL) { |
244 | if (getword(logdir,sizeof(logdir),str,' ')<0) { | |
245 | printf("SARG: Maybe you have an invalid logdir line in your %s file.\n",SquidGuardConf); | |
4bcb77cf FM |
246 | exit(1); |
247 | } | |
5f3cfd1d FM |
248 | } else if((str=get_param_value("log",buf))!=NULL) { |
249 | if((str2=get_param_value("anonymous",str))!=NULL) | |
250 | str=str2; | |
d6e703cc | 251 | |
5f3cfd1d FM |
252 | /* |
253 | If logdir is defined, we prepend it to the log file name, otherwise, we assume | |
254 | the log directive provides an absolute file name to the log file. Therefore, | |
255 | we don't need to add an additionnal / at the beginning of the log file name. | |
256 | */ | |
257 | y=(logdir[0]) ? sprintf(wentp,"%s/",logdir) : 0; | |
258 | /* | |
259 | Spaces are allowed in the name of the log file. The file name ends at the first # | |
260 | because it is assumed it is an end of line comment. Any space before the # is then | |
261 | removed. Any control character (i.e. a character with a code lower than 32) ends | |
262 | the file name. That includes the terminating zero. | |
263 | */ | |
264 | while((unsigned char)*str>=' ' && *str!='#' && y<sizeof(wentp)-1) | |
265 | wentp[y++]=*str++; | |
266 | if(*str=='#') { | |
267 | str--; | |
268 | while(*str==' ' && y>0) { | |
269 | str--; | |
270 | y--; | |
4bcb77cf | 271 | } |
d6e703cc | 272 | } |
5f3cfd1d | 273 | wentp[y]=0; |
491b862f | 274 | read_log(wentp,fp_ou); |
25697a35 | 275 | } |
25697a35 | 276 | } |
491b862f GS |
277 | } else { |
278 | sprintf(wentp,"%s",SquidGuardLogAlternate); | |
279 | read_log(wentp,fp_ou); | |
280 | } | |
281 | ||
282 | if (fp_guard) fclose(fp_guard); | |
283 | if (fp_ou) fclose(fp_ou); | |
284 | ||
c274f011 FM |
285 | if (files_done) { |
286 | for (y=0; y<nfiles_done; y++) | |
287 | if (files_done[y]) free(files_done[y]); | |
288 | free(files_done); | |
289 | } | |
290 | ||
491b862f | 291 | if(debug) { |
d2fe0c32 | 292 | debuga("%s: %s",text[54],guard_ou); |
25697a35 GS |
293 | } |
294 | ||
9a2efbd0 | 295 | sprintf(tmp6,"sort -k 1,1 -k 2,2 -k 4,4 \"%s\" -o \"%s\"",guard_in, guard_ou); |
456d78a5 FM |
296 | cstatus=system(tmp6); |
297 | if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) { | |
298 | fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus)); | |
299 | fprintf(stderr, "SARG: sort command: %s\n",tmp6); | |
300 | exit(1); | |
301 | } | |
491b862f | 302 | |
25697a35 GS |
303 | unlink(guard_in); |
304 | return; | |
305 | } |