]>
git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - html/cgi-bin/services.cgi
2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2007 Michael Tremer & Christian Schmidt #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
24 require '/var/ipfire/general-functions.pl';
25 require "${General::swroot}/lang.pl";
26 require "${General::swroot}/header.pl";
28 my @icmptypes = &get_icmptypes
();
30 &Header
::showhttpheaders
();
35 my $filename = "${General::swroot}/firewall/customservices";
36 my $key = 0; # used for finding last sequence number used
38 # Darren Critchley - vars for setting up sort order
43 if ($ENV{'QUERY_STRING'} ne '') {
44 my ($item1, $item2, $item3) = split(/\&/,$ENV{'QUERY_STRING'});
46 ($junk, $sort_col) = split(/\=/,$item1)
49 ($junk, $sort_type) = split(/\=/,$item2)
52 ($junk, $sort_dir) = split(/\=/,$item3)
56 $cgiparams{'KEY'} = '';
57 $cgiparams{'PORTS'} = '';
58 $cgiparams{'PROTOCOL'} = '6';
59 $cgiparams{'NAME'} = '';
60 $cgiparams{'PORT_INVERT'} = 'off';
61 $cgiparams{'PROTOCOL_INVERT'} = 'off';
62 $cgiparams{'ICMP'} = 'BLANK';
64 &Header
::getcgihash
(\
%cgiparams);
66 if ($cgiparams{'ACTION'} eq $Lang::tr
{'add'}){
69 unless($errormessage){
70 $key++; # Add one to last sequence number
71 open(FILE
,">>$filename") or die 'Unable to open config file.';
73 print FILE
"$key,$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";
75 &General
::log("$Lang::tr{'service added'}: $cgiparams{'NAME'}");
80 if ($cgiparams{'ACTION'} eq $Lang::tr
{'update'})
83 # Darren Critchley - If there is an error don't waste any more processing time
84 if ($errormessage) { $cgiparams{'ACTION'} = $Lang::tr
{'edit'}; goto UPD_ERROR
; }
86 unless($errormessage){
87 open(FILE
, $filename) or die 'Unable to open custom services file.';
91 open(FILE
, ">$filename") or die 'Unable to open config file.';
93 foreach $line (@current) {
95 my @temp = split(/\,/,$line);
96 if ($cgiparams{'KEY'} eq $temp[0]) {
97 print FILE
"$cgiparams{'KEY'},$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";
103 &General
::log("$Lang::tr{'service updated'}: $cgiparams{'NAME'}");
109 if ($cgiparams{'ACTION'} eq $Lang::tr
{'edit'})
111 open(FILE
, "$filename") or die 'Unable to open custom services file.';
112 my @current = <FILE
>;
115 unless ($errormessage)
117 foreach my $line (@current)
120 my @temp = split(/\,/,$line);
121 if ($cgiparams{'KEY'} eq $temp[0]) {
122 $cgiparams{'NAME'} = $temp[1];
123 $cgiparams{'PORTS'} = $temp[2];
124 $cgiparams{'PROTOCOL'} = $temp[3];
125 $cgiparams{'PORT_INVERT'} = $temp[4];
126 $cgiparams{'PROTOCOL_INVERT'} = $temp[5];
127 $cgiparams{'ICMP'} = $temp[6];
134 if ($cgiparams{'ACTION'} eq $Lang::tr
{'remove'})
136 open(FILE
, $filename) or die 'Unable to open custom services file.';
137 my @current = <FILE
>;
140 open(FILE
, ">$filename") or die 'Unable to open custom services file.';
142 foreach my $line (@current)
146 my @temp = split(/\,/,$line);
147 if ($cgiparams{'KEY'} eq $temp[0]) {
148 &General
::log("$Lang::tr{'service removed'}: $temp[1]");
150 print FILE
"$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6]\n";
158 if ($cgiparams{'ACTION'} eq $Lang::tr
{'reset'})
163 if ($cgiparams{'ACTION'} eq '')
165 $cgiparams{'KEY'} = '';
166 $cgiparams{'PORTS'} = '';
167 $cgiparams{'PROTOCOL'} = '6';
168 $cgiparams{'NAME'} = '';
169 $cgiparams{'PORT_INVERT'} = 'off';
170 $cgiparams{'PROTOCOL_INVERT'} = 'off';
171 $cgiparams{'ICMP'} = 'BLANK';
174 # Darren Critchley - Bring in the protocols file built from /etc/protocols into hash %protocol
175 require "${General::swroot}/firewall/protocols.pl";
177 # Darren Critchley - figure out which protocol is selected
178 $selected{'PROTOCOL'}{'tcpudp'}= '';
179 $selected{'PROTOCOL'}{'all'}= '';
180 foreach $line (keys %protocols) {
181 # $selected{'PROTOCOL'}{"$protocols{$line}"}= '';
182 $selected{'PROTOCOL'}{$line}= '';
184 $selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = 'SELECTED';
186 # Darren Critchley - figure out which icmptype is selected
187 $selected{'ICMP'}{$cgiparams{'ICMP'}} = 'SELECTED';
189 $checked{'PORT_INVERT'}{'off'} = '';
190 $checked{'PORT_INVERT'}{'on'} = '';
191 $checked{'PORT_INVERT'}{$cgiparams{'PORT_INVERT'}} = 'CHECKED';
192 $checked{'PROTOCOL_INVERT'}{'off'} = '';
193 $checked{'PROTOCOL_INVERT'}{'on'} = '';
194 $checked{'PROTOCOL_INVERT'}{$cgiparams{'PROTOCOL_INVERT'}} = 'CHECKED';
196 &Header
::openpage
($Lang::tr
{'services settings'}, 1, '');
198 &Header
::openbigbox
('100%', 'LEFT', '', $errormessage);
201 #&Header::openbox('100%', 'LEFT', 'DEBUG');
202 #foreach $line (keys %cgiparams) {
203 # print "<CLASS NAME='base'>$line = $cgiparams{$line}<BR>";
205 #print "$sort_col\n";
206 #print "$ENV{'QUERY_STRING'}\n";
207 #print " </CLASS>\n";
208 #&Header::closebox();
211 &Header
::openbox
('100%', 'LEFT', $Lang::tr
{'error messages'});
212 print "<CLASS NAME='base'><FONT COLOR='${Header::colourred}'>$errormessage\n</FONT>";
213 print " </CLASS>\n";
217 if ($cgiparams{'ACTION'} eq $Lang::tr
{'edit'}){
218 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'edit service'}:");
220 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'add service'}:");
222 # Darren Critchley - Show protocols with TCP, UDP, etc at the top of the list.
226 <TABLE WIDTH='100%' ALIGN='CENTER'>
228 <TD><strong>$Lang::tr{'servicename'}</strong></TD>
229 <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>
230 <TD><strong>$Lang::tr{'ports'}</strong></TD>
231 <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>
232 <TD><strong>$Lang::tr{'protocol'}</strong></TD>
238 <INPUT TYPE='TEXT' NAME='NAME' VALUE='$cgiparams{'NAME'}' SIZE='20' MAXLENGTH='20'>
241 <INPUT TYPE='CHECKBOX' NAME='PORT_INVERT' $checked{'PORT_INVERT'}{'on'}>
244 <INPUT TYPE='TEXT' NAME='PORTS' VALUE='$cgiparams{'PORTS'}' SIZE='15' MAXLENGTH='11'>
247 <INPUT TYPE='CHECKBOX' NAME='PROTOCOL_INVERT' $checked{'PROTOCOL_INVERT'}{'on'}>
250 <SELECT NAME='PROTOCOL'>
251 <OPTION VALUE='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</OPTION>
252 <OPTION VALUE='udp' $selected{'PROTOCOL'}{'udp'}>UDP</OPTION>
253 <OPTION VALUE='tcpudp' $selected{'PROTOCOL'}{'tcpudp'}>TCP & UDP</OPTION>
254 <OPTION VALUE='all' $selected{'PROTOCOL'}{'all'}>ALL</OPTION>
255 <OPTION VALUE='icmp' $selected{'PROTOCOL'}{'icmp'}>ICMP</OPTION>
256 <OPTION VALUE='gre' $selected{'PROTOCOL'}{'gre'}>GRE</OPTION>
259 foreach $line (sort keys %protocols) {
260 # Darren Critchley - do not have duplicates in the list
261 if ($protocols{$line} ne '6' && $protocols{$line} ne '17' && $protocols{$line} ne '1' && $protocols{$line} ne '47'){
262 # print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$protocols{$line}}>".uc($line)."</OPTION>\n";
263 print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$line}>".uc($line)."</OPTION>\n";
274 <TD><strong>$Lang::tr{'icmp type'}:</strong></TD>
277 <OPTION VALUE='BLANK' $selected{'ICMP'}{'BLANK'}>Valid ICMP Types</OPTION>
280 foreach $line (@icmptypes) {
281 if ($cgiparams{'ICMP'} eq $line){
282 print "<OPTION VALUE='$line' SELECTED>$line</OPTION>\n";
284 print "<OPTION VALUE='$line' >$line</OPTION>\n";
294 if ($cgiparams{'ACTION'} eq $Lang::tr
{'edit'}){
295 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'update'}'></TD>\n";
296 print "<INPUT TYPE='HIDDEN' NAME='KEY' VALUE='$cgiparams{'KEY'}'>\n";
297 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";
299 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'add'}'></TD>\n";
300 print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";
312 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'custom services'}:");
315 <TABLE WIDTH='100%' ALIGN='CENTER'>
320 if ($sort_dir eq 'asc' && $sort_col eq '2') {
321 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";
323 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";
325 if ($sort_dir eq 'asc' && $sort_col eq '3') {
326 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";
328 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";
330 if ($sort_dir eq 'asc' && $sort_col eq '4') {
331 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";
333 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";
337 <TD WIDTH='25%'><strong>$Lang::tr{'icmp type'}</strong></TD>
338 <TD WIDTH='5%'> </TD>
339 <TD WIDTH='5%'> </TD>
343 &display_custom_services
();
351 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'default services'}:");
354 <TABLE WIDTH='100%' ALIGN='CENTER'>
356 <TD><strong>$Lang::tr{'servicename'}</strong></TD>
357 <TD><strong>$Lang::tr{'ports'}</strong></TD>
358 <TD><strong>$Lang::tr{'protocol'}</strong></TD>
362 &display_default_services
();
370 print "$Lang::tr{'this feature has been sponsored by'} : ";
371 print "<A HREF='http://www.kdi.ca/' TARGET='_blank'>Kobelt Development Inc.</A>.\n";
374 &Header
::closebigbox
();
376 &Header
::closepage
();
378 sub display_custom_services
381 open(FILE
, "$filename") or die 'Unable to open services file.';
382 my @current = <FILE
>;
388 my $port_inv_tail = '';
389 my $prot_inv_tail = '';
390 my @outarray = &General
::srtarray
($sort_col,$sort_type,$sort_dir,@current);
391 foreach $line (@outarray)
395 my @temp = split(/\,/,$line);
396 # Darren Critchley highlight the row we are editing
397 if ( $cgiparams{'ACTION'} eq $Lang::tr
{'edit'} && $cgiparams{'KEY'} eq $temp[0] ) {
398 print "<TR BGCOLOR='${Header::colouryellow}'>\n";
401 print "<TR BGCOLOR='${Header::table1colour}'>\n";
403 print "<TR BGCOLOR='${Header::table2colour}'>\n";
406 print "<TD>$temp[1]</TD>\n";
407 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='';}
408 print "<TD ALIGN='CENTER'>" . $port_inv . &cleanport
("$temp[2]") . $port_inv_tail . "</TD>\n";
409 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='';}
410 print "<TD ALIGN='CENTER'>" . $prot_inv . &cleanprotocol
("$temp[3]") . $prot_inv_tail . "</TD>\n";
411 if ($temp[6] eq 'BLANK') {
412 print "<TD ALIGN='CENTER'>N/A</TD>\n";
414 print "<TD ALIGN='CENTER'>$temp[6]</TD>\n";
417 <FORM METHOD='POST' NAME='frm$temp[0]'>
419 <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'edit'}'>
420 <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'>
421 <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>
424 <FORM METHOD='POST' NAME='frm$temp[0]b'>
426 <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'remove'}'>
427 <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'>
428 <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>
439 sub display_default_services
441 my $fname = "${General::swroot}/firewall/defaultservices";
445 open(FILE
, "$fname") or die 'Unable to open default services file.';
446 my @current = <FILE
>;
451 foreach my $line (sort @current)
453 my @temp = split(/\,/,$line);
455 print "<TR BGCOLOR='${Header::table1colour}'>\n";
457 print "<TR BGCOLOR='${Header::table2colour}'>\n";
459 print "<TD>$temp[0]</TD>\n";
460 print "<TD ALIGN='CENTER'>$temp[1]</TD>\n";
461 print "<TD ALIGN='CENTER'>" . &cleanprotocol
("$temp[2]") . "</TD>\n";
471 if ($prtcl eq 'tcpudp') {
472 $prtcl = 'TCP & UDP';
483 # Darren Critchley - Format the ports
489 # Validate Field Entries
493 if ($cgiparams{'PROTOCOL'} eq 'tcp' || $cgiparams{'PROTOCOL'} eq 'udp' || $cgiparams{'PROTOCOL'} eq 'tcpudp' || $cgiparams{'PROTOCOL'} eq 'all') {
494 # Darren Critchley - Get rid of dashes in port ranges
495 $cgiparams{'PORTS'}=~ tr/-/:/;
496 # Darren Critchley - code to substitue wildcards
497 if ($cgiparams{'PORTS'} eq "*") {
498 $cgiparams{'PORTS'} = "1:65535";
500 if ($cgiparams{'PORTS'} =~ /^(\D)\:(\d+)$/) {
501 $cgiparams{'PORTS'} = "1:$2";
503 if ($cgiparams{'PORTS'} =~ /^(\d+)\:(\D)$/) {
504 $cgiparams{'PORTS'} = "$1:65535";
506 # Darren Critchley - watch the order here, the validportrange sets errormessage=''
507 $errormessage = &General
::validportrange
($cgiparams{'PORTS'}, 'src');
508 if ($errormessage) {return;}
510 $cgiparams{'PORTS'} = "";
512 if ($cgiparams{'PROTOCOL'} eq 'tcp') {
513 $cgiparams{'ICMP'} = "BLANK";
516 if($cgiparams{'PORTS'} eq '' && $cgiparams{'PORT_INVERT'} ne 'off'){
517 $cgiparams{'PORT_INVERT'} = 'off';
519 if ($cgiparams{'NAME'} eq '') {
520 $errormessage = $Lang::tr
{'noservicename'};
523 if ($cgiparams{'PROTOCOL'} eq 'icmp' && $cgiparams{'ICMP'} eq 'BLANK'){
524 $errormessage = $Lang::tr
{'icmp selected but no type'};
527 unless($errormessage){
528 $cgiparams{'NAME'}=&Header
::cleanhtml
($cgiparams{'NAME'});
529 open(FILE
, $filename) or die 'Unable to open custom services file.';
530 my @current = <FILE
>;
532 foreach my $line (@current)
536 my @temp = split(/\,/,$line);
537 if ($cgiparams{'NAME'} eq $temp[1] && $cgiparams{'KEY'} ne $temp[0]) {
538 $errormessage=$Lang::tr
{'duplicate name'};
544 unless($errormessage){
545 my $fname = "${General::swroot}/firewall/defaultservices";
549 open(FILE
, "$fname") or die 'Unable to open default services file.';
550 my @current = <FILE
>;
553 foreach my $line (sort @current)
555 my @temp = split(/\,/,$line);
556 if ($cgiparams{'NAME'} eq $temp[0]) {
557 $errormessage=$Lang::tr
{'duplicate name'};
567 my $fname = "${General::swroot}/firewall/icmptypes";
571 open(FILE
, "$fname") or die 'Unable to open icmp file.';
572 my @current = <FILE
>;
575 foreach $newline (sort @current)
578 if (substr($newline, 0, 1) ne "#") {
579 push (@newarray, $newline);