]> git.ipfire.org Git - ipfire-2.x.git/blame - src/misc-progs/restartsquid.c
HinzugefĆ¼gt:
[ipfire-2.x.git] / src / misc-progs / restartsquid.c
CommitLineData
cd1a2927
MT
1/* SmoothWall helper program - restartsquid\r
2 *\r
3 * This program is distributed under the terms of the GNU General Public\r
4 * Licence. See the file COPYING for details.\r
5 *\r
6 * (c) Lawrence Manning, 2001\r
7 * Restarting squid with transparent proxying.\r
8 *\r
9 * 05/02/2004 - Roy Walker <rwalker@miracomnetwork.com>\r
10 * Exclude red network from transparent proxy to allow browsing to alias IPs\r
11 * Read in VPN settings and exclude each VPN network from transparent proxy\r
12 * \r
13 * $Id: restartsquid.c,v 1.7.2.8 2005/04/22 18:44:37 rkerr Exp $\r
14 * \r
15 */\r
16 \r
17#include <stdio.h>\r
18#include <string.h>\r
19#include <unistd.h>\r
20#include <stdlib.h>\r
21#include <pwd.h>\r
22#include <sys/types.h>\r
23#include <sys/stat.h>\r
24#include <fcntl.h>\r
25#include "libsmooth.h"\r
26#include "setuid.h"\r
27\r
28int main(int argc, char *argv[])\r
29{\r
30 int fd = -1;\r
31 int enable = 0;\r
32 int enablevpn = 0;\r
33 int transparent = 0;\r
34 int enable_blue = 0;\r
35 int transparent_blue = 0;\r
36 int running = 0;\r
37 struct stat st;\r
38 FILE *ipfile;\r
39 char localip[STRING_SIZE] = "";\r
40 struct keyvalue *net = NULL;\r
41 struct keyvalue *squid = NULL;\r
42 char buffer[STRING_SIZE];\r
43 char proxy_port[STRING_SIZE];\r
44 char s[STRING_SIZE];\r
45 char green_dev[STRING_SIZE] = "";\r
46 char blue_dev[STRING_SIZE] = "";\r
47 char red_netaddress[STRING_SIZE] = "";\r
48 char red_netmask[STRING_SIZE] = "";\r
49 char configtype[STRING_SIZE] = "";\r
50 char redtype[STRING_SIZE] = "";\r
51 char enableredvpn[STRING_SIZE] = "";\r
52 char enablebluevpn[STRING_SIZE] = "";\r
53\r
54 if (!(initsetuid()))\r
55 exit(1);\r
56\r
57 /* Kill running squid */\r
58 safe_system("/sbin/iptables -t nat -F SQUID");\r
59 safe_system("/usr/sbin/squid -k shutdown >/dev/null 2>/dev/null");\r
60 sleep(5);\r
61 safe_system("/bin/killall -9 squid >/dev/null 2>/dev/null");\r
62 \r
63 /* See if proxy is enabled and / or transparent */\r
64 if ((fd = open(CONFIG_ROOT "/proxy/enable", O_RDONLY)) != -1)\r
65 {\r
66 close(fd);\r
67 enable = 1;\r
68 }\r
69 if ((fd = open(CONFIG_ROOT "/proxy/transparent", O_RDONLY)) != -1)\r
70 {\r
71 close(fd);\r
72 transparent = 1;\r
73 }\r
74 if ((fd = open(CONFIG_ROOT "/proxy/enable_blue", O_RDONLY)) != -1)\r
75 {\r
76 close(fd);\r
77 enable_blue = 1;\r
78 }\r
79 if ((fd = open(CONFIG_ROOT "/proxy/transparent_blue", O_RDONLY)) != -1)\r
80 {\r
81 close(fd);\r
82 transparent_blue = 1;\r
83 }\r
84\r
85 /* Read the network configuration */\r
86 net=initkeyvalues();\r
87 if (!readkeyvalues(net, CONFIG_ROOT "/ethernet/settings"))\r
88 {\r
89 fprintf(stderr, "Cannot read ethernet settings\n");\r
90 exit(1);\r
91 }\r
92 if (!findkey(net, "GREEN_DEV", green_dev))\r
93 {\r
94 fprintf(stderr, "Cannot read GREEN_DEV\n");\r
95 exit(1);\r
96 }\r
97 if (!VALID_DEVICE(green_dev))\r
98 {\r
99 fprintf(stderr, "Bad GREEN_DEV: %s\n", green_dev);\r
100 exit(1);\r
101 }\r
102 if (!findkey(net, "CONFIG_TYPE", configtype))\r
103 {\r
104 fprintf(stderr, "Cannot read CONFIG_TYPE\n");\r
105 exit(1);\r
106 }\r
107\r
108 findkey(net, "RED_TYPE", redtype);\r
109 findkey(net, "RED_NETADDRESS", red_netaddress);\r
110 findkey(net, "RED_NETMASK", red_netmask);\r
111 findkey(net, "BLUE_DEV", blue_dev);\r
112 freekeyvalues(net);\r
113\r
114 /* See if VPN software is enabled */\r
115 net=initkeyvalues();\r
116 if (!readkeyvalues(net, CONFIG_ROOT "/vpn/settings"))\r
117 {\r
118 fprintf(stderr, "Cannot read vpn settings\n");\r
119 exit(1);\r
120 }\r
121 findkey(net, "ENABLED", enableredvpn);\r
122 findkey(net, "ENABLED_BLUE", enablebluevpn);\r
123 freekeyvalues(net);\r
124 if ( (!strcmp(enableredvpn, "on") && VALID_IP(localip)) || \r
125 (!strcmp(enablebluevpn, "on") && VALID_DEVICE(blue_dev)) ) {\r
126 enablevpn = 1;\r
127 }\r
128\r
129 /* Retrieve the Squid pid file */\r
130 if ((fd = open("/var/run/squid.pid", O_RDONLY)) != -1)\r
131 {\r
132 close(fd);\r
133 running = 1;\r
134 }\r
135\r
136 /* Retrieve the RED ip address */\r
137 stat(CONFIG_ROOT "/red/local-ipaddress", &st);\r
138 if (S_ISREG(st.st_mode)) {\r
139 if (!(ipfile = fopen(CONFIG_ROOT "/red/local-ipaddress", "r")))\r
140 {\r
141 fprintf(stderr, "Couldn't open ip file\n");\r
142 exit(0); \r
143 }\r
144 if (fgets(localip, STRING_SIZE, ipfile))\r
145 {\r
146 if (localip[strlen(localip) - 1] == '\n')\r
147 localip[strlen(localip) - 1] = '\0';\r
148 }\r
149 fclose(ipfile);\r
150 if (!VALID_IP(localip))\r
151 {\r
152 fprintf(stderr, "Bad ip: %s\n", localip);\r
153 exit(0);\r
154 }\r
155 }\r
156\r
157 /* See if we need to flush the cache */\r
158 if (argc >=2) {\r
159 if (strcmp(argv[1], "-f") == 0) {\r
160 if (stat("/var/log/cache/swap.state", &st) == 0) {\r
161 struct passwd *pw;\r
162 if((pw = getpwnam("squid"))) {\r
163 endpwent(); /* probably paranoia, but just in case.. */\r
164 unpriv_system("/bin/echo > /var/log/cache/swap.state", pw->pw_uid, pw->pw_gid);\r
165 } else { endpwent(); }\r
166 }\r
167 }\r
168 }\r
169\r
170 if (enable || enable_blue)\r
171 {\r
172 safe_system("/usr/sbin/squid -D -z"); \r
173 safe_system("/usr/sbin/squid -D");\r
174 }\r
175\r
176 /* Retrieve the proxy port */\r
177 if (transparent || transparent_blue) {\r
178 squid=initkeyvalues();\r
179\r
180 if (!readkeyvalues(squid, CONFIG_ROOT "/proxy/settings"))\r
181 {\r
182 fprintf(stderr, "Cannot read proxy settings\n");\r
183 exit(1);\r
184 }\r
185\r
186 if (!(findkey(squid, "PROXY_PORT", proxy_port)))\r
187 {\r
188 strcpy (proxy_port, "800");\r
189 } else {\r
190 if(strspn(proxy_port, NUMBERS) != strlen(proxy_port))\r
191 {\r
192 fprintf(stderr, "Invalid proxy port: %s, defaulting to 800\n", proxy_port);\r
193 strcpy(proxy_port, "800");\r
194 }\r
195 }\r
196 freekeyvalues(squid);\r
197 }\r
198\r
199 if (transparent && enable) {\r
200 int count;\r
201 char *result;\r
202 char *name;\r
203 char *type;\r
204 char *running;\r
205 char *vpn_network_mask;\r
206 char *vpn_netaddress;\r
207 char *vpn_netmask;\r
208 FILE *file = NULL;\r
209 char *conn_enabled;\r
210 \r
211 /* Darren Critchley - check to see if RED VPN is enabled before mucking with rules */\r
212 if (!strcmp(enableredvpn, "on")) {\r
213 /* Read the /vpn/config file - no check to see if VPN is enabled */\r
214 if (!(file = fopen(CONFIG_ROOT "/vpn/config", "r"))) {\r
215 fprintf(stderr, "Couldn't open vpn config file");\r
216 exit(1);\r
217 }\r
218\r
219 while (fgets(s, STRING_SIZE, file) != NULL) {\r
220 if (s[strlen(s) - 1] == '\n')\r
221 s[strlen(s) - 1] = '\0';\r
222 running = strdup (s);\r
223 result = strsep(&running, ",");\r
224 count = 0;\r
225 name = NULL;\r
226 type = NULL;\r
227 vpn_network_mask = NULL;\r
228 conn_enabled = NULL;\r
229 while (result) {\r
230 if (count == 1)\r
231 conn_enabled = result;\r
232 if (count == 2)\r
233 name = result;\r
234 if (count == 4)\r
235 type = result;\r
236 if (count == 12 )\r
237 vpn_network_mask = result;\r
238 count++;\r
239 result = strsep(&running, ",");\r
240 }\r
241 \r
242 if (strspn(name, LETTERS_NUMBERS) != strlen(name)) {\r
243 fprintf(stderr, "Bad connection name: %s\n", name);\r
244 exit(1);\r
245 }\r
246 \r
247 if (! (strcmp(type, "net") == 0)) {\r
248 continue;\r
249 }\r
250 \r
251 /* Darren Critchley - new check to see if connection is enabled */\r
252 if (! (strcmp(conn_enabled, "on") == 0)) {\r
253 continue;\r
254 }\r
255 \r
256 result = strsep(&vpn_network_mask, "/");\r
257 count = 0;\r
258 vpn_netaddress = NULL;\r
259 vpn_netmask = NULL;\r
260 while (result) {\r
261 if (count == 0)\r
262 vpn_netaddress = result;\r
263 if (count == 1)\r
264 vpn_netmask = result;\r
265 count++;\r
266 result = strsep(&vpn_network_mask, "/");\r
267 }\r
268 \r
269 if (!VALID_IP(vpn_netaddress)) {\r
270 fprintf(stderr, "Bad network for vpn connection %s: %s\n", name, vpn_netaddress);\r
271 continue;\r
272 }\r
273 \r
274 if ((!VALID_IP(vpn_netmask)) && (!VALID_SHORT_MASK(vpn_netmask))) {\r
275 fprintf(stderr, "Bad mask for vpn connection %s: %s\n", name, vpn_netmask);\r
276 continue;\r
277 }\r
278 \r
279 memset(buffer, 0, STRING_SIZE);\r
280 if( snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s/%s --dport 80 -j RETURN", green_dev, vpn_netaddress, vpn_netmask) >= STRING_SIZE )\r
281 {\r
282 fprintf(stderr, "Command too long\n");\r
283 exit(1);\r
284 }\r
285 safe_system(buffer);\r
286 }\r
287 } \r
288 \r
289 memset(buffer, 0, STRING_SIZE);\r
290 if ( ( (strcmp(configtype, "2")==0) || (strcmp(configtype, "3")==0) || \r
291 (strcmp(configtype, "6")==0) || (strcmp(configtype, "7")==0) ) &&\r
292 (VALID_IP(red_netaddress)) && (VALID_IP(red_netmask)) && \r
293 (strcmp(redtype, "STATIC")==0) ) \r
294 {\r
295 memset(buffer, 0, STRING_SIZE);\r
296 if( snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s/%s --dport 80 -j RETURN", green_dev, red_netaddress, red_netmask) >= STRING_SIZE )\r
297 {\r
298 fprintf(stderr, "Command too long\n");\r
299 exit(1);\r
300 }\r
301 safe_system(buffer);\r
302 } else if (VALID_IP(localip)) {\r
303 memset(buffer, 0, STRING_SIZE);\r
304 if( snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s --dport 80 -j RETURN", green_dev, localip) >= STRING_SIZE )\r
305 {\r
306 fprintf(stderr, "Command too long\n");\r
307 exit(1);\r
308 }\r
309 safe_system(buffer);\r
310 }\r
311\r
312 memset(buffer, 0, STRING_SIZE);\r
313 if( snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp --dport 80 -j REDIRECT --to-port %s", green_dev, proxy_port) >= STRING_SIZE )\r
314 {\r
315 fprintf(stderr, "Command too long\n");\r
316 exit(1);\r
317 }\r
318 safe_system(buffer);\r
319 }\r
320\r
321 if (transparent_blue && enable_blue) {\r
322 int count;\r
323 char *result;\r
324 char *name;\r
325 char *type;\r
326 char *running;\r
327 char *vpn_network_mask;\r
328 char *vpn_netaddress;\r
329 char *vpn_netmask;\r
330 char *conn_enabled;\r
331 FILE *file = NULL;\r
332\r
333 if (! VALID_DEVICE(blue_dev))\r
334 {\r
335 fprintf(stderr, "Bad BLUE_DEV: %s\n", blue_dev);\r
336 exit(1);\r
337 }\r
338\r
339 /* Darren Critchley - check to see if BLUE VPN is enabled before mucking with rules */\r
340 if (!strcmp(enablebluevpn, "on")) {\r
341 /* Read the /vpn/config file - no check to see if VPN is enabled */\r
342 if (!(file = fopen(CONFIG_ROOT "/vpn/config", "r"))) {\r
343 fprintf(stderr, "Couldn't open vpn config file");\r
344 exit(1);\r
345 }\r
346 while (fgets(s, STRING_SIZE, file) != NULL) {\r
347 if (s[strlen(s) - 1] == '\n')\r
348 s[strlen(s) - 1] = '\0';\r
349 running = strdup (s);\r
350 result = strsep(&running, ",");\r
351 count = 0;\r
352 name = NULL;\r
353 type = NULL;\r
354 vpn_network_mask = NULL;\r
355 conn_enabled = NULL;\r
356 while (result) {\r
357 if (count == 1)\r
358 conn_enabled = result;\r
359 if (count == 2)\r
360 name = result;\r
361 if (count == 4)\r
362 type = result;\r
363 if (count == 12 )\r
364 vpn_network_mask = result;\r
365 count++;\r
366 result = strsep(&running, ",");\r
367 }\r
368 \r
369 if (strspn(name, LETTERS_NUMBERS) != strlen(name)) {\r
370 fprintf(stderr, "Bad connection name: %s\n", name);\r
371 exit(1);\r
372 }\r
373 \r
374 if (! (strcmp(type, "net") == 0)) {\r
375 continue;\r
376 }\r
377 \r
378 /* Darren Critchley - new check to see if connection is enabled */\r
379 if (! (strcmp(conn_enabled, "on") == 0)) {\r
380 continue;\r
381 }\r
382 \r
383 result = strsep(&vpn_network_mask, "/");\r
384 count = 0;\r
385 vpn_netaddress = NULL;\r
386 vpn_netmask = NULL;\r
387 while (result) {\r
388 if (count == 0)\r
389 vpn_netaddress = result;\r
390 if (count == 1)\r
391 vpn_netmask = result;\r
392 count++;\r
393 result = strsep(&vpn_network_mask, "/");\r
394 }\r
395 \r
396 if (!VALID_IP(vpn_netaddress)) {\r
397 fprintf(stderr, "Bad network for vpn connection %s: %s\n", name, vpn_netaddress);\r
398 continue;\r
399 }\r
400 \r
401 if ((!VALID_IP(vpn_netmask)) && (!VALID_SHORT_MASK(vpn_netmask))) {\r
402 fprintf(stderr, "Bad mask for vpn connection %s: %s\n", name, vpn_netmask);\r
403 continue;\r
404 }\r
405 \r
406 memset(buffer, 0, STRING_SIZE);\r
407 if (snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s/%s --dport 80 -j RETURN", blue_dev, vpn_netaddress, vpn_netmask) >= STRING_SIZE )\r
408 {\r
409 fprintf(stderr, "Command too long\n");\r
410 exit(1);\r
411 }\r
412 safe_system(buffer);\r
413 }\r
414 }\r
415 \r
416 memset(buffer, 0, STRING_SIZE);\r
417 if ( ( (strcmp(configtype, "2")==0) || (strcmp(configtype, "3")==0) ||\r
418 (strcmp(configtype, "6")==0) || (strcmp(configtype, "7")==0) ) &&\r
419 (VALID_IP(red_netaddress)) && (VALID_IP(red_netmask)) &&\r
420 (strcmp(redtype, "STATIC")==0) )\r
421 {\r
422 memset(buffer, 0, STRING_SIZE);\r
423 if( snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s/%s --dport 80 -j RETURN", blue_dev, red_netaddress, red_netmask) >= STRING_SIZE )\r
424 {\r
425 fprintf(stderr, "Command too long\n");\r
426 exit(1);\r
427 }\r
428 safe_system(buffer);\r
429 } else if (VALID_IP(localip)) {\r
430 memset(buffer, 0, STRING_SIZE);\r
431 if( snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s --dport 80 -j RETURN", blue_dev, localip) >= STRING_SIZE )\r
432 {\r
433 fprintf(stderr, "Command too long\n");\r
434 exit(1);\r
435 }\r
436 safe_system(buffer);\r
437 }\r
438\r
439 memset(buffer, 0, STRING_SIZE);\r
440 if( snprintf(buffer, STRING_SIZE - 1, "/sbin/iptables -t nat -A SQUID -i %s -p tcp --dport 80 -j REDIRECT --to-port %s", blue_dev, proxy_port) >= STRING_SIZE )\r
441 {\r
442 fprintf(stderr, "Command too long\n");\r
443 exit(1);\r
444 }\r
445 safe_system(buffer);\r
446 }\r
447 \r
448 return 0;\r
449}\r