-#!/usr/bin/perl\r
-#\r
-# This file is part of the IPCop Firewall.\r
-#\r
-# IPCop is free software; you can redistribute it and/or modify\r
-# it under the terms of the GNU General Public License as published by\r
-# the Free Software Foundation; either version 2 of the License, or\r
-# (at your option) any later version.\r
-#\r
-# IPCop is distributed in the hope that it will be useful,\r
-# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-# GNU General Public License for more details.\r
-#\r
-# You should have received a copy of the GNU General Public License\r
-# along with IPCop; if not, write to the Free Software\r
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-#\r
-# Copyright (C) 2003-09-22 Darren Critchley <darrenc@telus.net>\r
-#\r
-# $Id: services.cgi,v 1.2.2.3 2005/04/29 23:37:07 franck78 Exp $\r
-#\r
-\r
-use strict;\r
-\r
-require 'CONFIG_ROOT/general-functions.pl';\r
-require "${General::swroot}/lang.pl";\r
-require "${General::swroot}/header.pl";\r
-\r
-my @icmptypes = &get_icmptypes();\r
-\r
-&Header::showhttpheaders();\r
-\r
-my %cgiparams=();\r
-my %selected=();\r
-my %checked=();\r
-my $filename = "${General::swroot}/firewall/customservices";\r
-my $key = 0; # used for finding last sequence number used \r
-\r
-# Darren Critchley - vars for setting up sort order\r
-my $sort_col = '1';\r
-my $sort_type = 'a';\r
-my $sort_dir = 'asc';\r
-\r
-if ($ENV{'QUERY_STRING'} ne '') {\r
- my ($item1, $item2, $item3) = split(/\&/,$ENV{'QUERY_STRING'});\r
- if ($item1 ne '') {\r
- ($junk, $sort_col) = split(/\=/,$item1)\r
- }\r
- if ($item2 ne '') {\r
- ($junk, $sort_type) = split(/\=/,$item2)\r
- }\r
- if ($item3 ne '') {\r
- ($junk, $sort_dir) = split(/\=/,$item3)\r
- }\r
-}\r
-\r
-$cgiparams{'KEY'} = '';\r
-$cgiparams{'PORTS'} = '';\r
-$cgiparams{'PROTOCOL'} = '6';\r
-$cgiparams{'NAME'} = '';\r
-$cgiparams{'PORT_INVERT'} = 'off';\r
-$cgiparams{'PROTOCOL_INVERT'} = 'off';\r
-$cgiparams{'ICMP'} = 'BLANK';\r
-\r
-&Header::getcgihash(\%cgiparams);\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'add'}){\r
-\r
- &validateparams();\r
- unless($errormessage){\r
- $key++; # Add one to last sequence number\r
- open(FILE,">>$filename") or die 'Unable to open config file.';\r
- flock FILE, 2;\r
- print FILE "$key,$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";\r
- close(FILE);\r
- &General::log("$Lang::tr{'service added'}: $cgiparams{'NAME'}");\r
- undef %cgiparams;\r
- }\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'update'})\r
-{\r
- &validateparams();\r
- # Darren Critchley - If there is an error don't waste any more processing time\r
- if ($errormessage) { $cgiparams{'ACTION'} = $Lang::tr{'edit'}; goto UPD_ERROR; }\r
-\r
- unless($errormessage){\r
- open(FILE, $filename) or die 'Unable to open custom services file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
- my $line;\r
- open(FILE, ">$filename") or die 'Unable to open config file.';\r
- flock FILE, 2;\r
- foreach $line (@current) {\r
- chomp($line);\r
- my @temp = split(/\,/,$line);\r
- if ($cgiparams{'KEY'} eq $temp[0]) {\r
- print FILE "$cgiparams{'KEY'},$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";\r
- } else {\r
- print FILE "$line\n";\r
- }\r
- }\r
- close(FILE);\r
- &General::log("$Lang::tr{'service updated'}: $cgiparams{'NAME'}");\r
- undef %cgiparams;\r
- }\r
-UPD_ERROR:\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'})\r
-{\r
- open(FILE, "$filename") or die 'Unable to open custom services file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
-\r
- unless ($errormessage)\r
- {\r
- foreach my $line (@current)\r
- {\r
- chomp($line);\r
- my @temp = split(/\,/,$line);\r
- if ($cgiparams{'KEY'} eq $temp[0]) {\r
- $cgiparams{'NAME'} = $temp[1];\r
- $cgiparams{'PORTS'} = $temp[2];\r
- $cgiparams{'PROTOCOL'} = $temp[3];\r
- $cgiparams{'PORT_INVERT'} = $temp[4];\r
- $cgiparams{'PROTOCOL_INVERT'} = $temp[5];\r
- $cgiparams{'ICMP'} = $temp[6];\r
- }\r
- \r
- }\r
- }\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'remove'})\r
-{\r
- open(FILE, $filename) or die 'Unable to open custom services file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
-\r
- open(FILE, ">$filename") or die 'Unable to open custom services file.';\r
- flock FILE, 2;\r
- foreach my $line (@current)\r
- {\r
- chomp($line);\r
- if ($line ne '') { \r
- my @temp = split(/\,/,$line);\r
- if ($cgiparams{'KEY'} eq $temp[0]) {\r
- &General::log("$Lang::tr{'service removed'}: $temp[1]");\r
- } else {\r
- print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6]\n";\r
- }\r
- }\r
- }\r
- close(FILE);\r
- undef %cgiparams;\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'reset'})\r
-{\r
- undef %cgiparams;\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq '')\r
-{\r
- $cgiparams{'KEY'} = '';\r
- $cgiparams{'PORTS'} = '';\r
- $cgiparams{'PROTOCOL'} = '6';\r
- $cgiparams{'NAME'} = '';\r
- $cgiparams{'PORT_INVERT'} = 'off';\r
- $cgiparams{'PROTOCOL_INVERT'} = 'off';\r
- $cgiparams{'ICMP'} = 'BLANK';\r
-}\r
-\r
-# Darren Critchley - Bring in the protocols file built from /etc/protocols into hash %protocol\r
-require "${General::swroot}/firewall/protocols.pl";\r
-\r
-# Darren Critchley - figure out which protocol is selected\r
-$selected{'PROTOCOL'}{'tcpudp'}= '';\r
-$selected{'PROTOCOL'}{'all'}= '';\r
-foreach $line (keys %protocols) {\r
-# $selected{'PROTOCOL'}{"$protocols{$line}"}= '';\r
- $selected{'PROTOCOL'}{$line}= '';\r
-}\r
-$selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = 'SELECTED';\r
-\r
-# Darren Critchley - figure out which icmptype is selected\r
-$selected{'ICMP'}{$cgiparams{'ICMP'}} = 'SELECTED';\r
-\r
-$checked{'PORT_INVERT'}{'off'} = '';\r
-$checked{'PORT_INVERT'}{'on'} = '';\r
-$checked{'PORT_INVERT'}{$cgiparams{'PORT_INVERT'}} = 'CHECKED';\r
-$checked{'PROTOCOL_INVERT'}{'off'} = '';\r
-$checked{'PROTOCOL_INVERT'}{'on'} = '';\r
-$checked{'PROTOCOL_INVERT'}{$cgiparams{'PROTOCOL_INVERT'}} = 'CHECKED';\r
-\r
-&Header::openpage($Lang::tr{'services settings'}, 1, '');\r
-\r
-&Header::openbigbox('100%', 'LEFT', '', $errormessage);\r
-\r
-# DEBUG DEBUG\r
-#&Header::openbox('100%', 'LEFT', 'DEBUG');\r
-#foreach $line (keys %cgiparams) {\r
-# print "<CLASS NAME='base'>$line = $cgiparams{$line}<BR>";\r
-#}\r
-#print "$sort_col\n";\r
-#print "$ENV{'QUERY_STRING'}\n";\r
-#print " </CLASS>\n";\r
-#&Header::closebox();\r
-\r
-if ($errormessage) {\r
- &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});\r
- print "<CLASS NAME='base'><FONT COLOR='${Header::colourred}'>$errormessage\n</FONT>";\r
- print " </CLASS>\n";\r
- &Header::closebox();\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){\r
- &Header::openbox('100%', 'LEFT', "$Lang::tr{'edit service'}:");\r
-} else {\r
- &Header::openbox('100%', 'LEFT', "$Lang::tr{'add service'}:");\r
-}\r
-# Darren Critchley - Show protocols with TCP, UDP, etc at the top of the list.\r
-print <<END\r
-<FORM METHOD='POST'>\r
-<DIV ALIGN='CENTER'>\r
-<TABLE WIDTH='100%' ALIGN='CENTER'>\r
-<TR align="center">\r
- <TD><strong>$Lang::tr{'servicename'}</strong></TD>\r
- <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>\r
- <TD><strong>$Lang::tr{'ports'}</strong></TD>\r
- <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>\r
- <TD><strong>$Lang::tr{'protocol'}</strong></TD>\r
- <TD> </TD>\r
- <TD> </TD>\r
-</TR>\r
-<TR align="center">\r
- <TD>\r
- <INPUT TYPE='TEXT' NAME='NAME' VALUE='$cgiparams{'NAME'}' SIZE='20' MAXLENGTH='20'>\r
- </TD>\r
- <TD ALIGN='RIGHT'>\r
- <INPUT TYPE='CHECKBOX' NAME='PORT_INVERT' $checked{'PORT_INVERT'}{'on'}>\r
- </TD>\r
- <TD>\r
- <INPUT TYPE='TEXT' NAME='PORTS' VALUE='$cgiparams{'PORTS'}' SIZE='15' MAXLENGTH='11'>\r
- </TD>\r
- <TD ALIGN='RIGHT'>\r
- <INPUT TYPE='CHECKBOX' NAME='PROTOCOL_INVERT' $checked{'PROTOCOL_INVERT'}{'on'}>\r
- </TD>\r
- <TD ALIGN='LEFT'>\r
- <SELECT NAME='PROTOCOL'>\r
- <OPTION VALUE='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</OPTION>\r
- <OPTION VALUE='udp' $selected{'PROTOCOL'}{'udp'}>UDP</OPTION>\r
- <OPTION VALUE='tcpudp' $selected{'PROTOCOL'}{'tcpudp'}>TCP & UDP</OPTION>\r
- <OPTION VALUE='all' $selected{'PROTOCOL'}{'all'}>ALL</OPTION>\r
- <OPTION VALUE='icmp' $selected{'PROTOCOL'}{'icmp'}>ICMP</OPTION>\r
- <OPTION VALUE='gre' $selected{'PROTOCOL'}{'gre'}>GRE</OPTION>\r
-END\r
-;\r
-foreach $line (sort keys %protocols) {\r
- # Darren Critchley - do not have duplicates in the list\r
- if ($protocols{$line} ne '6' && $protocols{$line} ne '17' && $protocols{$line} ne '1' && $protocols{$line} ne '47'){\r
-# print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$protocols{$line}}>".uc($line)."</OPTION>\n";\r
- print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$line}>".uc($line)."</OPTION>\n";\r
- }\r
-}\r
-print <<END\r
- </SELECT>\r
- </TD>\r
-</TR>\r
-<TR>\r
- <TD> </TD>\r
- <TD> </TD>\r
- <TD> </TD>\r
- <TD><strong>$Lang::tr{'icmp type'}:</strong></TD>\r
- <TD ALIGN='LEFT'>\r
- <SELECT NAME='ICMP'>\r
- <OPTION VALUE='BLANK' $selected{'ICMP'}{'BLANK'}>Valid ICMP Types</OPTION>\r
-END\r
-;\r
-foreach $line (@icmptypes) {\r
- if ($cgiparams{'ICMP'} eq $line){\r
- print "<OPTION VALUE='$line' SELECTED>$line</OPTION>\n";\r
- } else {\r
- print "<OPTION VALUE='$line' >$line</OPTION>\n";\r
- }\r
-}\r
-print <<END\r
- </SELECT>\r
- </TD>\r
-</TR>\r
-<TR>\r
-END\r
-;\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){\r
- print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'update'}'></TD>\n";\r
- print "<INPUT TYPE='HIDDEN' NAME='KEY' VALUE='$cgiparams{'KEY'}'>\n";\r
- print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";\r
-} else {\r
- print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'add'}'></TD>\n";\r
- print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";\r
-}\r
-print <<END\r
-</TR>\r
-</TABLE>\r
-</DIV>\r
-</FORM>\r
-END\r
-;\r
-\r
-&Header::closebox();\r
-\r
-&Header::openbox('100%', 'LEFT', "$Lang::tr{'custom services'}:");\r
-print <<END\r
-<DIV ALIGN='CENTER'>\r
-<TABLE WIDTH='100%' ALIGN='CENTER'>\r
-<TR align="center">\r
-END\r
-;\r
-\r
-if ($sort_dir eq 'asc' && $sort_col eq '2') {\r
- 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";\r
-} else {\r
- 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";\r
-}\r
-if ($sort_dir eq 'asc' && $sort_col eq '3') {\r
- 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";\r
-} else {\r
- 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";\r
-}\r
-if ($sort_dir eq 'asc' && $sort_col eq '4') {\r
- 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";\r
-} else {\r
- 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";\r
-}\r
-\r
-print <<END\r
- <TD WIDTH='25%'><strong>$Lang::tr{'icmp type'}</strong></TD>\r
- <TD WIDTH='5%'> </TD>\r
- <TD WIDTH='5%'> </TD>\r
-</TR>\r
-END\r
-;\r
-&display_custom_services();\r
-print <<END\r
-</TABLE>\r
-</DIV>\r
-END\r
-;\r
-&Header::closebox();\r
-\r
-&Header::openbox('100%', 'LEFT', "$Lang::tr{'default services'}:");\r
-print <<END\r
-<DIV ALIGN='CENTER'>\r
-<TABLE WIDTH='100%' ALIGN='CENTER'>\r
-<TR align="center">\r
- <TD><strong>$Lang::tr{'servicename'}</strong></TD>\r
- <TD><strong>$Lang::tr{'ports'}</strong></TD>\r
- <TD><strong>$Lang::tr{'protocol'}</strong></TD>\r
-</TR>\r
-END\r
-;\r
-&display_default_services();\r
-print <<END\r
-</TABLE>\r
-</DIV>\r
-END\r
-;\r
-&Header::closebox();\r
- \r
- print "$Lang::tr{'this feature has been sponsored by'} : ";\r
- print "<A HREF='http://www.kdi.ca/' TARGET='_blank'>Kobelt Development Inc.</A>.\n";\r
-\r
-\r
-&Header::closebigbox();\r
-\r
-&Header::closepage();\r
-\r
-sub display_custom_services\r
-{\r
- \r
- open(FILE, "$filename") or die 'Unable to open services file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
-\r
- my $id = 0;\r
- my $port_inv = '';\r
- my $prot_inv = '';\r
- my $port_inv_tail = '';\r
- my $prot_inv_tail = '';\r
- my @outarray = &General::srtarray($sort_col,$sort_type,$sort_dir,@current);\r
- foreach $line (@outarray)\r
- {\r
- chomp($line);\r
- if ($line ne ''){\r
- my @temp = split(/\,/,$line);\r
- # Darren Critchley highlight the row we are editing\r
- if ( $cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'KEY'} eq $temp[0] ) { \r
- print "<TR BGCOLOR='${Header::colouryellow}'>\n";\r
- } else {\r
- if ($id % 2) {\r
- print "<TR BGCOLOR='${Header::table1colour}'>\n"; \r
- } else {\r
- print "<TR BGCOLOR='${Header::table2colour}'>\n";\r
- }\r
- }\r
- print "<TD>$temp[1]</TD>\n";\r
- 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='';}\r
- print "<TD ALIGN='CENTER'>" . $port_inv . &cleanport("$temp[2]") . $port_inv_tail . "</TD>\n";\r
- 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='';}\r
- print "<TD ALIGN='CENTER'>" . $prot_inv . &cleanprotocol("$temp[3]") . $prot_inv_tail . "</TD>\n";\r
- if ($temp[6] eq 'BLANK') {\r
- print "<TD ALIGN='CENTER'>N/A</TD>\n";\r
- } else {\r
- print "<TD ALIGN='CENTER'>$temp[6]</TD>\n";\r
- }\r
- print <<END\r
-<FORM METHOD='POST' NAME='frm$temp[0]'>\r
-<TD ALIGN='CENTER'>\r
- <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'edit'}'>\r
- <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'>\r
- <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>\r
-</TD>\r
-</FORM>\r
-<FORM METHOD='POST' NAME='frm$temp[0]b'>\r
-<TD ALIGN='CENTER'>\r
- <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'remove'}'>\r
- <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'>\r
- <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>\r
-</TD>\r
-</FORM>\r
-END\r
-;\r
- print "</TR>\n";\r
- $id++;\r
- }\r
- }\r
-}\r
-\r
-sub display_default_services\r
-{\r
- my $fname = "${General::swroot}/firewall/defaultservices";\r
- my $prev = "";\r
- my $newline="";\r
- \r
- open(FILE, "$fname") or die 'Unable to open default services file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
- \r
- my $id = 0;\r
- \r
- foreach my $line (sort @current)\r
- {\r
- my @temp = split(/\,/,$line);\r
- if ($id % 2) {\r
- print "<TR BGCOLOR='${Header::table1colour}'>\n"; \r
- } else {\r
- print "<TR BGCOLOR='${Header::table2colour}'>\n";\r
- }\r
- print "<TD>$temp[0]</TD>\n";\r
- print "<TD ALIGN='CENTER'>$temp[1]</TD>\n";\r
- print "<TD ALIGN='CENTER'>" . &cleanprotocol("$temp[2]") . "</TD>\n";\r
- print "</TR>\n";\r
- $id++;\r
- }\r
-}\r
-\r
-sub cleanprotocol\r
-{\r
- my $prtcl = $_[0];\r
- chomp($prtcl);\r
- if ($prtcl eq 'tcpudp') {\r
- $prtcl = 'TCP & UDP';\r
- } else {\r
- $prtcl = uc($prtcl);\r
- }\r
- return $prtcl;\r
-}\r
-\r
-sub cleanport\r
-{\r
- my $prt = $_[0];\r
- chomp($prt);\r
- # Darren Critchley - Format the ports\r
- $prt =~ s/-/ - /;\r
- $prt =~ s/:/ - /;\r
- return $prt;\r
-}\r
-\r
-# Validate Field Entries\r
-sub validateparams \r
-{\r
- $erromessage='';\r
- if ($cgiparams{'PROTOCOL'} eq 'tcp' || $cgiparams{'PROTOCOL'} eq 'udp' || $cgiparams{'PROTOCOL'} eq 'tcpudp' || $cgiparams{'PROTOCOL'} eq 'all') {\r
- # Darren Critchley - Get rid of dashes in port ranges\r
- $cgiparams{'PORTS'}=~ tr/-/:/;\r
- # Darren Critchley - code to substitue wildcards\r
- if ($cgiparams{'PORTS'} eq "*") {\r
- $cgiparams{'PORTS'} = "1:65535";\r
- }\r
- if ($cgiparams{'PORTS'} =~ /^(\D)\:(\d+)$/) {\r
- $cgiparams{'PORTS'} = "1:$2";\r
- }\r
- if ($cgiparams{'PORTS'} =~ /^(\d+)\:(\D)$/) {\r
- $cgiparams{'PORTS'} = "$1:65535";\r
- }\r
- # Darren Critchley - watch the order here, the validportrange sets errormessage=''\r
- $errormessage = &General::validportrange($cgiparams{'PORTS'}, 'src');\r
- if ($errormessage) {return;}\r
- } else {\r
- $cgiparams{'PORTS'} = "";\r
- }\r
- if ($cgiparams{'PROTOCOL'} eq 'tcp') {\r
- $cgiparams{'ICMP'} = "BLANK";\r
- }\r
- \r
- if($cgiparams{'PORTS'} eq '' && $cgiparams{'PORT_INVERT'} ne 'off'){\r
- $cgiparams{'PORT_INVERT'} = 'off';\r
- }\r
- if ($cgiparams{'NAME'} eq '') {\r
- $errormessage = $Lang::tr{'noservicename'};\r
- return;\r
- }\r
- if ($cgiparams{'PROTOCOL'} eq 'icmp' && $cgiparams{'ICMP'} eq 'BLANK'){\r
- $errormessage = $Lang::tr{'icmp selected but no type'};\r
- return;\r
- }\r
- unless($errormessage){\r
- $cgiparams{'NAME'}=&Header::cleanhtml($cgiparams{'NAME'});\r
- open(FILE, $filename) or die 'Unable to open custom services file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
- foreach my $line (@current)\r
- {\r
- chomp($line);\r
- if ($line ne '') {\r
- my @temp = split(/\,/,$line);\r
- if ($cgiparams{'NAME'} eq $temp[1] && $cgiparams{'KEY'} ne $temp[0]) {\r
- $errormessage=$Lang::tr{'duplicate name'};\r
- return;\r
- }\r
- $key=$temp[0];\r
- }\r
- }\r
- unless($errormessage){\r
- my $fname = "${General::swroot}/firewall/defaultservices";\r
- my $prev = "";\r
- my $newline="";\r
- \r
- open(FILE, "$fname") or die 'Unable to open default services file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
- \r
- foreach my $line (sort @current)\r
- {\r
- my @temp = split(/\,/,$line);\r
- if ($cgiparams{'NAME'} eq $temp[0]) {\r
- $errormessage=$Lang::tr{'duplicate name'};\r
- return;\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
-sub get_icmptypes\r
-{\r
- my $fname = "${General::swroot}/firewall/icmptypes";\r
- my $newline="";\r
- my @newarray=();\r
- \r
- open(FILE, "$fname") or die 'Unable to open icmp file.';\r
- my @current = <FILE>;\r
- close(FILE);\r
-\r
- foreach $newline (sort @current)\r
- {\r
- chomp ($newline);\r
- if (substr($newline, 0, 1) ne "#") {\r
- push (@newarray, $newline);\r
- }\r
- }\r
- return (@newarray);\r
-}\r
-\r
+#!/usr/bin/perl
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2007 Michael Tremer & Christian Schmidt #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+use strict;
+
+# enable only the following on debugging purpose
+#use warnings;
+#use CGI::Carp 'fatalsToBrowser';
+
+require '/var/ipfire/general-functions.pl';
+require "${General::swroot}/lang.pl";
+require "${General::swroot}/header.pl";
+require "${General::swroot}/graphs.pl";
+
+#workaround to suppress a warning when a variable is used only once
+my @dummy = ( ${Header::colourred} );
+undef (@dummy);
+
+my %color = ();
+my %mainsettings = ();
+&General::readhash("${General::swroot}/main/settings", \%mainsettings);
+&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
+
+my %netsettings=();
+&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
+
+&Graphs::updateprocessesgraph ("day");
+
+my %cgiparams=();
+# Maps a nice printable name to the changing part of the pid file, which
+# is also the name of the program
+my %servicenames =
+(
+ $Lang::tr{'dhcp server'} => 'dhcpd',
+ $Lang::tr{'web server'} => 'httpd',
+ $Lang::tr{'cron server'} => 'fcron',
+ $Lang::tr{'dns proxy server'} => 'dnsmasq',
+ $Lang::tr{'logging server'} => 'syslogd',
+ $Lang::tr{'kernel logging server'} => 'klogd',
+ $Lang::tr{'ntp server'} => 'ntpd',
+ $Lang::tr{'secure shell server'} => 'sshd',
+ $Lang::tr{'vpn'} => 'pluto',
+ $Lang::tr{'web proxy'} => 'squid',
+ 'OpenVPN' => 'openvpn'
+);
+
+my $lines=0; # Used to count the outputlines to make different bgcolor
+
+my $iface = '';
+if (open(FILE, "${General::swroot}/red/iface"))
+{
+ $iface = <FILE>;
+ close FILE;
+ chomp $iface;
+}
+$servicenames{"$Lang::tr{'intrusion detection system'} (RED)"} = "snort_${iface}";
+$servicenames{"$Lang::tr{'intrusion detection system'} (GREEN)"} = "snort_$netsettings{'GREEN_DEV'}";
+if ($netsettings{'ORANGE_DEV'} ne '') {
+ $servicenames{"$Lang::tr{'intrusion detection system'} (ORANGE)"} = "snort_$netsettings{'ORANGE_DEV'}";
+}
+if ($netsettings{'BLUE_DEV'} ne '') {
+ $servicenames{"$Lang::tr{'intrusion detection system'} (BLUE)"} = "snort_$netsettings{'BLUE_DEV'}";
+}
+
+&Header::showhttpheaders();
+&Header::getcgihash(\%cgiparams);
+&Header::openpage($Lang::tr{'status information'}, 1, '');
+&Header::openbigbox('100%', 'left');
+
+&Header::openbox('100%', 'left', $Lang::tr{'services'});
+
+print <<END
+<div align='center'>
+<table width='80%' cellspacing='1' border='0'>
+<tr bgcolor='$color{'color20'}'><td align='left'><b>$Lang::tr{'services'}</b></td><td align='center' ><b>$Lang::tr{'status'}</b></td><td align='center'><b>PID</b></td><td align='center'><b>$Lang::tr{'memory'}</b></td></tr>
+END
+;
+
+my $key = '';
+foreach $key (sort keys %servicenames)
+{
+ $lines++;
+ if ($lines % 2)
+ { print "<tr bgcolor='$color{'color22'}'>\n<td align='left'>$key</td>\n";}
+ else
+ { print "<tr bgcolor='$color{'color20'}'>\n<td align='left'>$key</td>\n";}
+
+ my $shortname = $servicenames{$key};
+ my $status = &isrunning($shortname);
+
+ print "$status\n";
+ print "</tr>\n";
+}
+
+
+print "</table></div>\n";
+
+&Header::closebox();
+
+&Header::openbox('100%', 'left', "Addon - $Lang::tr{services}");
+
+my $paramstr=$ENV{QUERY_STRING};
+my @param=split(/!/, $paramstr);
+if ($param[1] ne '') {
+ system("/usr/local/bin/addonctrl @param[0] @param[1] > /dev/null 2>&1");
+}
+
+print <<END
+<div align='center'>
+<table width='80%' cellspacing='1' border='0'>
+<tr bgcolor='$color{'color20'}'>
+<td align='center'><b>Addon</b></td>
+<td align='center'><b>Boot</b></td>
+<td align='center' colspan=2><b>$Lang::tr{'action'}</b></td>
+<td align='center'><b>$Lang::tr{'status'}</b></td>
+<td align='center'><b>PID</b></td>
+<td align='center'><b>$Lang::tr{'memory'}</b></td>
+</tr>
+END
+;
+
+my $lines=0; # Used to count the outputlines to make different bgcolor
+
+# Generate list of installed addon pak's
+my @pak = `find /opt/pakfire/db/installed/meta-* | cut -d"-" -f2`;
+foreach (@pak)
+{
+ chomp($_);
+
+ # Check which of the paks are services
+ my @svc = `find /etc/init.d/$_ | cut -d"/" -f4`;
+ foreach (@svc)
+ {
+ # blacklist some packages
+ #
+ # alsa has trouble with the volume saving and was not really stopped
+ #
+ chomp($_);
+ if ($_ ne "alsa")
+ {
+ $lines++;
+ if ($lines % 2)
+ {
+ print "<tr bgcolor='$color{'color22'}'>";
+ }
+ else
+ {
+ print "<tr bgcolor='$color{'color20'}'>";
+ }
+ print "<td align='left'>$_</td> ";
+ my $status = isautorun($_);
+ print "$status ";
+ print "<td align='center'><A HREF=services.cgi?$_!start><img alt='$Lang::tr{'start'}' title='$Lang::tr{'start'}' src='/images/go-up.png' border='0' /></A></td>";
+ print "<td align='center'><A HREF=services.cgi?$_!stop><img alt='$Lang::tr{'stop'}' title='$Lang::tr{'stop'}' src='/images/go-down.png' border='0' /></A></td> ";
+ my $status = &isrunningaddon($_);
+ $status =~ s/\\e\[[0-1]\;[0-9]+m//g;
+
+ chomp($status);
+ print "$status";
+ print "</tr>";
+ }
+ }
+}
+
+print "</table></div>\n";
+
+&Header::closebox();
+
+&Header::openbox('100%', 'center', "$Lang::tr{'processes'} $Lang::tr{'graph'}");
+if (-e "$Header::graphdir/processes-day.png") {
+ my $ftime = localtime((stat("$Header::graphdir/processes-day.png"))[9]);
+ print "<center><b>$Lang::tr{'the statistics were last updated at'}: $ftime</b></center><br />\n";
+ print "<a href='/cgi-bin/graphs.cgi?graph=processes'>";
+ print "<img alt='' src='/graphs/processes-day.png' border='0' />";
+ print "</a>";
+} else {
+ print $Lang::tr{'no information available'};
+}
+print "<br />\n";
+&Header::closebox();
+
+&Header::openbox('100%', 'center', "$Lang::tr{'processes'} $Lang::tr{'memory'} $Lang::tr{'graph'}");
+if (-e "$Header::graphdir/processesmem-day.png") {
+ my $ftime = localtime((stat("$Header::graphdir/processesmem-day.png"))[9]);
+ print "<center><b>$Lang::tr{'the statistics were last updated at'}: $ftime</b></center><br />\n";
+ print "<a href='/cgi-bin/graphs.cgi?graph=processesmem'>";
+ print "<img alt='' src='/graphs/processesmem-day.png' border='0' />";
+ print "</a>";
+} else {
+ print $Lang::tr{'no information available'};
+}
+print "<br />\n";
+&Header::closebox();
+&Header::closebigbox();
+&Header::closepage();
+
+sub isautorun
+{
+ my $cmd = $_[0];
+ my $status = "<td align='center'></td>";
+ my $init = `find /etc/rc.d/rc3.d/S??${cmd}`;
+ chomp ($init);
+ if ($init ne '') {
+ $status = "<td align='center'><A HREF=services.cgi?$_!disable><img alt='$Lang::tr{'deactivate'}' title='$Lang::tr{'deactivate'}' src='/images/on.gif' border='0' width='16' height='16' /></A></td>";
+ }
+ $init = `find /etc/rc.d/rc3.d/off/S??${cmd}`;
+ chomp ($init);
+ if ($init ne '') {
+ $status = "<td align='center'><A HREF=services.cgi?$_!enable><img alt='$Lang::tr{'activate'}' title='$Lang::tr{'activate'}' src='/images/off.gif' border='0' width='16' height='16' /></A></td>";
+ }
+
+return $status;
+}
+
+sub isrunning
+{
+ my $cmd = $_[0];
+ my $status = "<td align='center' bgcolor='${Header::colourred}'><font color='white'><b>$Lang::tr{'stopped'}</b></font></td><td colspan='2'></td>";
+ my $pid = '';
+ my $testcmd = '';
+ my $exename;
+ my @memory;
+
+ $cmd =~ /(^[a-z]+)/;
+ $exename = $1;
+
+ if (open(FILE, "/var/run/${cmd}.pid")){
+ $pid = <FILE>; chomp $pid;
+ close FILE;
+ if (open(FILE, "/proc/${pid}/status")){
+ while (<FILE>){
+ if (/^Name:\W+(.*)/) {$testcmd = $1; }
+ }
+ close FILE;
+ }
+ if (open(FILE, "/proc/${pid}/statm")){
+ my $temp = <FILE>;
+ @memory = split(/ /,$temp);
+ }
+ close FILE;
+ if ($testcmd =~ /$exename/){$status = "<td align='center' bgcolor='${Header::colourgreen}'><font color='white'><b>$Lang::tr{'running'}</b></font></td><td align='center'>$pid</td><td align='center'>$memory[0] KB</td>";}
+ }
+return $status;
+}
+
+sub isrunningaddon
+{
+ my $cmd = $_[0];
+ my $status = "<td align='center' bgcolor='${Header::colourred}'><font color='white'><b>$Lang::tr{'stopped'}</b></font></td><td colspan='2'></td>";
+ my $pid = '';
+ my $testcmd = '';
+ my $exename;
+ my @memory;
+
+ my $testcmd = `/usr/local/bin/addonctrl $_ status`;
+
+ if ( $testcmd =~ /is\ running/ && $testcmd !~ /is\ not\ running/){
+ $status = "<td align='center' bgcolor='${Header::colourgreen}'><font color='white'><b>$Lang::tr{'running'}</b></font></td>";
+ $testcmd =~ s/[a-z_]//gi; $testcmd =~ s/\[[0-1]\;[0-9]+//gi; $testcmd =~ s/[\(\)\.]//gi; $testcmd =~ s/ //gi; $testcmd =~ s/\e//gi;
+
+ my @pid = split(/\s/,$testcmd);
+ $status .="<td align='center'>$pid[0]</td>";
+
+ my $memory = 0;
+
+ foreach (@pid){
+ chomp($_);
+ if (open(FILE, "/proc/$_/statm")){
+ my $temp = <FILE>;
+ @memory = split(/ /,$temp);
+ }
+ $memory+=$memory[0];
+ }
+ $status .="<td align='center'>$memory KB</td>";
+ }
+ else {$status = "<td align='center' bgcolor='${Header::colourred}'><font color='white'><b>$Lang::tr{'stopped'}</b></font></td><td colspan='2'></td>";}
+return $status;
+}