]>
Commit | Line | Data |
---|---|---|
ac1cfefa MT |
1 | #!/usr/bin/perl |
2 | # | |
3 | # SmoothWall CGIs | |
4 | # | |
5 | # This code is distributed under the terms of the GPL | |
6 | # | |
7 | # (c) The SmoothWall Team | |
8 | # | |
9 | # $Id: proxy.cgi,v 1.13.2.23 2006/01/29 09:29:47 eoberlander Exp $ | |
10 | # | |
11 | ||
12 | use strict; | |
13 | ||
14 | # enable only the following on debugging purpose | |
15 | #use warnings; | |
16 | #use CGI::Carp 'fatalsToBrowser'; | |
17 | ||
18 | require 'CONFIG_ROOT/general-functions.pl'; | |
19 | require "${General::swroot}/lang.pl"; | |
20 | require "${General::swroot}/header.pl"; | |
21 | ||
22 | my %proxysettings=(); | |
23 | my %netsettings=(); | |
24 | my %mainsettings=(); | |
25 | my $errormessage = ''; | |
26 | my $NeedDoHTML = 1; | |
27 | ||
28 | &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); | |
29 | &General::readhash("${General::swroot}/main/settings", \%mainsettings); | |
30 | ||
31 | &Header::showhttpheaders(); | |
32 | ||
33 | $proxysettings{'ACTION'} = ''; | |
34 | $proxysettings{'VALID'} = ''; | |
35 | ||
36 | $proxysettings{'UPSTREAM_PROXY'} = ''; | |
37 | $proxysettings{'UPSTREAM_USER'} = ''; | |
38 | $proxysettings{'UPSTREAM_PASSWORD'} = ''; | |
39 | $proxysettings{'ENABLE'} = 'off'; | |
40 | $proxysettings{'ENABLE_BLUE'} = 'off'; | |
41 | $proxysettings{'CACHE_SIZE'} = '50'; | |
42 | $proxysettings{'TRANSPARENT'} = 'off'; | |
43 | $proxysettings{'TRANSPARENT_BLUE'} = 'off'; | |
44 | $proxysettings{'MAX_SIZE'} = '4096'; | |
45 | $proxysettings{'MIN_SIZE'} = '0'; | |
46 | $proxysettings{'MAX_OUTGOING_SIZE'} = '0'; | |
47 | $proxysettings{'MAX_INCOMING_SIZE'} = '0'; | |
48 | $proxysettings{'LOGGING'} = 'off'; | |
49 | $proxysettings{'PROXY_PORT'} = '800'; | |
50 | $proxysettings{'EXTENSION_METHODS'} = ''; | |
51 | ||
52 | &Header::getcgihash(\%proxysettings); | |
53 | ||
54 | my $needhup = 0; | |
55 | my $cachemem = ''; | |
56 | ||
57 | if ($proxysettings{'ACTION'} eq $Lang::tr{'save'}) | |
58 | { | |
59 | ||
60 | #assume error | |
61 | my $configerror = 1; | |
62 | ||
63 | if ($proxysettings{'ENABLE'} !~ /^(on|off)$/ || | |
64 | $proxysettings{'TRANSPARENT'} !~ /^(on|off)$/ || | |
65 | $proxysettings{'ENABLE_BLUE'} !~ /^(on|off)$/ || | |
66 | $proxysettings{'TRANSPARENT_BLUE'} !~ /^(on|off)$/ ) { | |
67 | $errormessage = $Lang::tr{'invalid input'}; | |
68 | goto ERROR; | |
69 | } | |
70 | if (!($proxysettings{'CACHE_SIZE'} =~ /^\d+/) || | |
71 | ($proxysettings{'CACHE_SIZE'} < 10)) | |
72 | { | |
73 | $errormessage = $Lang::tr{'invalid cache size'}; | |
74 | goto ERROR; | |
75 | } | |
76 | if (!($proxysettings{'MAX_SIZE'} =~ /^\d+/)) | |
77 | { | |
78 | $errormessage = $Lang::tr{'invalid maximum object size'}; | |
79 | goto ERROR; | |
80 | } | |
81 | if (!($proxysettings{'MIN_SIZE'} =~ /^\d+/)) | |
82 | { | |
83 | $errormessage = $Lang::tr{'invalid minimum object size'}; | |
84 | goto ERROR; | |
85 | } | |
86 | if (!($proxysettings{'MAX_OUTGOING_SIZE'} =~ /^\d+/)) | |
87 | { | |
88 | $errormessage = $Lang::tr{'invalid maximum outgoing size'}; | |
89 | goto ERROR; | |
90 | } | |
91 | if (!($proxysettings{'MAX_INCOMING_SIZE'} =~ /^\d+/)) | |
92 | { | |
93 | $errormessage = $Lang::tr{'invalid maximum incoming size'}; | |
94 | goto ERROR; | |
95 | } | |
96 | ||
97 | if (!($proxysettings{'EXTENSION_METHODS'} =~ /^(|[A-Z0-9 _-]+)$/)) | |
98 | { | |
99 | $errormessage = $Lang::tr{'squid extension methods invalid'}; | |
100 | goto ERROR; | |
101 | } | |
102 | ||
103 | # Quick parent proxy error checking of username and password info. If username password don't both exist give an error. | |
104 | my $proxy1 = 'YES'; | |
105 | my $proxy2 = 'YES'; | |
106 | if (($proxysettings{'UPSTREAM_USER'} eq '')) {$proxy1 = '';} | |
107 | if (($proxysettings{'UPSTREAM_PASSWORD'} eq '')) {$proxy2 = '';} | |
108 | if (($proxy1 ne $proxy2)) | |
109 | { | |
110 | $errormessage = $Lang::tr{'invalid upstream proxy username or password setting'}; | |
111 | goto ERROR; | |
112 | } | |
113 | ||
114 | $_ = $proxysettings{'UPSTREAM_PROXY'}; | |
115 | my ($remotehost, $remoteport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/); | |
116 | $remoteport = 80 if ($remoteport eq ''); | |
117 | ||
118 | $proxysettings{'VALID'} = 'yes'; | |
119 | &General::writehash("${General::swroot}/proxy/settings", \%proxysettings); | |
120 | ||
121 | # | |
122 | # NAH, 03-Jan-2004 | |
123 | # | |
124 | my @free = `/usr/bin/free`; | |
125 | $free[1] =~ m/(\d+)/; | |
126 | $cachemem = int $1 / 10; | |
127 | if ($cachemem < 4096) { | |
128 | $cachemem = 4096; | |
129 | } | |
130 | if ($cachemem > $proxysettings{'CACHE_SIZE'} * 40) { | |
131 | $cachemem = ( $proxysettings{'CACHE_SIZE'} * 40 ); | |
132 | } | |
133 | ||
134 | open(FILE, ">/${General::swroot}/proxy/squid.conf") or die "Unable to write squid.conf file"; | |
135 | flock(FILE, 2); | |
136 | print FILE <<END | |
137 | shutdown_lifetime 5 seconds | |
138 | icp_port 0 | |
139 | ||
140 | http_port $netsettings{'GREEN_ADDRESS'}:$proxysettings{'PROXY_PORT'} | |
141 | END | |
142 | ; | |
143 | print FILE "\nextension_methods $proxysettings{'EXTENSION_METHODS'}\n" if ($proxysettings{'EXTENSION_METHODS'} ne ''); | |
144 | ||
145 | if ($netsettings{'BLUE_DEV'} && $proxysettings{'ENABLE_BLUE'} eq 'on') { | |
146 | print FILE "http_port $netsettings{'BLUE_ADDRESS'}:$proxysettings{'PROXY_PORT'}\n"; | |
147 | } | |
148 | print FILE <<END | |
149 | ||
150 | acl QUERY urlpath_regex cgi-bin \\? | |
151 | no_cache deny QUERY | |
152 | ||
153 | cache_effective_user squid | |
154 | cache_effective_group squid | |
155 | ||
156 | pid_filename /var/run/squid.pid | |
157 | ||
158 | END | |
159 | ; | |
160 | ||
161 | if ($proxysettings{'LOGGING'} eq 'on') | |
162 | { | |
163 | print FILE <<END | |
164 | cache_access_log /var/log/squid/access.log | |
165 | cache_log /var/log/squid/cache.log | |
166 | cache_store_log none | |
167 | ||
168 | END | |
169 | ;} else { | |
170 | print FILE <<END | |
171 | cache_access_log /dev/null | |
172 | cache_log /dev/null | |
173 | cache_store_log none | |
174 | ||
175 | END | |
176 | ;} | |
177 | print FILE <<END | |
178 | log_mime_hdrs off | |
179 | forwarded_for off | |
180 | ||
181 | END | |
182 | ; | |
183 | ||
184 | #Insert acl file and replace __VAR__ with correct values | |
185 | my $blue_net = ''; #BLUE empty by default | |
186 | my $blue_ip = ''; | |
187 | if ($netsettings{'BLUE_DEV'} && $proxysettings{'ENABLE_BLUE'} eq 'on') { | |
188 | $blue_net = "$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}"; | |
189 | $blue_ip = "$netsettings{'BLUE_ADDRESS'}"; | |
190 | } | |
191 | open (ACL, "${General::swroot}/proxy/acl") or die "Unable to open ACL list file"; | |
192 | while (<ACL>) { | |
193 | $_ =~ s/__GREEN_IP__/$netsettings{'GREEN_ADDRESS'}/; | |
194 | $_ =~ s/__GREEN_NET__/$netsettings{'GREEN_NETADDRESS'}\/$netsettings{'GREEN_NETMASK'}/; | |
195 | $_ =~ s/__BLUE_IP__/$blue_ip/; | |
196 | $_ =~ s/__BLUE_NET__/$blue_net/; | |
197 | $_ =~ s/__PROXY_PORT__/$proxysettings{'PROXY_PORT'}/; | |
198 | print FILE $_; | |
199 | } | |
200 | close (ACL); | |
201 | ||
202 | # This value is in bytes, so we must turn it from KB into bytes | |
203 | my $max_incoming_size = $proxysettings{'MAX_INCOMING_SIZE'} * 1024; | |
204 | ||
205 | print FILE <<END | |
206 | ||
207 | maximum_object_size $proxysettings{'MAX_SIZE'} KB | |
208 | minimum_object_size $proxysettings{'MIN_SIZE'} KB | |
209 | ||
210 | cache_mem $cachemem KB | |
211 | cache_dir aufs /var/log/cache $proxysettings{'CACHE_SIZE'} 16 256 | |
212 | ||
213 | request_body_max_size $proxysettings{'MAX_OUTGOING_SIZE'} KB | |
214 | reply_body_max_size $max_incoming_size allow all | |
215 | ||
216 | visible_hostname $mainsettings{'HOSTNAME'}.$mainsettings{'DOMAINNAME'} | |
217 | ||
218 | END | |
219 | ; | |
220 | ||
221 | # Write the parent proxy info, if needed. | |
222 | if ($remotehost ne '') | |
223 | { | |
224 | # Enter authentication for the parent cache (format is login=user:password) | |
225 | if ($proxy1 eq 'YES') { | |
226 | print FILE <<END | |
227 | cache_peer $remotehost parent $remoteport 3130 login=$proxysettings{'UPSTREAM_USER'}:$proxysettings{'UPSTREAM_PASSWORD'} default no-query | |
228 | ||
229 | END | |
230 | ; | |
231 | } else { | |
232 | # Not using authentication with the parent cache | |
233 | print FILE <<END | |
234 | cache_peer $remotehost parent $remoteport 3130 default no-query | |
235 | ||
236 | END | |
237 | ; | |
238 | } | |
239 | print FILE "never_direct allow all\n"; | |
240 | } | |
241 | if (($proxysettings{'TRANSPARENT'} eq 'on') || | |
242 | ($proxysettings{'TRANSPARENT_BLUE'} eq 'on')) | |
243 | { | |
244 | print FILE <<END | |
245 | httpd_accel_host virtual | |
246 | httpd_accel_port 80 | |
247 | httpd_accel_with_proxy on | |
248 | httpd_accel_uses_host_header on | |
249 | END | |
250 | ; | |
251 | } | |
252 | close FILE; | |
253 | $configerror = 0; ## a good config! | |
254 | ||
255 | ERROR: | |
256 | unlink "${General::swroot}/proxy/enable"; | |
257 | unlink "${General::swroot}/proxy/transparent"; | |
258 | unlink "${General::swroot}/proxy/enable_blue"; | |
259 | unlink "${General::swroot}/proxy/transparent_blue"; | |
260 | &DoHTML; | |
261 | ||
262 | if (!$configerror) | |
263 | { | |
264 | if ($proxysettings{'ENABLE'} eq 'on') { | |
265 | system ('/bin/touch', "${General::swroot}/proxy/enable"); } | |
266 | if ($proxysettings{'TRANSPARENT'} eq 'on') { | |
267 | system ('/bin/touch', "${General::swroot}/proxy/transparent"); } | |
268 | if ($proxysettings{'ENABLE_BLUE'} eq 'on') { | |
269 | system ('/bin/touch', "${General::swroot}/proxy/enable_blue"); } | |
270 | if ($proxysettings{'TRANSPARENT_BLUE'} eq 'on') { | |
271 | system ('/bin/touch', "${General::swroot}/proxy/transparent_blue"); } | |
272 | system('/usr/local/bin/restartsquid'); | |
273 | } | |
274 | } | |
275 | ||
276 | if ($proxysettings{'ACTION'} eq $Lang::tr{'clear cache'}) | |
277 | { | |
278 | &DoHTML; | |
279 | system('/usr/local/bin/restartsquid','-f'); | |
280 | } | |
281 | ||
282 | &DoHTML if $NeedDoHTML; | |
283 | ||
284 | ||
285 | sub DoHTML { | |
286 | ||
287 | $NeedDoHTML = 0; | |
288 | &General::readhash("${General::swroot}/proxy/settings", \%proxysettings); | |
289 | ||
290 | my %checked=(); | |
291 | ||
292 | $checked{'ENABLE'}{'off'} = ''; | |
293 | $checked{'ENABLE'}{'on'} = ''; | |
294 | $checked{'ENABLE'}{$proxysettings{'ENABLE'}} = "checked='checked'"; | |
295 | ||
296 | $checked{'TRANSPARENT'}{'off'} = ''; | |
297 | $checked{'TRANSPARENT'}{'on'} = ''; | |
298 | $checked{'TRANSPARENT'}{$proxysettings{'TRANSPARENT'}} = "checked='checked'"; | |
299 | ||
300 | $checked{'ENABLE_BLUE'}{'off'} = ''; | |
301 | $checked{'ENABLE_BLUE'}{'on'} = ''; | |
302 | $checked{'ENABLE_BLUE'}{$proxysettings{'ENABLE_BLUE'}} = "checked='checked'"; | |
303 | ||
304 | $checked{'TRANSPARENT_BLUE'}{'off'} = ''; | |
305 | $checked{'TRANSPARENT_BLUE'}{'on'} = ''; | |
306 | $checked{'TRANSPARENT_BLUE'}{$proxysettings{'TRANSPARENT_BLUE'}} = "checked='checked'"; | |
307 | ||
308 | $checked{'LOGGING'}{'off'} = ''; | |
309 | $checked{'LOGGING'}{'on'} = ''; | |
310 | $checked{'LOGGING'}{$proxysettings{'LOGGING'}} = "checked='checked'"; | |
311 | ||
312 | &Header::openpage($Lang::tr{'web proxy configuration'}, 1, ''); | |
313 | ||
314 | &Header::openbigbox('100%', 'left', '', $errormessage); | |
315 | ||
316 | if ($errormessage) { | |
317 | &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); | |
318 | print "<font class='base'>$errormessage </font>\n"; | |
319 | &Header::closebox(); | |
320 | } | |
321 | ||
322 | print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>\n"; | |
323 | ||
324 | &Header::openbox('100%', 'left', "$Lang::tr{'web proxy'}:"); | |
325 | print <<END | |
326 | <table width='100%'> | |
327 | <tr> | |
328 | <td width='25%' class='base'>$Lang::tr{'enabled on'} <font color="${Header::colourgreen}">Green</font>:</td> | |
329 | <td width='15%'><input type='checkbox' name='ENABLE' $checked{'ENABLE'}{'on'} /></td> | |
330 | <td width='30%' class='base'>$Lang::tr{'upstream proxy host:port'}: <img src='/blob.gif' alt='*' /></td> | |
331 | <td width='30%'><input type='text' name='UPSTREAM_PROXY' value='$proxysettings{'UPSTREAM_PROXY'}' /></td> | |
332 | </tr> | |
333 | <tr> | |
334 | <td class='base'>$Lang::tr{'transparent on'} <font color="${Header::colourgreen}">Green</font>:</td> | |
335 | <td><input type='checkbox' name='TRANSPARENT' $checked{'TRANSPARENT'}{'on'} /></td> | |
336 | <td class='base'>$Lang::tr{'upstream username'} <img src='/blob.gif' alt='*' /></td> | |
337 | <td><input type='text' name='UPSTREAM_USER' value='$proxysettings{'UPSTREAM_USER'}' /></td> | |
338 | </tr> | |
339 | <tr> | |
340 | END | |
341 | ; | |
342 | if ($netsettings{'BLUE_DEV'}) { | |
343 | print "<td class='base'>$Lang::tr{'enabled on'} <font color='${Header::colourblue}'>Blue</font>:</td>"; | |
344 | print "<td><input type='checkbox' name='ENABLE_BLUE' $checked{'ENABLE_BLUE'}{'on'} /></td>"; | |
345 | } else { | |
346 | print "<td colspan='2'> </td>"; | |
347 | } | |
348 | print <<END | |
349 | <td class='base'>$Lang::tr{'upstream password'} <img src='/blob.gif' alt='*' /></td> | |
350 | <td><input type='password' name='UPSTREAM_PASSWORD' value='$proxysettings{'UPSTREAM_PASSWORD'}' /></td> | |
351 | </tr> | |
352 | <tr> | |
353 | END | |
354 | ; | |
355 | if ($netsettings{'BLUE_DEV'}) { | |
356 | print "<td class='base'>$Lang::tr{'transparent on'} <font color='${Header::colourblue}'>Blue</font>:</td>"; | |
357 | print "<td><input type='checkbox' name='TRANSPARENT_BLUE' $checked{'TRANSPARENT_BLUE'}{'on'} /></td>"; | |
358 | } else { | |
359 | print "<td colspan='2'> </td>"; | |
360 | } | |
361 | print <<END | |
362 | <td class='base'>$Lang::tr{'proxy port'}:</td> | |
363 | <td><input type='text' name='PROXY_PORT' value='$proxysettings{'PROXY_PORT'}' size='5' /></td> | |
364 | </tr> | |
365 | <tr> | |
366 | <td class='base'>$Lang::tr{'log enabled'}:</td> | |
367 | <td><input type='checkbox' name='LOGGING' $checked{'LOGGING'}{'on'} /></td> | |
368 | <td>$Lang::tr{'squid extension methods'}: <img src='/blob.gif' alt='*' /></td> | |
369 | <td><input type='text' name='EXTENSION_METHODS' value='$proxysettings{'EXTENSION_METHODS'}' /></td> | |
370 | </tr> | |
371 | <!--TAG FOR ADDONS--> | |
372 | <tr> | |
373 | <td colspan='4'><hr /><b>$Lang::tr{'cache management'}</b></td> | |
374 | </tr> | |
375 | <tr> | |
376 | <td width='25%' class='base'>$Lang::tr{'cache size'}</td> | |
377 | <td><input type='text' name='CACHE_SIZE' value='$proxysettings{'CACHE_SIZE'}' size='5' /></td> | |
378 | </tr> | |
379 | <tr> | |
380 | <td class='base'>$Lang::tr{'min size'}</td> | |
381 | <td><input type='text' name='MIN_SIZE' value='$proxysettings{'MIN_SIZE'}' size='5' /></td> | |
382 | <td class='base'>$Lang::tr{'max size'}</td> | |
383 | <td><input type='text' name='MAX_SIZE' value='$proxysettings{'MAX_SIZE'}' size='5' /></td> | |
384 | </tr> | |
385 | <tr> | |
386 | <td colspan='4'><hr /><b>$Lang::tr{'transfer limits'}</b></td> | |
387 | </tr> | |
388 | <tr> | |
389 | <td class='base'>$Lang::tr{'max incoming size'}</td> | |
390 | <td><input type='text' name='MAX_INCOMING_SIZE' value='$proxysettings{'MAX_INCOMING_SIZE'}' size='5' /></td> | |
391 | <td class='base'>$Lang::tr{'max outgoing size'}</td> | |
392 | <td><input type='text' name='MAX_OUTGOING_SIZE' value='$proxysettings{'MAX_OUTGOING_SIZE'}' size='5' /></td> | |
393 | </tr> | |
394 | </table> | |
395 | <table width='100%'> | |
396 | <hr /> | |
397 | <tr> | |
398 | <td width='28%'> | |
399 | <img src='/blob.gif' align='top' alt='*' /> | |
400 | <font class='base'>$Lang::tr{'this field may be blank'}</font> | |
401 | </td> | |
402 | <td width='33%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'clear cache'}' /></td> | |
403 | <td width=33%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td> | |
404 | <td width='5%' align='right'> | |
405 | <a href='${General::adminmanualurl}/services.html#services_webproxy' target='_blank'> | |
406 | <img src='/images/web-support.png' title='$Lang::tr{'online help en'}' /></a></td> | |
407 | </tr> | |
408 | ||
409 | </table> | |
410 | END | |
411 | ; | |
412 | &Header::closebox(); | |
413 | ||
414 | print "</form>\n"; | |
415 | ||
416 | &Header::closebigbox(); | |
417 | ||
418 | &Header::closepage(); | |
419 | ||
420 | } # end sub DoHTML | |
421 | 1 |