From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michael Tremer To: development@lists.ipfire.org Subject: Re: [PATCH] New addon: Portredirect 1.0 Date: Mon, 28 Jun 2021 18:56:43 +0100 Message-ID: <96F9CD11-CCC8-4683-B75F-80440C62E242@ipfire.org> In-Reply-To: <305D680D-4D10-4D99-9F1D-3589BDF08FA9@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8207404099069258012==" List-Id: --===============8207404099069258012== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Hello, > On 28 Jun 2021, at 18:53, Jon Murphy wrote: >=20 > Hi Michael! Happy Monday! >=20 >=20 >> Why do we not extend the firewall UI probably by about 20 lines of code in= stead of adding many hundreds of lines? >>=20 >> Please can someone elaborate on this more? >=20 > Doing a DNS redirect, via the WegBUI, has been an issue since 2015. I foun= d this quote in the old forum: >=20 > "Having investigated a bit more I have concluded that it's not currently po= ssible to create such rules through the WUI. >=20 > There are a number of obstacles: > 1. It is not allowed to create a rule where source IP and destination nat I= P is on the same subnetwork (e.g. GREEN), WUI error message: "Source and dest= ination IP addresses are from the same subnet." >=20 > 2. WUI will not allow you to create a rule without a destination (the filte= red packet must adhere to a destination, not only a port) and the destination= MUST be an IP address of one of the IPFire interfaces, which limits whats po= ssible a great deal."=20 And these cannot be changed? > And I found this from 2016: > https://bugzilla.ipfire.org/show_bug.cgi?id=3D11168 >=20 > So I am guessing that no one has been able to determine a way to extend the= WebGUI. =20 Has anyone tried? I do not see any obvious reasons why this should not be pos= sible. > I am curious - Who created the https://ipfire:444/cgi-bin/firewall.cgi page= ? And could they help? -Michael > Jon >=20 >=20 >> On Jun 28, 2021, at 11:04 AM, Michael Tremer = wrote: >>=20 >> Hello Matthias, >>=20 >>> On 27 Jun 2021, at 14:48, Matthias Fischer wrote: >>>=20 >>> From: Marcel Lorenz >>=20 >> Thank you for sending this patch on Marcel=E2=80=99s behalf, but I would m= uch more prefer if he would submit his patches on his own. I do not see why t= hat isn=E2=80=99t possible. >>=20 >>> Please note: >>> This is a new addon written by Marcel Lorenz . >>>=20 >>> It adds a new GUI to IPFire for DNS/NTP *and* user specific port redirect= ions. >>>=20 >>> How its working: >>> It has exactly the same functionalities as "Forcing DNS/NTP..." - and so= me more. >>>=20 >>> By setting switches, DNS/NTP requests are automatically >>> redirected to the local IPFire DNS/NTP servers. >>>=20 >>> Additionally, the user can specify custom redirections. >>>=20 >>> These rules are added to a new chain in PREROUTING =3D> PORT_REDIRECT. >>>=20 >>> To avoid problems with (e.g.) transparent 'squid' configurations, >>> redirection rules are added automatically before existing 'squid' rules. >>=20 >> This message does unfortunately not say why this add-on would be useful. I= am emphasising this again and again that it is not very important how someth= ing is done specially. That should be commented in the code and other impleme= ntation details should also be documented there. >>=20 >> As I have stated on this functionality many times before, I do not see why= this is necessary at all. >>=20 >> Why is this an add-on? >>=20 >> Why do we not extend the firewall UI probably by about 20 lines of code in= stead of adding many hundreds of lines? >>=20 >> Please can someone elaborate on this more? >>=20 >> -Michael >>=20 >>> Signed-off-by: Matthias Fischer >>> --- >>> config/portredir/EX-portredir.menu | 6 + >>> config/portredir/lang/portredir.de.pl | 19 + >>> config/portredir/lang/portredir.en.pl | 19 + >>> config/portredir/portredir-backup | 1 + >>> config/portredir/portredir.cgi | 525 ++++++++++++++++++++++++++ >>> config/rootfiles/common/misc-progs | 1 + >>> config/rootfiles/packages/portredir | 11 + >>> lfs/portredir | 85 +++++ >>> make.sh | 1 + >>> src/initscripts/packages/portredir | 191 ++++++++++ >>> src/misc-progs/Makefile | 2 +- >>> src/misc-progs/portredirctrl.c | 47 +++ >>> src/paks/portredir/install.sh | 32 ++ >>> src/paks/portredir/uninstall.sh | 28 ++ >>> src/paks/portredir/update.sh | 26 ++ >>> 15 files changed, 993 insertions(+), 1 deletion(-) >>> create mode 100644 config/portredir/EX-portredir.menu >>> create mode 100644 config/portredir/lang/portredir.de.pl >>> create mode 100644 config/portredir/lang/portredir.en.pl >>> create mode 100644 config/portredir/portredir-backup >>> create mode 100644 config/portredir/portredir.cgi >>> create mode 100644 config/rootfiles/packages/portredir >>> create mode 100644 lfs/portredir >>> create mode 100644 src/initscripts/packages/portredir >>> create mode 100644 src/misc-progs/portredirctrl.c >>> create mode 100644 src/paks/portredir/install.sh >>> create mode 100644 src/paks/portredir/uninstall.sh >>> create mode 100644 src/paks/portredir/update.sh >>>=20 >>> diff --git a/config/portredir/EX-portredir.menu b/config/portredir/EX-por= tredir.menu >>> new file mode 100644 >>> index 000000000..8376e8053 >>> --- /dev/null >>> +++ b/config/portredir/EX-portredir.menu >>> @@ -0,0 +1,6 @@ >>> + $subfirewall->{'95.portredir'} =3D { >>> + 'caption' =3D> $Lang::tr{'portredir port redirections'}, >>> + 'uri' =3D> '/cgi-bin/portredir.cgi', >>> + 'title' =3D> "$Lang::tr{'portredir port redirections'}", >>> + 'enabled' =3D> 1 >>> + }; >>> diff --git a/config/portredir/lang/portredir.de.pl b/config/portredir/lan= g/portredir.de.pl >>> new file mode 100644 >>> index 000000000..b932d4a85 >>> --- /dev/null >>> +++ b/config/portredir/lang/portredir.de.pl >>> @@ -0,0 +1,19 @@ >>> +%tr =3D ( >>> +%tr, >>> +'portredir enable addon' =3D> 'Addon aktivieren', >>> +'portredir common settings' =3D> 'Allgemeine Einstellungen', >>> +'portredir port redirections' =3D> 'Portumleitungen', >>> +'portredir fw for interface' =3D> 'Firewalloptionen f=C3=BCr das Interfa= ce', >>> +'portredir enable user redirections' =3D> 'Aktiviere benutzerdefinierte = Portumleitungen', >>> +'portredir force local dns' =3D> 'Erzwinge lokale DNS-Server', >>> +'portredir force local ntp' =3D> 'Erzwinge lokale NTP-Server', >>> +'portredir custom redirections' =3D> 'Benutzerdefinierte Portumleitungen= ', >>> +'portredir remove rule' =3D> 'Entferne Regel', >>> +'portredir add rule' =3D> 'Hinzuf=C3=BCgen', >>> +'portredir no entries' =3D> 'Keine Eintr=C3=A4ge vorhanden.', >>> +'portredir invalid address' =3D> 'Ung=C3=BCltige Host-Addresse.', >>> +'portredir empty input' =3D> 'Fehlende Angabe: Bitte geben Sie einen g= =C3=BCltigen Host an.', >>> +'portredir save to activate' =3D> 'Speichern, um =C3=84nderungen zu akti= vieren', >>> +); >>> + >>> +#EOF >>> diff --git a/config/portredir/lang/portredir.en.pl b/config/portredir/lan= g/portredir.en.pl >>> new file mode 100644 >>> index 000000000..f442f3eaa >>> --- /dev/null >>> +++ b/config/portredir/lang/portredir.en.pl >>> @@ -0,0 +1,19 @@ >>> +%tr =3D ( >>> +%tr, >>> +'portredir enable addon' =3D> 'Enable addon', >>> +'portredir common settings' =3D> 'Common settings', >>> +'portredir port redirections' =3D> 'Port redirections', >>> +'portredir fw for interface' =3D> 'Firewall options for interface', >>> +'portredir enable user redirections' =3D> 'Enable user port redirections= ', >>> +'portredir force local dns' =3D> 'Enforce local DNS servers', >>> +'portredir force local ntp' =3D> 'Enforce local NTP servers', >>> +'portredir custom redirections' =3D> 'Custom port redirections', >>> +'portredir remove rule' =3D> 'Remove rule', >>> +'portredir add rule' =3D> 'Add new', >>> +'portredir no entries' =3D> 'No entries at the moment.', >>> +'portredir invalid address' =3D> 'Invalid host address.', >>> +'portredir empty input' =3D> 'Empty input: Please enter a valid host.', >>> +'portredir save to activate' =3D> 'Save to activate changes', >>> +); >>> + >>> +#EOF >>> diff --git a/config/portredir/portredir-backup b/config/portredir/portred= ir-backup >>> new file mode 100644 >>> index 000000000..bd2ada742 >>> --- /dev/null >>> +++ b/config/portredir/portredir-backup >>> @@ -0,0 +1 @@ >>> +/var/ipfire/portredir >>> diff --git a/config/portredir/portredir.cgi b/config/portredir/portredir.= cgi >>> new file mode 100644 >>> index 000000000..4913dda3f >>> --- /dev/null >>> +++ b/config/portredir/portredir.cgi >>> @@ -0,0 +1,525 @@ >>> +#!/usr/bin/perl >>> +########################################################################= ####### >>> +# = # >>> +# IPFire.org - A linux based firewall = # >>> +# Copyright (C) 2021 IPFire Team = # >>> +# = # >>> +# 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 . = # >>> +# = # >>> +########################################################################= ####### >>> + >>> +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"; >>> + >>> +# File declarations >>> +my $settingsfile =3D "${General::swroot}/portredir/settings"; >>> +my $redirectsfile =3D "${General::swroot}/portredir/redirects"; >>> + >>> +# Create empty settingsfiles if they does not exist yet >>> +unless (-e "$settingsfile") { system ("touch $settingsfile"); } >>> +unless (-e "$redirectsfile") { system ("touch $redirectsfile"); } >>> + >>> +# load ipfire settings >>> +our %netsettings =3D (); >>> +our %color =3D (); >>> +&General::readhash("${General::swroot}/ethernet/settings", \%netsettings= ); >>> +&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.tx= t", \%color); >>> + >>> +my %settings=3D(); >>> +my %portredirs=3D(); >>> +my %checked=3D(); # Checkbox manipulations >>> +my $errormessage=3D''; >>> +my %selected=3D(); >>> +our %redirects=3D(); >>> + >>> +$settings{'ACTION'} =3D ''; >>> +$settings{'REDIR_ENABLE_ADDON'}=3D"off"; >>> +$settings{'REDIR_CUSTOM_GREEN'}=3D"off"; >>> +$settings{'REDIR_CUSTOM_BLUE'}=3D"off"; >>> +$settings{'REDIR_CUSTOM_ORANGE'}=3D"off"; >>> +$settings{'REDIR_DNS_GREEN'}=3D"off"; >>> +$settings{'REDIR_NTP_GREEN'}=3D"off"; >>> +$settings{'REDIR_DNS_BLUE'}=3D"off"; >>> +$settings{'REDIR_NTP_BLUE'}=3D"off"; >>> +$settings{'REDIR_DNS_ORANGE'}=3D"off"; >>> +$settings{'REDIR_NTP_ORANGE'}=3D"off"; >>> + >>> +&Header::showhttpheaders(); >>> + >>> +# Get GUI values >>> +&Header::getcgihash(\%settings); >>> + >>> +# Save action >>> +if ($settings{'ACTION'} eq $Lang::tr{'save'}) { >>> + >>> + # If custom rules enabled, deactivate default rules on interface >>> + if ($settings{'REDIR_CUSTOM_GREEN'} eq "on" ) { >>> + $settings{'REDIR_DNS_GREEN'}=3D"off"; >>> + $settings{'REDIR_NTP_GREEN'}=3D"off"; >>> + } >>> + >>> + if ($settings{'REDIR_CUSTOM_BLUE'} eq "on" ) { >>> + $settings{'REDIR_DNS_BLUE'}=3D"off"; >>> + $settings{'REDIR_NTP_BLUE'}=3D"off"; >>> + } >>> + >>> + if ($settings{'REDIR_CUSTOM_ORANGE'} eq "on" ) { >>> + $settings{'REDIR_DNS_ORANGE'}=3D"off"; >>> + $settings{'REDIR_NTP_ORANGE'}=3D"off"; >>> + } >>> + >>> + &General::writehash($settingsfile, \%settings); >>> + >>> + if ($settings{'REDIR_ENABLE_ADDON'} eq "on") { >>> + system ('/usr/local/bin/portredirctrl restart >/dev/null 2>&1'); >>> + system ('/usr/local/bin/portredirctrl enable >/dev/null 2>&1'); >>> + &General::log('portredir addon: port redirections enabled'); >>> + } >>> + if ($settings{'REDIR_ENABLE_ADDON'} eq "off") { >>> + system ('/usr/local/bin/portredirctrl disable >/dev/null 2>&1'); >>> + system ('/usr/local/bin/portredirctrl stop >/dev/null 2>&1'); >>> + &General::log('portredir addon: port redirections disabled'); >>> + } >>> + >>> +# Add/edit an entry to the redirectsfile. >>> + >>> +} elsif (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION= '} eq $Lang::tr{'update'})) { >>> + >>> + # Check if any input has been performed. >>> + if ($settings{'REDIR_ENTRY_ADDRESS'} ne '') { >>> + >>> + # Check if the given input is no valid IP-address, display an error me= ssage. >>> + if (!&General::validip($settings{'REDIR_ENTRY_ADDRESS'})) { >>> + $errormessage =3D "$Lang::tr{'portredir invalid address'}"; >>> + } >>> + } else { >>> + $errormessage =3D "$Lang::tr{'portredir empty input'}"; >>> + } >>> + >>> + # Go further if there was no error. >>> + if ($errormessage eq '') { >>> + my %redirects =3D (); >>> + my $id; >>> + my $status; >>> + >>> + # Assign hash values. >>> + my $new_entry_interface =3D $settings{'REDIR_ENTRY_INTERFACE'}; >>> + my $new_entry_protocol =3D $settings{'REDIR_ENTRY_PROTOCOL'}; >>> + my $new_entry_port =3D $settings{'REDIR_ENTRY_PORT'}; >>> + my $new_entry_address =3D $settings{'REDIR_ENTRY_ADDRESS'}; >>> + my $new_entry_remark =3D $settings{'REDIR_ENTRY_REMARK'}; >>> + >>> + # Read-in redirectsfile. >>> + &General::readhasharray($redirectsfile, \%redirects); >>> + >>> + # Check if we should edit an existing entry and got an ID. >>> + if (($settings{'ACTION'} eq $Lang::tr{'update'}) && ($settings{'ID'}))= { >>> + # Assin the provided id. >>> + $id =3D $settings{'ID'}; >>> + >>> + # Undef the given ID. >>> + undef($settings{'ID'}); >>> + >>> + # Grab the configured status of the corresponding entry. >>> + $status =3D $redirects{$id}[4]; >>> + } else { >>> + # Each newly added entry automatically should be enabled. >>> + $status =3D "enabled"; >>> + >>> + # Generate the ID for the new entry. >>> + # >>> + # Sort the keys by their ID and store them in an array. >>> + my @keys =3D sort { $a <=3D> $b } keys %redirects; >>> + >>> + # Reverse the key array. >>> + my @reversed =3D reverse(@keys); >>> + >>> + # Obtain the last used id. >>> + my $last_id =3D @reversed[0]; >>> + >>> + # Increase the last id by one and use it as id for the new entry. >>> + $id =3D ++$last_id; >>> + } >>> + >>> + # Add/Modify the entry to/in the redirects hash. >>> + $redirects{$id} =3D ["$new_entry_interface", "$new_entry_protocol", "$= new_entry_port", "$new_entry_address","$status", "$new_entry_remark"]; >>> + >>> + # Write the changed redirects hash to the redirects file. >>> + &General::writehasharray($redirectsfile, \%redirects); >>> + } >>> + >>> +# Toggle Enabled/Disabled for an existing entry on the redirects list. >>> + >>> +} elsif ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { >>> + my %redirects =3D (); >>> + >>> + # Only go further, if an ID has been passed. >>> + if ($settings{'ID'}) { >>> + # Assign the given ID. >>> + my $id =3D $settings{'ID'}; >>> + >>> + # Undef the given ID. >>> + undef($settings{'ID'}); >>> + >>> + # Read-in ignoredfile. >>> + &General::readhasharray($redirectsfile, \%redirects); >>> + >>> + # Grab the configured status of the corresponding entry. >>> + my $status =3D $redirects{$id}[4]; >>> + >>> + # Switch the status. >>> + if ($status eq "disabled") { >>> + $status =3D "enabled"; >>> + } else { >>> + $status =3D "disabled"; >>> + } >>> + >>> + # Modify the status of the existing entry. >>> + $redirects{$id} =3D ["$redirects{$id}[0]", "$redirects{$id}[1]", "$red= irects{$id}[2]", "$redirects{$id}[3]","$status", "$redirects{$id}[5]"]; >>> + >>> + # Write the changed ignored hash to the redirects file. >>> + &General::writehasharray($redirectsfile, \%redirects); >>> + } >>> + >>> +# Remove entry from redirects list. >>> + >>> +} elsif ($settings{'ACTION'} eq $Lang::tr{'remove'}) { >>> + my %redirects =3D (); >>> + >>> + # Read-in redirectsfile. >>> + &General::readhasharray($redirectsfile, \%redirects); >>> + >>> + # move data on key up >>> + foreach my $key (sort keys %redirects) { >>> + if ($key >=3D $settings{'ID'}) { >>> + my $next =3D $key + 1; >>> + if (exists $redirects{$next}) { >>> + foreach my $i (0 .. $#{$redirects{$next}}) { $redirects{$key}[$i] = =3D $redirects{$next}[$i]; } >>> + } >>> + } >>> + } >>> + >>> + my $last_key =3D (sort {$a <=3D> $b} keys %redirects)[-1]; >>> + delete $redirects{$last_key}; >>> + >>> + # Undef the given ID. >>> + undef($settings{'ID'}); >>> + >>> + # Write the changed redirects hash to file. >>> + &General::writehasharray($redirectsfile, \%redirects); >>> +} >>> + >>> +# Load settings from file >>> +&General::readhash($settingsfile, \%settings); >>> +&General::readhasharray($redirectsfile, \%redirects); >>> + >>> +# Call functions to generate whole page. >>> +&Header::openpage($Lang::tr{'portredir port redirections'}, 1, ''); >>> +&Header::openbigbox('100%', 'left', '', $errormessage); >>> + >>> +if ($errormessage) { >>> + &Header::openbox('100%', 'left', $Lang::tr{'warning messages'}); >>> + print "$errormessage "; >>> + &Header::closebox(); >>> +} >>> + >>> +$checked{'REDIR_ENABLE_ADDON'}{'off'} =3D ''; >>> +$checked{'REDIR_ENABLE_ADDON'}{'on'} =3D ''; >>> +$checked{'REDIR_ENABLE_ADDON'}{$settings{'REDIR_ENABLE_ADDON'}} =3D "che= cked=3D'checked'"; >>> +$checked{'REDIR_CUSTOM_GREEN'}{'off'} =3D ''; >>> +$checked{'REDIR_CUSTOM_GREEN'}{'on'} =3D ''; >>> +$checked{'REDIR_CUSTOM_GREEN'}{$settings{'REDIR_CUSTOM_GREEN'}} =3D "che= cked=3D'checked'"; >>> +$checked{'REDIR_CUSTOM_BLUE'}{'off'} =3D ''; >>> +$checked{'REDIR_CUSTOM_BLUE'}{'on'} =3D ''; >>> +$checked{'REDIR_CUSTOM_BLUE'}{$settings{'REDIR_CUSTOM_BLUE'}} =3D "check= ed=3D'checked'"; >>> +$checked{'REDIR_CUSTOM_ORANGE'}{'off'} =3D ''; >>> +$checked{'REDIR_CUSTOM_ORANGE'}{'on'} =3D ''; >>> +$checked{'REDIR_CUSTOM_ORANGE'}{$settings{'REDIR_CUSTOM_ORANGE'}} =3D "c= hecked=3D'checked'"; >>> +$checked{'REDIR_DNS_GREEN'}{'off'} =3D ''; >>> +$checked{'REDIR_DNS_GREEN'}{'on'} =3D ''; >>> +$checked{'REDIR_DNS_GREEN'}{$settings{'REDIR_DNS_GREEN'}} =3D "checked= =3D'checked'"; >>> +$checked{'REDIR_NTP_GREEN'}{'off'} =3D ''; >>> +$checked{'REDIR_NTP_GREEN'}{'on'} =3D ''; >>> +$checked{'REDIR_NTP_GREEN'}{$settings{'REDIR_NTP_GREEN'}} =3D "checked= =3D'checked'"; >>> +$checked{'REDIR_DNS_BLUE'}{'off'} =3D ''; >>> +$checked{'REDIR_DNS_BLUE'}{'on'} =3D ''; >>> +$checked{'REDIR_DNS_BLUE'}{$settings{'REDIR_DNS_BLUE'}} =3D "checked=3D'= checked'"; >>> +$checked{'REDIR_NTP_BLUE'}{'off'} =3D ''; >>> +$checked{'REDIR_NTP_BLUE'}{'on'} =3D ''; >>> +$checked{'REDIR_NTP_BLUE'}{$settings{'REDIR_NTP_BLUE'}} =3D "checked=3D'= checked'"; >>> +$checked{'REDIR_DNS_ORANGE'}{'off'} =3D ''; >>> +$checked{'REDIR_DNS_ORANGE'}{'on'} =3D ''; >>> +$checked{'REDIR_DNS_ORANGE'}{$settings{'REDIR_DNS_ORANGE'}} =3D "checked= =3D'checked'"; >>> +$checked{'REDIR_NTP_ORANGE'}{'off'} =3D ''; >>> +$checked{'REDIR_NTP_ORANGE'}{'on'} =3D ''; >>> +$checked{'REDIR_NTP_ORANGE'}{$settings{'REDIR_NTP_ORANGE'}} =3D "checked= =3D'checked'"; >>> + >>> +$selected{'REDIR_ENTRY_INTERFACE'}{$settings{'REDIR_ENTRY_INTERFACE'}} = =3D 'selected'; >>> +$selected{'REDIR_ENTRY_PROTOCOL'}{$settings{'REDIR_ENTRY_PROTOCOL'}} =3D= 'selected'; >>> + >>> +&showMainBox(); >>> +&showRedirectsBox(); >>> + >>> +&Header::closebigbox(); >>> +&Header::closepage(); >>> + >>> +# Function to show main settings and options. >>> +sub showMainBox() { >>> + >>> + &Header::openbox('100%', 'center', "$Lang::tr{'settings'}"); >>> + print "
"; >>> + >>> +print <>> + >>> + >> + >>> + >>> + >>> + >>> + >>> +END >>> + >>> + # create html table with header line 1 >>> + print "
$= Lang::tr{'portredir common settings'}
$Lang::tr{'portredir enable addon'}:<= /td> >>> +
 
"; >>> + print ""; >>> + if ($netsettings{'GREEN_DEV'}) {print ""; >>> + } else { print ""; } >>> + if ($netsettings{'BLUE_DEV'}) {print ""; >>> + } else { print ""; } >>> + if ($netsettings{'ORANGE_DEV'}) {print ""; >>> + } else { print ""; } >>> + >>> + # the empty right row >>> + print ""; >>> + >>> + # line 2 >>> + print ""; >>> + if ($netsettings{'GREEN_DEV'}) {print "";} else { print "";} >>> + if ($netsettings{'BLUE_DEV'}) {print "";} else { print "";} >>> + if ($netsettings{'ORANGE_DEV'}) {print "";} else { print "";} >>> + >>> + # line 3 >>> + print ""; >>> + if ($netsettings{'GREEN_DEV'}) {print "";} else { print "";} >>> + if ($netsettings{'BLUE_DEV'}) {print "";} else { print "";} >>> + if ($netsettings{'ORANGE_DEV'}) {print "";} else { print "";} >>> + >>> + # line 4 >>> + print "";} else { print "";} >>> + if ($netsettings{'BLUE_DEV'}) {print "";} else { print "";} >>> + if ($netsettings{'ORANGE_DEV'}) {print "";} else { print "";} >>> + >>> + print <>> +
$Lang::tr{'po= rtredir fw for interface'}$Lang::tr{'green'}$Lang::tr{'blue'}$Lang::tr{'orange'}
$Lang::tr{'portredir force local dns'}
$Lang::tr{'portredir force local ntp'}
$Lang::tr{'portredir enable user redirections'}"; >>> + if ($netsettings{'GREEN_DEV'}) {print "
>>> + >>> + >>> + >>> +
 
$Lang::tr{'portredir save to activate'}<= /td>
>>> +END >>> + >>> +&Header::closebox(); >>> +} >>> + >>> +# Function to show elements of the redirects file and allow to add or re= move single members of it. >>> +sub showRedirectsBox() { >>> + &Header::openbox('100%', 'center', "$Lang::tr{'portredir custom = redirections'}"); >>> + >>> + print <>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> +END >>> + # Check if some rules have been added to be redirects. >>> + if (keys (%redirects)) { >>> + my $col =3D ""; >>> + >>> + # List all entries of the hash. >>> + foreach my $key (sort keys %redirects){ >>> + >>> + # Assign data array positions to some nice variable names. >>> + my $interface =3D $redirects{$key}[0]; >>> + my $protocol =3D $redirects{$key}[1]; >>> + my $port =3D $redirects{$key}[2]; >>> + my $address =3D $redirects{$key}[3]; >>> + my $status =3D $redirects{$key}[4]; >>> + my $remark =3D $redirects{$key}[5]; >>> + >>> + # Check if the key (id) number is even or not. >>> + if ($settings{'ID'} eq $key) { >>> + $col=3D"bgcolor=3D'${Header::colouryellow}'"; >>> + } elsif ($key % 2) { >>> + $col=3D"bgcolor=3D'$color{'color22'}'"; >>> + } else { >>> + $col=3D"bgcolor=3D'$color{'color20'}'"; >>> + } >>> + >>> + # Choose icon for the checkbox. >>> + my $gif; >>> + my $gdesc; >>> + >>> + # Check if the status is enabled and select the correct image and d= escription. >>> + if ($status eq 'enabled' ) { >>> + $gif =3D 'on.gif'; >>> + $gdesc =3D $Lang::tr{'click to disable'}; >>> + } else { >>> + $gif =3D 'off.gif'; >>> + $gdesc =3D $Lang::tr{'click to enable'}; >>> + } >>> + >>> + print <>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> +END >>> + } >>> + } else { >>> + # Print notice that currently no ports are redirected. >>> + print "\n"; >>> + print "\n"; >>> + print "\n"; >>> + } >>> + >>> + print "
$Lang::tr{'interface'}$Lang::tr{'protocol'}$Lang::tr{'port'}$Lang::tr{'ip address'}$Lang::tr{'remark'}
$Lang::tr{$interface}$protocol >>> + $port $addr= ess $rema= rk >>> +
>>> + >>> + >>> + >>> +
>>> +
>>> +
>>> + >>> + >>> + >>> +
>>> +
>>> +
>>> + >>> + >>> + >>> +
>>> +
$Lang::tr{'portredir no entr= ies'}
\n"; >>> + >>> + # Section to add new elements or edit existing ones. >>> + print <>> +
>>> +
>>> +
>>> +
>>> + >>> +END >>> + >>> + # Assign correct headline and button text. >>> + my $buttontext; >>> + my $entry_interface; >>> + my $entry_protocol; >>> + my $entry_port; >>> + my $entry_address; >>> + my $entry_remark; >>> + >>> + # Check if an ID (key) has been given, in this case an existing entry s= hould be edited. >>> + if ($settings{'ID'} ne '') { >>> + $buttontext =3D $Lang::tr{'update'}; >>> + print "\n"; >>> + >>> + # Grab address and remark for the given key. >>> + $entry_interface =3D $redirects{$settings{'ID'}}[0]; >>> + $entry_protocol =3D $redirects{$settings{'ID'}}[1]; >>> + $entry_port =3D $redirects{$settings{'ID'}}[2]; >>> + $entry_address =3D $redirects{$settings{'ID'}}[3]; >>> + $entry_remark =3D $redirects{$settings{'ID'}}[5]; >>> + >>> + } else { >>> + $buttontext =3D $Lang::tr{'add'}; >>> + print "\n"; >>> + print "\n"; >>> + } >>> + >>> + print <>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> + >>> +
$Lang::tr{'update'}=
$Lang::tr{'dnsforw= ard add a new entry'}
 
$Lang::tr{'interface'}$Lang::tr{'protocol'} $Lang::tr{'port'} $Lang::tr{'ip address'} $Lang::tr{'remark'}
>>> +
>>> +END >>> + &Header::closebox(); >>> +} >>> diff --git a/config/rootfiles/common/misc-progs b/config/rootfiles/common= /misc-progs >>> index d6594b3f8..fbad2af8b 100644 >>> --- a/config/rootfiles/common/misc-progs >>> +++ b/config/rootfiles/common/misc-progs >>> @@ -17,6 +17,7 @@ usr/local/bin/logwatch >>> #usr/local/bin/mpfirectrl >>> usr/local/bin/openvpnctrl >>> usr/local/bin/pakfire >>> +#usr/local/bin/portredirctrl >>> usr/local/bin/qosctrl >>> usr/local/bin/rebuildhosts >>> usr/local/bin/rebuildroutes >>> diff --git a/config/rootfiles/packages/portredir b/config/rootfiles/packa= ges/portredir >>> new file mode 100644 >>> index 000000000..4b4ba8366 >>> --- /dev/null >>> +++ b/config/rootfiles/packages/portredir >>> @@ -0,0 +1,11 @@ >>> +etc/rc.d/init.d/portredir >>> +etc/rc.d/rc0.d/K77portredir >>> +etc/rc.d/rc3.d/S23portredir >>> +etc/rc.d/rc6.d/K77portredir >>> +srv/web/ipfire/cgi-bin/portredir.cgi >>> +usr/local/bin/portredirctrl >>> +var/ipfire/addon-lang/portredir.de.pl >>> +var/ipfire/addon-lang/portredir.en.pl >>> +var/ipfire/backup/addons/includes/portredir >>> +var/ipfire/menu.d/EX-portredir.menu >>> +var/ipfire/portredir >>> diff --git a/lfs/portredir b/lfs/portredir >>> new file mode 100644 >>> index 000000000..a4911f71f >>> --- /dev/null >>> +++ b/lfs/portredir >>> @@ -0,0 +1,85 @@ >>> +########################################################################= ####### >>> +# = # >>> +# IPFire.org - A linux based firewall = # >>> +# Copyright (C) 2007-2021 IPFire Team = # >>> +# = # >>> +# 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 . = # >>> +# = # >>> +########################################################################= ####### >>> + >>> +########################################################################= ####### >>> +# Definitions >>> +########################################################################= ####### >>> + >>> +include Config >>> + >>> +VER =3D 1.0 >>> + >>> +THISAPP =3D portredir-$(VER) >>> +DIR_APP =3D $(DIR_SRC)/$(THISAPP) >>> +TARGET =3D $(DIR_INFO)/$(THISAPP) >>> +PROG =3D portredir >>> +PAK_VER =3D 1 >>> + >>> +########################################################################= ####### >>> +# Top-level Rules >>> +########################################################################= ####### >>> + >>> +install : $(TARGET) >>> + >>> +check : >>> + >>> +download : >>> + >>> +md5 : >>> + >>> +dist:=20 >>> + @$(PAK) >>> + >>> +########################################################################= ####### >>> +# Installation Details >>> +########################################################################= ####### >>> + >>> +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) >>> + @$(PREBUILD) >>> + @rm -rf $(DIR_APP) && cd $(DIR_SRC) >>> + >>> + #install cgi=20 >>> + install -v -m 755 $(DIR_CONF)/portredir/portredir.cgi /srv/web/ipfire/c= gi-bin/ >>> + >>> + #create configuration dir=20 >>> + -mkdir -pv /var/ipfire/portredir/ >>> + chown -R nobody:nobody /var/ipfire/portredir/ >>> + >>> + # Install include file for backup >>> + install -v -m 644 $(DIR_CONF)/portredir/portredir-backup /var/ipfire/ba= ckup/addons/includes/portredir >>> + >>> + # Install menu file >>> + install -v -m 644 $(DIR_CONF)/portredir/EX-portredir.menu /var/ipfire/m= enu.d/ >>> + chown nobody:nobody /var/ipfire/menu.d/EX-portredir.menu >>> + >>> + # Install addon-specific language-files >>> + install -v -m 644 $(DIR_CONF)/portredir/lang/portredir.*.pl /var/ipfire= /addon-lang/ >>> + >>> + #install initscripts >>> + $(call INSTALL_INITSCRIPT,portredir) >>> + >>> + # Create symlinks for runlevel interaction. >>> + ln -svf /etc/rc.d/init.d/portredir /etc/rc.d/rc3.d/S23portredir >>> + ln -svf /etc/rc.d/init.d/portredir /etc/rc.d/rc0.d/K77portredir >>> + ln -svf /etc/rc.d/init.d/portredir /etc/rc.d/rc6.d/K77portredir >>> + >>> + @rm -rf $(DIR_APP) >>> + @$(POSTBUILD) >>> + >>> diff --git a/make.sh b/make.sh >>> index fc03ebcd5..ab9fe881a 100755 >>> --- a/make.sh >>> +++ b/make.sh >>> @@ -1623,6 +1623,7 @@ buildipfire() { >>> lfsmake2 socat >>> lfsmake2 libcdada >>> lfsmake2 pmacct >>> + lfsmake2 portredir >>> } >>>=20 >>> buildinstaller() { >>> diff --git a/src/initscripts/packages/portredir b/src/initscripts/package= s/portredir >>> new file mode 100644 >>> index 000000000..cc57fb9cc >>> --- /dev/null >>> +++ b/src/initscripts/packages/portredir >>> @@ -0,0 +1,191 @@ >>> +#!/bin/sh >>> +######################################################################## >>> +# Begin $rc_base/init.d/portredir >>> +# >>> +# Description : portredir init script for DNS/NTP and custom=20 >>> +# port redirection rules >>> +# >>> +######################################################################## >>> + >>> +. /etc/sysconfig/rc >>> +. ${rc_functions} >>> + >>> +IPT=3D"/sbin/iptables"; >>> +parent_chain=3D"PREROUTING"; >>> +chain=3D"PORT_REDIRECT"; >>> + >>> +confdir=3D"/var/ipfire/portredir"; >>> +settingsfile=3D"${confdir}/settings"; >>> +redirectsfile=3D"${confdir}/redirects"; >>> +SYSLOG=3D"NO"; >>> +VERBOSE=3D"NO"; >>> + >>> +eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings); >>> +eval $(/usr/local/bin/readhash ${settingsfile}); >>> + >>> +logtext() { >>> + if [ "${SYSLOG}" =3D "YES" ]; then logger -t "portredir" ${1}; fi; >>> + if [ "${VERBOSE}" =3D "YES" ]; then echo ${1}; fi;} >>> + >>> +create_chain() { >>> + >>> + local line=3D$(${IPT} -t nat -L ${parent_chain} --line-numbers |grep "S= QUID" |awk '{printf($1)}'); >>> + >>> + if [[ "${REDIR_ENABLE_ADDON}" =3D=3D "off" || -z "${REDIR_ENABLE_ADDON}= " ]]; then >>> + logtext "addon not enabled in web interface..."; >>> + echo "Portredir addon not enabled in web interface..."; >>> + exit 0; >>> + fi; >>> + >>> + if [ -z "$(${IPT} -t nat -L ${parent_chain} |grep ${chain})" ]; then >>> + ${IPT} -t nat -N ${chain}; >>> + >>> + if [ ! -z "${line}" ]; then >>> + logtext "create chain ${chain} and link in ${parent_chain} at positio= n ${line}..."; >>> + ${IPT} -t nat -I ${parent_chain} ${line} -j ${chain}; >>> + else >>> + logtext "create chain ${chain} and link in ${parent_chain} at last po= sition..."; >>> + ${IPT} -t nat -A ${parent_chain} -j ${chain}; >>> + fi >>> + else >>> + return 1; >>> + fi; >>> + return 0; >>> +} >>> + >>> +remove_chain() { >>> + if [ ! -z "$(${IPT} -t nat -L ${parent_chain} |grep ${chain})" ]; then >>> + logtext "remove chain ${chain} and link in ${parent_chain} from system= ..."; >>> + ${IPT} -t nat -D "${parent_chain}" -j ${chain}; >>> + ${IPT} -t nat -F ${chain}; >>> + ${IPT} -t nat -X ${chain}; >>> + else >>> + return 1; >>> + fi; >>> + return 0; >>> +} >>> + >>> +activate_custom_redirections() { >>> +=09 >>> + local array=3D(); >>> + local redirects=3D(); >>> + local i; >>> + index=3D(); >>> + iface=3D(); >>> + protocol=3D(); >>> + port=3D(); >>> + targetip=3D(); >>> + enabled=3D(); >>> + >>> + IFS=3D$'\n' read -d '' -ra redirects < ${redirectsfile}; >>> + >>> + for i in "${!redirects[@]}" >>> + do >>> + IFS=3D$',' read -ra array <<< ${redirects[i]}; >>> + index[i]=3D${array[0]}; >>> + iface[i]=3D${array[1]}; >>> + protocol[i]=3D${array[2]}; >>> + port[i]=3D${array[3]}; >>> + targetip[i]=3D${array[4]}; >>> + enabled[i]=3D${array[5]}; >>> + done >>> + >>> + for i in "${!index[@]}" >>> + do >>> + if [[ ! -z "${GREEN_DEV}" && "${iface[i]}" =3D "green" && "${enabled[= i]}" =3D "enabled" ]]; then >>> + >>> + logtext "add redirect in ${chain} on ${GREEN_DEV} ip ${targetip[i]} p= rotocol ${protocol[i]} port ${port[i]} "; >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d ${targetip[i]} -p ${prot= ocol[i]} -m ${protocol[i]} --dport ${port[i]} -j RETURN; >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p ${protocol[i]} -m ${prot= ocol[i]} --dport ${port[i]} -j REDIRECT; >>> + fi >>> + if [[ ! -z "${BLUE_DEV}" && "${iface[i]}" =3D "blue" && "${enabled[i]= }" =3D "enabled" ]]; then >>> + logtext "add redirect in ${chain} on ${BLUE_DEV} ip ${targetip[i]} pr= otocol ${protocol[i]} port ${port[i]} "; >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d ${targetip[i]} -p ${proto= col[i]} -m ${protocol[i]} --dport ${port[i]} -j RETURN; >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p ${protocol[i]} -m ${proto= col[i]} --dport ${port[i]} -j REDIRECT; >>> + fi >>> + if [[ ! -z "${ORANGE_DEV}" && "${iface[i]}" =3D "orange" && "${enable= d[i]}" =3D "enabled" ]]; then >>> + logtext "add redirect in ${chain} on ${ORANGE_DEV} ip ${targetip[i]} = protocol ${protocol[i]} port ${port[i]} "; >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -d ${targetip[i]} -p ${pro= tocol[i]} -m ${protocol[i]} --dport ${port[i]} -j RETURN; >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p ${protocol[i]} -m ${pro= tocol[i]} --dport ${port[i]} -j REDIRECT; >>> + fi >>> + done >>> + unset array redirects i index iface protocol port targetip enabled; >>> + return 0; >>> +} >>> + >>> +activate_redirections() { >>> + >>> + if ! create_chain; then return 1; fi; >>> +=09 >>> + # Force DNS REDIRECTs on GREEN (udp, tcp, 53) >>> + if [[ "${REDIR_DNS_GREEN}" =3D=3D "on" && "${REDIR_CUSTOM_GREEN}" =3D = "off" ]]; then >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d ${GREEN_ADDRESS} -p udp -= m udp --dport domain -j RETURN; >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p udp -m udp --dport domain= -j REDIRECT; >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d ${GREEN_ADDRESS} -p tcp -= m tcp --dport domain -j RETURN; >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p tcp -m tcp --dport domain= -j REDIRECT; >>> + fi >>> + >>> + # Force DNS REDIRECTs on BLUE (udp, tcp, 53) >>> + if [[ "${REDIR_DNS_BLUE}" =3D=3D "on" && "${REDIR_CUSTOM_BLUE}" =3D "o= ff" ]]; then >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d ${BLUE_ADDRESS} -p udp -m = udp --dport domain -j RETURN >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p udp -m udp --dport domain = -j REDIRECT >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d ${BLUE_ADDRESS} -p tcp -m = tcp --dport domain -j RETURN >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p tcp -m tcp --dport domain = -j REDIRECT >>> + fi >>> + >>> + # Force DNS REDIRECTs on ORANGE (udp, tcp, 53) >>> + if [[ "${REDIR_DNS_ORANGE}" =3D=3D "on" && "${REDIR_CUSTOM_ORANGE}" = =3D "off" ]]; then >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -d ${ORANGE_ADDRESS} -p udp= -m udp --dport domain -j RETURN >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p udp -m udp --dport domai= n -j REDIRECT >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -d ${ORANGE_ADDRESS} -p tcp= -m tcp --dport domain -j RETURN >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p tcp -m tcp --dport domai= n -j REDIRECT >>> + fi >>> + >>> + # Force NTP REDIRECTs on GREEN (udp, 123) >>> + if [[ "${REDIR_NTP_GREEN}" =3D=3D "on" && "${REDIR_CUSTOM_GREEN}" =3D = "off" ]]; then >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d ${GREEN_ADDRESS} -p udp -= m udp --dport ntp -j RETURN >>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p udp -m udp --dport ntp -j= REDIRECT >>> + fi >>> + >>> + # Force NTP REDIRECTs on BLUE (udp, 123) >>> + if [[ "${REDIR_NTP_BLUE}" =3D=3D "on" && "${REDIR_CUSTOM_BLUE}" =3D "o= ff" ]]; then >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d ${BLUE_ADDRESS} -p udp -m = udp --dport ntp -j RETURN >>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p udp -m udp --dport ntp -j = REDIRECT >>> + fi >>> + >>> + # Force NTP REDIRECTs on ORANGE (udp, 123) >>> + if [[ "${REDIR_NTP_ORANGE}" =3D=3D "on" && "${REDIR_CUSTOM_ORANGE}" = =3D "off" ]]; then >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -d ${ORANGE_ADDRESS} -p udp= -m udp --dport ntp -j RETURN >>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p udp -m udp --dport ntp -= j REDIRECT >>> + fi >>> + >>> + if ! activate_custom_redirections; then return 1; fi; >>> + >>> + return 0; >>> +} >>> + >>> +case "${1}" in >>> + start) >>> + boot_mesg "Loading port redirections..." >>> + activate_redirections; >>> + evaluate_retval; >>> + ;; >>> + >>> + stop)=09 >>> + boot_mesg "Removing port redirections..." >>> + remove_chain; >>> + evaluate_retval; >>> + ;; >>> + >>> + restart) >>> + ${0} stop >>> + ${0} start >>> + ;; >>> + >>> + *) >>> + echo "Usage: ${0} {start|stop|restart}" >>> + exit 1 >>> + ;; >>> +esac >>> + >>> +# End $rc_base/init.d/portredir >>> diff --git a/src/misc-progs/Makefile b/src/misc-progs/Makefile >>> index 7c3ef7529..850f8fdcc 100644 >>> --- a/src/misc-progs/Makefile >>> +++ b/src/misc-progs/Makefile >>> @@ -30,7 +30,7 @@ SUID_PROGS =3D squidctrl sshctrl ipfirereboot \ >>> wirelessctrl getipstat qosctrl \ >>> redctrl syslogdctrl extrahdctrl sambactrl \ >>> smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \ >>> - setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \ >>> + setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes port= redirctrl \ >>> getconntracktable wirelessclient torctrl ddnsctrl unboundctrl \ >>> captivectrl >>>=20 >>> diff --git a/src/misc-progs/portredirctrl.c b/src/misc-progs/portredirctr= l.c >>> new file mode 100644 >>> index 000000000..7897d711c >>> --- /dev/null >>> +++ b/src/misc-progs/portredirctrl.c >>> @@ -0,0 +1,47 @@ >>> +/* This file is part of the IPFire Firewall. >>> + * >>> + * This program is distributed under the terms of the GNU General Public >>> + * Licence. See the file COPYING for details. >>> + * >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include "setuid.h" >>> + >>> +int main(int argc, char *argv[]) { >>> + if (!(initsetuid())) >>> + exit(1); >>> + >>> + // Check what command is asked >>> + if (argc < 2) { >>> + fprintf(stderr, "\nNo argument given.\n\nportredirctrl (= start|stop|restart|enable|disable)\n\n"); >>> + exit(1); >>> + } >>> + >>> + if (strcmp(argv[1], "start") =3D=3D 0) { >>> + safe_system("/etc/rc.d/init.d/portredir start"); >>> + } else if (strcmp(argv[1], "stop") =3D=3D 0) { >>> + safe_system("/etc/rc.d/init.d/portredir stop"); >>> + } else if (strcmp(argv[1], "restart") =3D=3D 0) { >>> + safe_system("/etc/rc.d/init.d/portredir restart"); >>> + } else if (strcmp(argv[1], "enable") =3D=3D 0) { >>> + safe_system("touch /var/ipfire/portredir/enable"); >>> + safe_system("ln -snf /etc/rc.d/init.d/portredir /etc/rc.d/rc3.d/S23por= tredir >/dev/null 2>&1"); >>> + safe_system("ln -snf /etc/rc.d/init.d/portredir /etc/rc.d/rc0.d/K77por= tredir >/dev/null 2>&1"); >>> + safe_system("ln -snf /etc/rc.d/init.d/portredir /etc/rc.d/rc6.d/K77por= tredir >/dev/null 2>&1"); >>> + } else if (strcmp(argv[1], "disable") =3D=3D 0) { >>> + safe_system("/etc/rc.d/init.d/portredir stop"); >>> + safe_system("unlink /var/ipfire/portredir/enable"); >>> + safe_system("rm -rf /etc/rc.d/rc*.d/*portredir >/dev/null 2>&1"); >>> + } else { >>> + fprintf(stderr, "\nBad argument given.\n\nportredirctrl = (start|stop|restart|enable|disable)\n\n"); >>> + exit(1); >>> + } >>> + >>> + return 0; >>> +} >>> diff --git a/src/paks/portredir/install.sh b/src/paks/portredir/install.sh >>> new file mode 100644 >>> index 000000000..9f69aeae2 >>> --- /dev/null >>> +++ b/src/paks/portredir/install.sh >>> @@ -0,0 +1,32 @@ >>> +#!/bin/bash >>> +########################################################################= #### >>> +# = # >>> +# This file is part of the IPFire Firewall. = # >>> +# = # >>> +# IPFire 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 2 of the License, or = # >>> +# (at your option) any later version. = # >>> +# = # >>> +# IPFire 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 IPFire; if not, write to the Free Software = # >>> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U= SA # >>> +# = # >>> +# Copyright (C) 2021 IPFire-Team . = # >>> +# = # >>> +########################################################################= #### >>> +# >>> +. /opt/pakfire/lib/functions.sh >>> +extract_files >>> +restore_backup ${NAME} >>> + >>> +/usr/local/bin/update-lang-cache >>> + >>> +chown root:nobody /usr/local/bin/portredirctrl >>> +chmod 4750 /usr/local/bin/portredirctrl >>> +chmod u+s /usr/local/bin/portredirctrl >>> diff --git a/src/paks/portredir/uninstall.sh b/src/paks/portredir/uninsta= ll.sh >>> new file mode 100644 >>> index 000000000..df9270125 >>> --- /dev/null >>> +++ b/src/paks/portredir/uninstall.sh >>> @@ -0,0 +1,28 @@ >>> +#!/bin/bash >>> +########################################################################= #### >>> +# = # >>> +# This file is part of the IPFire Firewall. = # >>> +# = # >>> +# IPFire 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 2 of the License, or = # >>> +# (at your option) any later version. = # >>> +# = # >>> +# IPFire 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 IPFire; if not, write to the Free Software = # >>> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U= SA # >>> +# = # >>> +# Copyright (C) 2007 IPFire-Team . = # >>> +# = # >>> +########################################################################= #### >>> +# >>> +. /opt/pakfire/lib/functions.sh >>> +make_backup ${NAME} >>> +remove_files >>> + >>> +/usr/local/bin/update-lang-cache >>> diff --git a/src/paks/portredir/update.sh b/src/paks/portredir/update.sh >>> new file mode 100644 >>> index 000000000..89c40d0d7 >>> --- /dev/null >>> +++ b/src/paks/portredir/update.sh >>> @@ -0,0 +1,26 @@ >>> +#!/bin/bash >>> +########################################################################= #### >>> +# = # >>> +# This file is part of the IPFire Firewall. = # >>> +# = # >>> +# IPFire 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 2 of the License, or = # >>> +# (at your option) any later version. = # >>> +# = # >>> +# IPFire 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 IPFire; if not, write to the Free Software = # >>> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U= SA # >>> +# = # >>> +# Copyright (C) 2007 IPFire-Team . = # >>> +# = # >>> +########################################################################= #### >>> +# >>> +. /opt/pakfire/lib/functions.sh >>> +./uninstall.sh >>> +./install.sh >>> --=20 >>> 2.18.0 >>>=20 >>=20 >=20 --===============8207404099069258012==--