]> git.ipfire.org Git - ipfire-2.x.git/blob - html/cgi-bin/proxy.cgi
git-svn-id: http://svn.ipfire.org/svn/ipfire/IPFire/source@16 ea5c0bd1-69bd-2848...
[ipfire-2.x.git] / html / cgi-bin / proxy.cgi
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&nbsp;</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'}:&nbsp;<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'}&nbsp;<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'>&nbsp;</td>";
347 }
348 print <<END
349 <td class='base'>$Lang::tr{'upstream password'}&nbsp;<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'>&nbsp;</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'}:&nbsp;<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='*' />&nbsp;
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