1 /*
2   By accepting this notice, you agree to be bound by the following
3   agreements:
4 
5   This software product, squidGuard, is copyrighted (C) 1998-2007
6   by Christine Kronberg, Shalla Secure Services. All rights reserved.
7 
8   This program is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License (version 2) as
10   published by the Free Software Foundation.  It is distributed in the
11   hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
12   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13   PURPOSE.  See the GNU General Public License (GPL) for more details.
14 
15   You should have received a copy of the GNU General Public License
16   (GPL) along with this program.
17 */
18 
19 #include "sg.h"
20 
21 struct Setting *lastSetting = NULL;
22 struct Setting *Setting = NULL;                        /* linked list, Calloc */
23 
24 struct Source *lastSource = NULL;
25 struct Source *Source = NULL;                  /* linked list, Calloc */
26 
27 struct Destination *lastDest = NULL;
28 struct Destination *Dest = NULL;               /* linked list, Calloc */
29 
30 struct sgRewrite *lastRewrite = NULL;
31 struct sgRewrite *Rewrite = NULL;              /* linked list, Calloc */
32 struct sgRegExp *lastRewriteRegExec = NULL;
33 
34 struct Time *lastTime = NULL;
35 struct Time *Time = NULL;                      /* linked list, Calloc */
36 
37 struct LogFileStat *globalErrorLog = NULL;
38 struct LogFile *globalLogFile = NULL;
39 
40 struct LogFileStat *lastLogFileStat;
41 struct LogFileStat *LogFileStat;               /* linked list, Calloc */
42 
43 struct TimeElement *lastTimeElement = NULL;
44 struct TimeElement *TimeElement = NULL;
45 
46 struct Acl *lastAcl = NULL;
47 struct Acl *defaultAcl = NULL;
48 struct Acl *Acl = NULL;                                /* linked list, Calloc */
49 struct AclDest *lastAclDest = NULL;
50 
51 struct sgRegExp *lastRegExpDest;
52 
53 struct Source *lastActiveSource;
54 
55 char **globalArgv ;
56 char **globalEnvp ;
57 int globalDebugTimeDelta = 0;
58 int globalDebug = 0;
59 int globalPid = 0;
60 int globalUpdate = 0;
61 int passthrough = 0;
62 int showBar = 0;   /* Do not display the progress bar. */
63 char *globalCreateDb = NULL;
64 int failsafe_mode = 0;
65 int sig_hup = 0;
66 int sig_alrm = 0;
67 int sgtime = 0;
68 char *globalLogDir = NULL;
69 
70 
71 #if __STDC__
main(int argc,char ** argv,char ** envp)72 int main(int    argc,
73          char   **argv,
74 	 char   **envp)
75 #else
76 int main(argc, argv, envp)
77      int argc;
78      char *argv[];
79      char *envp[];
80 #endif
81 {
82   int ch;
83   struct SquidInfo squidInfo;
84   struct Source *src;
85   struct Acl *acl;
86   struct timeval start_time,ready_time,stop_time;
87   char buf[MAX_BUF];
88   char *redirect,tmp[MAX_BUF];
89   char *configFile = NULL;
90   time_t t;
91 #if HAVE_SIGACTION
92   struct sigaction act;
93 #endif
94   gettimeofday(&start_time, NULL);
95   progname = argv[0];
96   globalPid = getpid();
97   while ((ch = getopt(argc, argv, "hbduPC:t:c:v")) != EOF)
98     switch (ch) {
99     case 'd':
100        globalDebug = 1;
101       break;
102     case 'c':
103       configFile = optarg;
104       break;
105     case 'b':
106       showBar = 1;
107     case 'C':
108       globalCreateDb = optarg;
109       break;
110     case 'P':
111       passthrough = 1;
112       break;
113     case 'u':
114       globalUpdate = 1;
115       break;
116     case 'v':
117 #if DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR == 42
118       fprintf(stderr, "SquidGuard: %s %s\n", VERSION,db_version_4002(NULL,NULL,NULL));
119 #else
120       fprintf(stderr, "SquidGuard: %s %s\n", VERSION,db_version(NULL,NULL,NULL));
121 #endif
122       exit(0);
123       break;
124     case 't':
125       if((t = iso2sec(optarg)) == -1){
126 	fprintf(stderr,"-t dateformat error, should be yyyy-mm-ddTHH:MM:SS\n");
127 	exit(0);
128       }
129       if(t < 0){
130 	fprintf(stderr,"-t date have to after 1970-01-01T01:00:00\n");
131 	exit(0);
132       }
133       sgLogError("squidGuard emulating date %s", niso(t));
134       globalDebugTimeDelta = t - start_time.tv_sec;
135       start_time.tv_sec = start_time.tv_sec + globalDebugTimeDelta;
136       break;
137     case '?':
138     case 'h':
139     default:
140       usage();
141     }
142   globalArgv = argv;
143   globalEnvp = envp;
144   sgSetGlobalErrorLogFile();
145   sgReadConfig(configFile);
146   sgSetGlobalErrorLogFile();
147   sgLogError("squidGuard %s started (%d.%03d)",
148 	     VERSION, start_time.tv_sec, start_time.tv_usec/1000);
149   if(globalUpdate || globalCreateDb != NULL){
150     sgLogError("db update done");
151     gettimeofday(&stop_time, NULL);
152     stop_time.tv_sec = stop_time.tv_sec + globalDebugTimeDelta;
153     sgLogError("squidGuard stopped (%d.%03d)",stop_time.tv_sec,stop_time.tv_usec/1000);
154     exit(0);
155   }
156   sgTimeElementSortEvents();
157   sgTimeNextEvent();
158 #if HAVE_SIGACTION
159 #ifndef SA_NODEFER
160 #define SA_NODEFER 0
161 #endif
162   act.sa_handler = sgHandlerSigHUP;
163   act.sa_flags = SA_NODEFER | SA_RESTART;
164   sigaction(SIGHUP, &act, NULL);
165 #else
166 #if HAVE_SIGNAL
167   signal(SIGHUP, sgHandlerSigHUP);
168 #else
169 #endif
170 #endif
171   gettimeofday(&ready_time, NULL);
172   ready_time.tv_sec = ready_time.tv_sec + globalDebugTimeDelta;
173   sgLogError("squidGuard ready for requests (%d.%03d)",
174 	     ready_time.tv_sec, ready_time.tv_usec/1000);
175   tmp[MAX_BUF-1] = '\0';
176   while(1) {
177     while(fgets(buf, MAX_BUF, stdin) != NULL){
178       if(sig_hup) {
179 	sgReloadConfig();
180       }
181       if(failsafe_mode) {
182 	puts("ERR message=\"squidGuard failsafe mode\"");
183 	fflush(stdout);
184 	if(sig_hup){
185           sgReloadConfig();
186 	}
187 	continue;
188       }
189       if(parseLine(buf,&squidInfo) != 1){
190 	sgLogError("Error parsing squid line: %s",buf);
191 	puts("BH message=\"squidGuard error parsing squid line\"");
192       }
193         else {
194 	src = Source;
195 	for(;;){
196 	  strncpy(tmp,squidInfo.src,MAX_BUF-1);
197           tmp[MAX_BUF-1] = 0;   /* force null termination */
198 	  globalLogFile = NULL;
199 	  src = sgFindSource(src, tmp,squidInfo.ident,squidInfo.srcDomain);
200 	  acl = sgAclCheckSource(src);
201 	  if((redirect = sgAclAccess(src,acl,&squidInfo)) == NULL){
202 	    if(src == NULL || src->cont_search == 0){
203 	      puts("ERR");
204 	      break;
205 	    } else
206 	      if(src->next != NULL){
207 		src = src->next;
208 		continue;
209 	      } else {
210 		puts("ERR");
211 		break;
212 	      }
213 	  } else {
214 	    if(squidInfo.srcDomain[0] == '\0'){
215 	      squidInfo.srcDomain[0] = '-';
216 	      squidInfo.srcDomain[1] = '\0';
217 	    }
218 	    if(squidInfo.ident[0] == '\0'){
219 	      squidInfo.ident[0] = '-';
220 	      squidInfo.ident[1] = '\0';
221 	    }
222             if (isdigit(redirect[0]) && isdigit(redirect[1]) && isdigit(redirect[2]) && redirect[3]==':') {
223               fprintf(stdout,"OK status=%c%c%c url=\"%s\"\n", redirect[0], redirect[1], redirect[2], &redirect[4]);
224             } else
225               fprintf(stdout,"OK rewrite-url=\"%s\"\n",redirect);
226             /* sgLogError("%s %s/%s %s %s\n",redirect,squidInfo.src,squidInfo.srcDomain,squidInfo.ident,squidInfo.method);  */
227 	    break;
228 	  }
229 	} /*for(;;)*/
230       }
231       fflush(stdout);
232       if(sig_hup)
233         sgReloadConfig();
234     }
235 #if !HAVE_SIGACTION
236 #if HAVE_SIGNAL
237     if(errno != EINTR){
238       gettimeofday(&stop_time, NULL);
239       stop_time.tv_sec = stop_time.tv_sec + globalDebugTimeDelta;
240       sgLogError("squidGuard stopped (%d.%03d)",stop_time.tv_sec,stop_time.tv_usec/1000);
241       exit(2);
242     }
243 #endif
244 #else
245     gettimeofday(&stop_time, NULL);
246     stop_time.tv_sec = stop_time.tv_sec + globalDebugTimeDelta;
247     sgLogError("squidGuard stopped (%d.%03d)",stop_time.tv_sec,stop_time.tv_usec/1000);
248     exit(0);
249 #endif
250   }
251   exit(0);
252 }
253 
254 #if __STDC__
usage()255 void usage()
256 #else
257 void usage()
258 #endif
259 {
260   fprintf(stderr,
261 	  "Usage: squidGuard [-u] [-C block] [-t time] [-c file] [-v] [-d] [-P]\n");
262   fprintf(stderr, "Options:\n");
263   fprintf(stderr, "  -v          : show version number\n");
264   fprintf(stderr, "  -d          : all errors to stderr\n");
265   fprintf(stderr, "  -b          : switch on the progress bar when updating the blacklists\n");
266   fprintf(stderr, "  -c file     : load alternate configfile\n");
267   fprintf(stderr, "  -t time     : specify startup time in the format: yyyy-mm-ddTHH:MM:SS\n");
268   fprintf(stderr, "  -u          : update .db files from .diff files\n");
269   fprintf(stderr, "  -C file|all : create new .db files from urls/domain files\n");
270   fprintf(stderr, "                specified in \"file\".\n");
271   fprintf(stderr, "  -P          : do not go into emergency mode when an error with the \n");
272   fprintf(stderr, "                blacklists is encountered.\n");
273 
274   exit(1);
275 }
276