]>
git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - html/cgi-bin/services.cgi
3 # This file is part of the IPFire Firewall.
5 # IPFire is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # IPFire is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with IPFire; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # Copyright (C) 2003-09-22 Darren Critchley <darrenc@telus.net>
21 # $Id: services.cgi,v 1.2.2.3 2005/04/29 23:37:07 franck78 Exp $
26 require 'CONFIG_ROOT/general-functions.pl';
27 require "${General::swroot}/lang.pl";
28 require "${General::swroot}/header.pl";
30 my @icmptypes = &get_icmptypes
();
32 &Header
::showhttpheaders
();
37 my $filename = "${General::swroot}/firewall/customservices";
38 my $key = 0; # used for finding last sequence number used
40 # Darren Critchley - vars for setting up sort order
45 if ($ENV{'QUERY_STRING'} ne '') {
46 my ($item1, $item2, $item3) = split(/\&/,$ENV{'QUERY_STRING'});
48 ($junk, $sort_col) = split(/\=/,$item1)
51 ($junk, $sort_type) = split(/\=/,$item2)
54 ($junk, $sort_dir) = split(/\=/,$item3)
58 $cgiparams{'KEY'} = '';
59 $cgiparams{'PORTS'} = '';
60 $cgiparams{'PROTOCOL'} = '6';
61 $cgiparams{'NAME'} = '';
62 $cgiparams{'PORT_INVERT'} = 'off';
63 $cgiparams{'PROTOCOL_INVERT'} = 'off';
64 $cgiparams{'ICMP'} = 'BLANK';
66 &Header
::getcgihash
(\
%cgiparams);
68 if ($cgiparams{'ACTION'} eq $Lang::tr
{'add'}){
71 unless($errormessage){
72 $key++; # Add one to last sequence number
73 open(FILE
,">>$filename") or die 'Unable to open config file.';
75 print FILE
"$key,$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";
77 &General
::log("$Lang::tr{'service added'}: $cgiparams{'NAME'}");
82 if ($cgiparams{'ACTION'} eq $Lang::tr
{'update'})
85 # Darren Critchley - If there is an error don't waste any more processing time
86 if ($errormessage) { $cgiparams{'ACTION'} = $Lang::tr
{'edit'}; goto UPD_ERROR
; }
88 unless($errormessage){
89 open(FILE
, $filename) or die 'Unable to open custom services file.';
93 open(FILE
, ">$filename") or die 'Unable to open config file.';
95 foreach $line (@current) {
97 my @temp = split(/\,/,$line);
98 if ($cgiparams{'KEY'} eq $temp[0]) {
99 print FILE
"$cgiparams{'KEY'},$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";
101 print FILE
"$line\n";
105 &General
::log("$Lang::tr{'service updated'}: $cgiparams{'NAME'}");
111 if ($cgiparams{'ACTION'} eq $Lang::tr
{'edit'})
113 open(FILE
, "$filename") or die 'Unable to open custom services file.';
114 my @current = <FILE
>;
117 unless ($errormessage)
119 foreach my $line (@current)
122 my @temp = split(/\,/,$line);
123 if ($cgiparams{'KEY'} eq $temp[0]) {
124 $cgiparams{'NAME'} = $temp[1];
125 $cgiparams{'PORTS'} = $temp[2];
126 $cgiparams{'PROTOCOL'} = $temp[3];
127 $cgiparams{'PORT_INVERT'} = $temp[4];
128 $cgiparams{'PROTOCOL_INVERT'} = $temp[5];
129 $cgiparams{'ICMP'} = $temp[6];
136 if ($cgiparams{'ACTION'} eq $Lang::tr
{'remove'})
138 open(FILE
, $filename) or die 'Unable to open custom services file.';
139 my @current = <FILE
>;
142 open(FILE
, ">$filename") or die 'Unable to open custom services file.';
144 foreach my $line (@current)
148 my @temp = split(/\,/,$line);
149 if ($cgiparams{'KEY'} eq $temp[0]) {
150 &General
::log("$Lang::tr{'service removed'}: $temp[1]");
152 print FILE
"$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6]\n";
160 if ($cgiparams{'ACTION'} eq $Lang::tr
{'reset'})
165 if ($cgiparams{'ACTION'} eq '')
167 $cgiparams{'KEY'} = '';
168 $cgiparams{'PORTS'} = '';
169 $cgiparams{'PROTOCOL'} = '6';
170 $cgiparams{'NAME'} = '';
171 $cgiparams{'PORT_INVERT'} = 'off';
172 $cgiparams{'PROTOCOL_INVERT'} = 'off';
173 $cgiparams{'ICMP'} = 'BLANK';
176 # Darren Critchley - Bring in the protocols file built from /etc/protocols into hash %protocol
177 require "${General::swroot}/firewall/protocols.pl";
179 # Darren Critchley - figure out which protocol is selected
180 $selected{'PROTOCOL'}{'tcpudp'}= '';
181 $selected{'PROTOCOL'}{'all'}= '';
182 foreach $line (keys %protocols) {
183 # $selected{'PROTOCOL'}{"$protocols{$line}"}= '';
184 $selected{'PROTOCOL'}{$line}= '';
186 $selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = 'SELECTED';
188 # Darren Critchley - figure out which icmptype is selected
189 $selected{'ICMP'}{$cgiparams{'ICMP'}} = 'SELECTED';
191 $checked{'PORT_INVERT'}{'off'} = '';
192 $checked{'PORT_INVERT'}{'on'} = '';
193 $checked{'PORT_INVERT'}{$cgiparams{'PORT_INVERT'}} = 'CHECKED';
194 $checked{'PROTOCOL_INVERT'}{'off'} = '';
195 $checked{'PROTOCOL_INVERT'}{'on'} = '';
196 $checked{'PROTOCOL_INVERT'}{$cgiparams{'PROTOCOL_INVERT'}} = 'CHECKED';
198 &Header
::openpage
($Lang::tr
{'services settings'}, 1, '');
200 &Header
::openbigbox
('100%', 'LEFT', '', $errormessage);
203 #&Header::openbox('100%', 'LEFT', 'DEBUG');
204 #foreach $line (keys %cgiparams) {
205 # print "<CLASS NAME='base'>$line = $cgiparams{$line}<BR>";
207 #print "$sort_col\n";
208 #print "$ENV{'QUERY_STRING'}\n";
209 #print " </CLASS>\n";
210 #&Header::closebox();
213 &Header
::openbox
('100%', 'LEFT', $Lang::tr
{'error messages'});
214 print "<CLASS NAME='base'><FONT COLOR='${Header::colourred}'>$errormessage\n</FONT>";
215 print " </CLASS>\n";
219 if ($cgiparams{'ACTION'} eq $Lang::tr
{'edit'}){
220 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'edit service'}:");
222 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'add service'}:");
224 # Darren Critchley - Show protocols with TCP, UDP, etc at the top of the list.
228 <TABLE WIDTH='100%' ALIGN='CENTER'>
230 <TD><strong>$Lang::tr{'servicename'}</strong></TD>
231 <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>
232 <TD><strong>$Lang::tr{'ports'}</strong></TD>
233 <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>
234 <TD><strong>$Lang::tr{'protocol'}</strong></TD>
240 <INPUT TYPE='TEXT' NAME='NAME' VALUE='$cgiparams{'NAME'}' SIZE='20' MAXLENGTH='20'>
243 <INPUT TYPE='CHECKBOX' NAME='PORT_INVERT' $checked{'PORT_INVERT'}{'on'}>
246 <INPUT TYPE='TEXT' NAME='PORTS' VALUE='$cgiparams{'PORTS'}' SIZE='15' MAXLENGTH='11'>
249 <INPUT TYPE='CHECKBOX' NAME='PROTOCOL_INVERT' $checked{'PROTOCOL_INVERT'}{'on'}>
252 <SELECT NAME='PROTOCOL'>
253 <OPTION VALUE='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</OPTION>
254 <OPTION VALUE='udp' $selected{'PROTOCOL'}{'udp'}>UDP</OPTION>
255 <OPTION VALUE='tcpudp' $selected{'PROTOCOL'}{'tcpudp'}>TCP & UDP</OPTION>
256 <OPTION VALUE='all' $selected{'PROTOCOL'}{'all'}>ALL</OPTION>
257 <OPTION VALUE='icmp' $selected{'PROTOCOL'}{'icmp'}>ICMP</OPTION>
258 <OPTION VALUE='gre' $selected{'PROTOCOL'}{'gre'}>GRE</OPTION>
261 foreach $line (sort keys %protocols) {
262 # Darren Critchley - do not have duplicates in the list
263 if ($protocols{$line} ne '6' && $protocols{$line} ne '17' && $protocols{$line} ne '1' && $protocols{$line} ne '47'){
264 # print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$protocols{$line}}>".uc($line)."</OPTION>\n";
265 print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$line}>".uc($line)."</OPTION>\n";
276 <TD><strong>$Lang::tr{'icmp type'}:</strong></TD>
279 <OPTION VALUE='BLANK' $selected{'ICMP'}{'BLANK'}>Valid ICMP Types</OPTION>
282 foreach $line (@icmptypes) {
283 if ($cgiparams{'ICMP'} eq $line){
284 print "<OPTION VALUE='$line' SELECTED>$line</OPTION>\n";
286 print "<OPTION VALUE='$line' >$line</OPTION>\n";
296 if ($cgiparams{'ACTION'} eq $Lang::tr
{'edit'}){
297 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'update'}'></TD>\n";
298 print "<INPUT TYPE='HIDDEN' NAME='KEY' VALUE='$cgiparams{'KEY'}'>\n";
299 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";
301 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'add'}'></TD>\n";
302 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";
314 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'custom services'}:");
317 <TABLE WIDTH='100%' ALIGN='CENTER'>
322 if ($sort_dir eq 'asc' && $sort_col eq '2') {
323 print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=2&srtype=a&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'servicename'}</a></strong></TD>\n";
325 print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=2&srtype=a&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'servicename'}</a></strong></TD>\n";
327 if ($sort_dir eq 'asc' && $sort_col eq '3') {
328 print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=3&srtype=n&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'ports'}</a></strong></TD>\n";
330 print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=3&srtype=n&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'ports'}</a></strong></TD>\n";
332 if ($sort_dir eq 'asc' && $sort_col eq '4') {
333 print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=4&srtype=a&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'protocol'}</a></strong></TD>\n";
335 print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=4&srtype=a&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'protocol'}</a></strong></TD>\n";
339 <TD WIDTH='25%'><strong>$Lang::tr{'icmp type'}</strong></TD>
340 <TD WIDTH='5%'> </TD>
341 <TD WIDTH='5%'> </TD>
345 &display_custom_services
();
353 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'default services'}:");
356 <TABLE WIDTH='100%' ALIGN='CENTER'>
358 <TD><strong>$Lang::tr{'servicename'}</strong></TD>
359 <TD><strong>$Lang::tr{'ports'}</strong></TD>
360 <TD><strong>$Lang::tr{'protocol'}</strong></TD>
364 &display_default_services
();
372 print "$Lang::tr{'this feature has been sponsored by'} : ";
373 print "<A HREF='http://www.kdi.ca/' TARGET='_blank'>Kobelt Development Inc.</A>.\n";
376 &Header
::closebigbox
();
378 &Header
::closepage
();
380 sub display_custom_services
383 open(FILE
, "$filename") or die 'Unable to open services file.';
384 my @current = <FILE
>;
390 my $port_inv_tail = '';
391 my $prot_inv_tail = '';
392 my @outarray = &General
::srtarray
($sort_col,$sort_type,$sort_dir,@current);
393 foreach $line (@outarray)
397 my @temp = split(/\,/,$line);
398 # Darren Critchley highlight the row we are editing
399 if ( $cgiparams{'ACTION'} eq $Lang::tr
{'edit'} && $cgiparams{'KEY'} eq $temp[0] ) {
400 print "<TR BGCOLOR='${Header::colouryellow}'>\n";
403 print "<TR BGCOLOR='${Header::table1colour}'>\n";
405 print "<TR BGCOLOR='${Header::table2colour}'>\n";
408 print "<TD>$temp[1]</TD>\n";
409 if ($temp[4] eq 'on'){$port_inv = " <strong><font color='RED'>! (</font></strong>";$port_inv_tail = "<strong><font color='RED'>)</font></strong>";}else{$port_inv='';$port_inv_tail='';}
410 print "<TD ALIGN='CENTER'>" . $port_inv . &cleanport
("$temp[2]") . $port_inv_tail . "</TD>\n";
411 if ($temp[5] eq 'on'){$prot_inv = " <strong><font color='RED'>! (</font></strong>";$prot_inv_tail = "<strong><font color='RED'>)</font></strong>";}else{$prot_inv='';$prot_inv_tail='';}
412 print "<TD ALIGN='CENTER'>" . $prot_inv . &cleanprotocol
("$temp[3]") . $prot_inv_tail . "</TD>\n";
413 if ($temp[6] eq 'BLANK') {
414 print "<TD ALIGN='CENTER'>N/A</TD>\n";
416 print "<TD ALIGN='CENTER'>$temp[6]</TD>\n";
419 <FORM METHOD='POST' NAME='frm$temp[0]'>
421 <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'edit'}'>
422 <INPUT TYPE='image' NAME='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'>
423 <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>
426 <FORM METHOD='POST' NAME='frm$temp[0]b'>
428 <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'remove'}'>
429 <INPUT TYPE='image' NAME='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0'>
430 <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>
441 sub display_default_services
443 my $fname = "${General::swroot}/firewall/defaultservices";
447 open(FILE
, "$fname") or die 'Unable to open default services file.';
448 my @current = <FILE
>;
453 foreach my $line (sort @current)
455 my @temp = split(/\,/,$line);
457 print "<TR BGCOLOR='${Header::table1colour}'>\n";
459 print "<TR BGCOLOR='${Header::table2colour}'>\n";
461 print "<TD>$temp[0]</TD>\n";
462 print "<TD ALIGN='CENTER'>$temp[1]</TD>\n";
463 print "<TD ALIGN='CENTER'>" . &cleanprotocol
("$temp[2]") . "</TD>\n";
473 if ($prtcl eq 'tcpudp') {
474 $prtcl = 'TCP & UDP';
485 # Darren Critchley - Format the ports
491 # Validate Field Entries
495 if ($cgiparams{'PROTOCOL'} eq 'tcp' || $cgiparams{'PROTOCOL'} eq 'udp' || $cgiparams{'PROTOCOL'} eq 'tcpudp' || $cgiparams{'PROTOCOL'} eq 'all') {
496 # Darren Critchley - Get rid of dashes in port ranges
497 $cgiparams{'PORTS'}=~ tr/-/:/;
498 # Darren Critchley - code to substitue wildcards
499 if ($cgiparams{'PORTS'} eq "*") {
500 $cgiparams{'PORTS'} = "1:65535";
502 if ($cgiparams{'PORTS'} =~ /^(\D)\:(\d+)$/) {
503 $cgiparams{'PORTS'} = "1:$2";
505 if ($cgiparams{'PORTS'} =~ /^(\d+)\:(\D)$/) {
506 $cgiparams{'PORTS'} = "$1:65535";
508 # Darren Critchley - watch the order here, the validportrange sets errormessage=''
509 $errormessage = &General
::validportrange
($cgiparams{'PORTS'}, 'src');
510 if ($errormessage) {return;}
512 $cgiparams{'PORTS'} = "";
514 if ($cgiparams{'PROTOCOL'} eq 'tcp') {
515 $cgiparams{'ICMP'} = "BLANK";
518 if($cgiparams{'PORTS'} eq '' && $cgiparams{'PORT_INVERT'} ne 'off'){
519 $cgiparams{'PORT_INVERT'} = 'off';
521 if ($cgiparams{'NAME'} eq '') {
522 $errormessage = $Lang::tr
{'noservicename'};
525 if ($cgiparams{'PROTOCOL'} eq 'icmp' && $cgiparams{'ICMP'} eq 'BLANK'){
526 $errormessage = $Lang::tr
{'icmp selected but no type'};
529 unless($errormessage){
530 $cgiparams{'NAME'}=&Header
::cleanhtml
($cgiparams{'NAME'});
531 open(FILE
, $filename) or die 'Unable to open custom services file.';
532 my @current = <FILE
>;
534 foreach my $line (@current)
538 my @temp = split(/\,/,$line);
539 if ($cgiparams{'NAME'} eq $temp[1] && $cgiparams{'KEY'} ne $temp[0]) {
540 $errormessage=$Lang::tr
{'duplicate name'};
546 unless($errormessage){
547 my $fname = "${General::swroot}/firewall/defaultservices";
551 open(FILE
, "$fname") or die 'Unable to open default services file.';
552 my @current = <FILE
>;
555 foreach my $line (sort @current)
557 my @temp = split(/\,/,$line);
558 if ($cgiparams{'NAME'} eq $temp[0]) {
559 $errormessage=$Lang::tr
{'duplicate name'};
569 my $fname = "${General::swroot}/firewall/icmptypes";
573 open(FILE
, "$fname") or die 'Unable to open icmp file.';
574 my @current = <FILE
>;
577 foreach $newline (sort @current)
580 if (substr($newline, 0, 1) ne "#") {
581 push (@newarray, $newline);