From: Matthias Fischer <matthias.fischer@ipfire.org>
To: development@lists.ipfire.org
Subject: [PATCH] New addon: Portredirect 1.0
Date: Sun, 27 Jun 2021 15:48:19 +0200 [thread overview]
Message-ID: <20210627134819.2088-1-matthias.fischer@ipfire.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 49002 bytes --]
From: Marcel Lorenz <marcel.lorenz(a)ipfire.org>
Please note:
This is a new addon written by Marcel Lorenz <marcel.lorenz(a)ipfire.org>.
It adds a new GUI to IPFire for DNS/NTP *and* user specific port redirections.
How its working:
It has exactly the same functionalities as "Forcing DNS/NTP..." - and some more.
By setting switches, DNS/NTP requests are automatically
redirected to the local IPFire DNS/NTP servers.
Additionally, the user can specify custom redirections.
These rules are added to a new chain in PREROUTING => PORT_REDIRECT.
To avoid problems with (e.g.) transparent 'squid' configurations,
redirection rules are added automatically before existing 'squid' rules.
Signed-off-by: Matthias Fischer <matthias.fischer(a)ipfire.org>
---
| 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
--git a/config/portredir/EX-portredir.menu b/config/portredir/EX-portredir.menu
new file mode 100644
index 000000000..8376e8053
--- /dev/null
+++ b/config/portredir/EX-portredir.menu
@@ -0,0 +1,6 @@
+ $subfirewall->{'95.portredir'} = {
+ 'caption' => $Lang::tr{'portredir port redirections'},
+ 'uri' => '/cgi-bin/portredir.cgi',
+ 'title' => "$Lang::tr{'portredir port redirections'}",
+ 'enabled' => 1
+ };
diff --git a/config/portredir/lang/portredir.de.pl b/config/portredir/lang/portredir.de.pl
new file mode 100644
index 000000000..b932d4a85
--- /dev/null
+++ b/config/portredir/lang/portredir.de.pl
@@ -0,0 +1,19 @@
+%tr = (
+%tr,
+'portredir enable addon' => 'Addon aktivieren',
+'portredir common settings' => 'Allgemeine Einstellungen',
+'portredir port redirections' => 'Portumleitungen',
+'portredir fw for interface' => 'Firewalloptionen für das Interface',
+'portredir enable user redirections' => 'Aktiviere benutzerdefinierte Portumleitungen',
+'portredir force local dns' => 'Erzwinge lokale DNS-Server',
+'portredir force local ntp' => 'Erzwinge lokale NTP-Server',
+'portredir custom redirections' => 'Benutzerdefinierte Portumleitungen',
+'portredir remove rule' => 'Entferne Regel',
+'portredir add rule' => 'Hinzufügen',
+'portredir no entries' => 'Keine Einträge vorhanden.',
+'portredir invalid address' => 'Ungültige Host-Addresse.',
+'portredir empty input' => 'Fehlende Angabe: Bitte geben Sie einen gültigen Host an.',
+'portredir save to activate' => 'Speichern, um Änderungen zu aktivieren',
+);
+
+#EOF
diff --git a/config/portredir/lang/portredir.en.pl b/config/portredir/lang/portredir.en.pl
new file mode 100644
index 000000000..f442f3eaa
--- /dev/null
+++ b/config/portredir/lang/portredir.en.pl
@@ -0,0 +1,19 @@
+%tr = (
+%tr,
+'portredir enable addon' => 'Enable addon',
+'portredir common settings' => 'Common settings',
+'portredir port redirections' => 'Port redirections',
+'portredir fw for interface' => 'Firewall options for interface',
+'portredir enable user redirections' => 'Enable user port redirections',
+'portredir force local dns' => 'Enforce local DNS servers',
+'portredir force local ntp' => 'Enforce local NTP servers',
+'portredir custom redirections' => 'Custom port redirections',
+'portredir remove rule' => 'Remove rule',
+'portredir add rule' => 'Add new',
+'portredir no entries' => 'No entries at the moment.',
+'portredir invalid address' => 'Invalid host address.',
+'portredir empty input' => 'Empty input: Please enter a valid host.',
+'portredir save to activate' => 'Save to activate changes',
+);
+
+#EOF
diff --git a/config/portredir/portredir-backup b/config/portredir/portredir-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 <info(a)ipfire.org> #
+# #
+# 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";
+
+# File declarations
+my $settingsfile = "${General::swroot}/portredir/settings";
+my $redirectsfile = "${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 = ();
+our %color = ();
+&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
+&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
+
+my %settings=();
+my %portredirs=();
+my %checked=(); # Checkbox manipulations
+my $errormessage='';
+my %selected=();
+our %redirects=();
+
+$settings{'ACTION'} = '';
+$settings{'REDIR_ENABLE_ADDON'}="off";
+$settings{'REDIR_CUSTOM_GREEN'}="off";
+$settings{'REDIR_CUSTOM_BLUE'}="off";
+$settings{'REDIR_CUSTOM_ORANGE'}="off";
+$settings{'REDIR_DNS_GREEN'}="off";
+$settings{'REDIR_NTP_GREEN'}="off";
+$settings{'REDIR_DNS_BLUE'}="off";
+$settings{'REDIR_NTP_BLUE'}="off";
+$settings{'REDIR_DNS_ORANGE'}="off";
+$settings{'REDIR_NTP_ORANGE'}="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'}="off";
+ $settings{'REDIR_NTP_GREEN'}="off";
+ }
+
+ if ($settings{'REDIR_CUSTOM_BLUE'} eq "on" ) {
+ $settings{'REDIR_DNS_BLUE'}="off";
+ $settings{'REDIR_NTP_BLUE'}="off";
+ }
+
+ if ($settings{'REDIR_CUSTOM_ORANGE'} eq "on" ) {
+ $settings{'REDIR_DNS_ORANGE'}="off";
+ $settings{'REDIR_NTP_ORANGE'}="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 message.
+ if (!&General::validip($settings{'REDIR_ENTRY_ADDRESS'})) {
+ $errormessage = "$Lang::tr{'portredir invalid address'}";
+ }
+ } else {
+ $errormessage = "$Lang::tr{'portredir empty input'}";
+ }
+
+ # Go further if there was no error.
+ if ($errormessage eq '') {
+ my %redirects = ();
+ my $id;
+ my $status;
+
+ # Assign hash values.
+ my $new_entry_interface = $settings{'REDIR_ENTRY_INTERFACE'};
+ my $new_entry_protocol = $settings{'REDIR_ENTRY_PROTOCOL'};
+ my $new_entry_port = $settings{'REDIR_ENTRY_PORT'};
+ my $new_entry_address = $settings{'REDIR_ENTRY_ADDRESS'};
+ my $new_entry_remark = $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 = $settings{'ID'};
+
+ # Undef the given ID.
+ undef($settings{'ID'});
+
+ # Grab the configured status of the corresponding entry.
+ $status = $redirects{$id}[4];
+ } else {
+ # Each newly added entry automatically should be enabled.
+ $status = "enabled";
+
+ # Generate the ID for the new entry.
+ #
+ # Sort the keys by their ID and store them in an array.
+ my @keys = sort { $a <=> $b } keys %redirects;
+
+ # Reverse the key array.
+ my @reversed = reverse(@keys);
+
+ # Obtain the last used id.
+ my $last_id = @reversed[0];
+
+ # Increase the last id by one and use it as id for the new entry.
+ $id = ++$last_id;
+ }
+
+ # Add/Modify the entry to/in the redirects hash.
+ $redirects{$id} = ["$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 = ();
+
+ # Only go further, if an ID has been passed.
+ if ($settings{'ID'}) {
+ # Assign the given ID.
+ my $id = $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 = $redirects{$id}[4];
+
+ # Switch the status.
+ if ($status eq "disabled") {
+ $status = "enabled";
+ } else {
+ $status = "disabled";
+ }
+
+ # Modify the status of the existing entry.
+ $redirects{$id} = ["$redirects{$id}[0]", "$redirects{$id}[1]", "$redirects{$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 = ();
+
+ # Read-in redirectsfile.
+ &General::readhasharray($redirectsfile, \%redirects);
+
+ # move data on key up
+ foreach my $key (sort keys %redirects) {
+ if ($key >= $settings{'ID'}) {
+ my $next = $key + 1;
+ if (exists $redirects{$next}) {
+ foreach my $i (0 .. $#{$redirects{$next}}) { $redirects{$key}[$i] = $redirects{$next}[$i]; }
+ }
+ }
+ }
+
+ my $last_key = (sort {$a <=> $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 "<font color='red'>$errormessage </font>";
+ &Header::closebox();
+}
+
+$checked{'REDIR_ENABLE_ADDON'}{'off'} = '';
+$checked{'REDIR_ENABLE_ADDON'}{'on'} = '';
+$checked{'REDIR_ENABLE_ADDON'}{$settings{'REDIR_ENABLE_ADDON'}} = "checked='checked'";
+$checked{'REDIR_CUSTOM_GREEN'}{'off'} = '';
+$checked{'REDIR_CUSTOM_GREEN'}{'on'} = '';
+$checked{'REDIR_CUSTOM_GREEN'}{$settings{'REDIR_CUSTOM_GREEN'}} = "checked='checked'";
+$checked{'REDIR_CUSTOM_BLUE'}{'off'} = '';
+$checked{'REDIR_CUSTOM_BLUE'}{'on'} = '';
+$checked{'REDIR_CUSTOM_BLUE'}{$settings{'REDIR_CUSTOM_BLUE'}} = "checked='checked'";
+$checked{'REDIR_CUSTOM_ORANGE'}{'off'} = '';
+$checked{'REDIR_CUSTOM_ORANGE'}{'on'} = '';
+$checked{'REDIR_CUSTOM_ORANGE'}{$settings{'REDIR_CUSTOM_ORANGE'}} = "checked='checked'";
+$checked{'REDIR_DNS_GREEN'}{'off'} = '';
+$checked{'REDIR_DNS_GREEN'}{'on'} = '';
+$checked{'REDIR_DNS_GREEN'}{$settings{'REDIR_DNS_GREEN'}} = "checked='checked'";
+$checked{'REDIR_NTP_GREEN'}{'off'} = '';
+$checked{'REDIR_NTP_GREEN'}{'on'} = '';
+$checked{'REDIR_NTP_GREEN'}{$settings{'REDIR_NTP_GREEN'}} = "checked='checked'";
+$checked{'REDIR_DNS_BLUE'}{'off'} = '';
+$checked{'REDIR_DNS_BLUE'}{'on'} = '';
+$checked{'REDIR_DNS_BLUE'}{$settings{'REDIR_DNS_BLUE'}} = "checked='checked'";
+$checked{'REDIR_NTP_BLUE'}{'off'} = '';
+$checked{'REDIR_NTP_BLUE'}{'on'} = '';
+$checked{'REDIR_NTP_BLUE'}{$settings{'REDIR_NTP_BLUE'}} = "checked='checked'";
+$checked{'REDIR_DNS_ORANGE'}{'off'} = '';
+$checked{'REDIR_DNS_ORANGE'}{'on'} = '';
+$checked{'REDIR_DNS_ORANGE'}{$settings{'REDIR_DNS_ORANGE'}} = "checked='checked'";
+$checked{'REDIR_NTP_ORANGE'}{'off'} = '';
+$checked{'REDIR_NTP_ORANGE'}{'on'} = '';
+$checked{'REDIR_NTP_ORANGE'}{$settings{'REDIR_NTP_ORANGE'}} = "checked='checked'";
+
+$selected{'REDIR_ENTRY_INTERFACE'}{$settings{'REDIR_ENTRY_INTERFACE'}} = 'selected';
+$selected{'REDIR_ENTRY_PROTOCOL'}{$settings{'REDIR_ENTRY_PROTOCOL'}} = 'selected';
+
+&showMainBox();
+&showRedirectsBox();
+
+&Header::closebigbox();
+&Header::closepage();
+
+# Function to show main settings and options.
+sub showMainBox() {
+
+ &Header::openbox('100%', 'center', "$Lang::tr{'settings'}");
+ print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>";
+
+print <<END;
+<table width='80%' cellspacing='0' border='0'>
+ <tr><td colspan='2' class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'portredir common settings'}</b></td></tr
+ <tr>
+ <td width='25%' class='base'>$Lang::tr{'portredir enable addon'}:</td>
+ <td><input type='checkbox' name='REDIR_ENABLE_ADDON' $checked{'REDIR_ENABLE_ADDON'}{'on'} /></td>
+ </tr>
+ <tr><td colspan='2'></td></tr>
+ <tr><td colspan='2'> </td></tr>
+END
+
+ # create html table with header line 1
+ print "<table width='80%' cellspacing='0' border='0'><tr>";
+ print "<th class='base' width='40%' align='left'><b>$Lang::tr{'portredir fw for interface'}</th>";
+ if ($netsettings{'GREEN_DEV'}) {print "<th class='base' width='10%'><b><font color=green>$Lang::tr{'green'}</font></th>";
+ } else { print "<th class='base' width='10%'></font></th>"; }
+ if ($netsettings{'BLUE_DEV'}) {print "<th class='base' width='10%'><b><font color=blue>$Lang::tr{'blue'}</font></th>";
+ } else { print "<th class='base' width='10%'></font></th>"; }
+ if ($netsettings{'ORANGE_DEV'}) {print "<th class='base' width='10%'><b><font color=orange>$Lang::tr{'orange'}</font></th>";
+ } else { print "<th class='base' width='10%'></font></th>"; }
+
+ # the empty right row
+ print "<th class='base' width='30%'><td></td></th></tr>";
+
+ # line 2
+ print "<tr><td>$Lang::tr{'portredir force local dns'}</td>";
+ if ($netsettings{'GREEN_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_DNS_GREEN' $checked{'REDIR_DNS_GREEN'}{'on'}></td>";} else { print "<td></td>";}
+ if ($netsettings{'BLUE_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_DNS_BLUE' $checked{'REDIR_DNS_BLUE'}{'on'}></td>";} else { print "<td></td>";}
+ if ($netsettings{'ORANGE_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_DNS_ORANGE' $checked{'REDIR_DNS_ORANGE'}{'on'}></td>";} else { print "<td></td>";}
+
+ # line 3
+ print "</tr><tr><td>$Lang::tr{'portredir force local ntp'}</td>";
+ if ($netsettings{'GREEN_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_NTP_GREEN' $checked{'REDIR_NTP_GREEN'}{'on'}></td>";} else { print "<td></td>";}
+ if ($netsettings{'BLUE_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_NTP_BLUE' $checked{'REDIR_NTP_BLUE'}{'on'}></td>";} else { print "<td></td>";}
+ if ($netsettings{'ORANGE_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_NTP_ORANGE' $checked{'REDIR_NTP_ORANGE'}{'on'}></td>";} else { print "<td></td>";}
+
+ # line 4
+ print "</tr><tr><td>$Lang::tr{'portredir enable user redirections'}</td>";
+ if ($netsettings{'GREEN_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_CUSTOM_GREEN' $checked{'REDIR_CUSTOM_GREEN'}{'on'}></td>";} else { print "<td></td>";}
+ if ($netsettings{'BLUE_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_CUSTOM_BLUE' $checked{'REDIR_CUSTOM_BLUE'}{'on'}></td>";} else { print "<td></td>";}
+ if ($netsettings{'ORANGE_DEV'}) {print "<td class='base' align='center'><input type='checkbox' name='REDIR_CUSTOM_ORANGE' $checked{'REDIR_CUSTOM_ORANGE'}{'on'}></td>";} else { print "<td></td>";}
+
+ print <<END;
+ </tr></table>
+ <table width='80%' cellspacing='0' border='0'>
+ <tr><td colspan='2'> </td></tr>
+ <tr><td align='left'><b>$Lang::tr{'portredir save to activate'}</b></td><td width='5%' align='center'><input type='submit' name='ACTION' value=' $Lang::tr{'save'} '></td></tr>
+ </table></form>
+END
+
+&Header::closebox();
+}
+
+# Function to show elements of the redirects file and allow to add or remove single members of it.
+sub showRedirectsBox() {
+ &Header::openbox('100%', 'center', "$Lang::tr{'portredir custom redirections'}");
+
+ print <<END;
+ <table width='80%' cellspacing='1' border='0'>
+ <tr>
+ <td class='base' bgcolor='$color{'color20'}' align='center'><b>$Lang::tr{'interface'}</b></td>
+ <td class='base' bgcolor='$color{'color20'}' align='center'><b>$Lang::tr{'protocol'}</b></td>
+ <td class='base' bgcolor='$color{'color20'}' align='center'><b>$Lang::tr{'port'}</b></td>
+ <td class='base' bgcolor='$color{'color20'}' align='center'><b>$Lang::tr{'ip address'}</b></td>
+ <td class='base' bgcolor='$color{'color20'}' align='center'><b>$Lang::tr{'remark'}</b></td>
+ <td class='base' colspan='3' bgcolor='$color{'color20'}'></td>
+ </tr>
+END
+ # Check if some rules have been added to be redirects.
+ if (keys (%redirects)) {
+ my $col = "";
+
+ # List all entries of the hash.
+ foreach my $key (sort keys %redirects){
+
+ # Assign data array positions to some nice variable names.
+ my $interface = $redirects{$key}[0];
+ my $protocol = $redirects{$key}[1];
+ my $port = $redirects{$key}[2];
+ my $address = $redirects{$key}[3];
+ my $status = $redirects{$key}[4];
+ my $remark = $redirects{$key}[5];
+
+ # Check if the key (id) number is even or not.
+ if ($settings{'ID'} eq $key) {
+ $col="bgcolor='${Header::colouryellow}'";
+ } elsif ($key % 2) {
+ $col="bgcolor='$color{'color22'}'";
+ } else {
+ $col="bgcolor='$color{'color20'}'";
+ }
+
+ # Choose icon for the checkbox.
+ my $gif;
+ my $gdesc;
+
+ # Check if the status is enabled and select the correct image and description.
+ if ($status eq 'enabled' ) {
+ $gif = 'on.gif';
+ $gdesc = $Lang::tr{'click to disable'};
+ } else {
+ $gif = 'off.gif';
+ $gdesc = $Lang::tr{'click to enable'};
+ }
+
+ print <<END;
+ <tr>
+ <td width='15%' class='base' align='center' $col><b><font color=$interface>$Lang::tr{$interface}</font></b></td>
+ <td width='10%' class='base' align='center' $col>$protocol</td>
+ <td width='10%' class='base' align='center' $col>$port</td>
+ <td width='15%' class='base' align='center' $col> $address</td>
+ <td width='40%' class='base' align='center' $col> $remark</td>
+ <td align='center' $col>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
+ <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc' />
+ <input type='hidden' name='ID' value='$key' />
+ </form>
+ </td>
+ <td align='center' $col>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
+ <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
+ <input type='hidden' name='ID' value='$key' />
+ </form>
+ </td>
+ <td align='center' $col>
+ <form method='post' name='$key' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' title='$Lang::tr{'remove'}' alt='$Lang::tr{'remove'}'>
+ <input type='hidden' name='ID' value='$key'>
+ <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}'>
+ </form>
+ </td>
+ </tr>
+END
+ }
+ } else {
+ # Print notice that currently no ports are redirected.
+ print "<tr>\n";
+ print "<td class='base' colspan='2'>$Lang::tr{'portredir no entries'}</td>\n";
+ print "</tr>\n";
+ }
+
+ print "</table>\n";
+
+ # Section to add new elements or edit existing ones.
+ print <<END;
+ <br>
+ <hr>
+ <br>
+ <div align='center'>
+ <table width='100%' cellspacing='0' border='0'>
+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 should be edited.
+ if ($settings{'ID'} ne '') {
+ $buttontext = $Lang::tr{'update'};
+ print "<tr><td class='boldbase' colspan='6'><b>$Lang::tr{'update'}</b></td></tr>\n";
+
+ # Grab address and remark for the given key.
+ $entry_interface = $redirects{$settings{'ID'}}[0];
+ $entry_protocol = $redirects{$settings{'ID'}}[1];
+ $entry_port = $redirects{$settings{'ID'}}[2];
+ $entry_address = $redirects{$settings{'ID'}}[3];
+ $entry_remark = $redirects{$settings{'ID'}}[5];
+
+ } else {
+ $buttontext = $Lang::tr{'add'};
+ print "<tr><td class='boldbase' colspan='11'><b>$Lang::tr{'dnsforward add a new entry'}</b></td></tr>\n";
+ print "<tr><td> </td></tr>\n";
+ }
+
+ print <<END;
+ <tr>
+ <td class='base' width='1%' bgcolor='$color{'color22'}'></td>
+ <td class='base' width='15%' bgcolor='$color{'color22'}' align='left'><b>$Lang::tr{'interface'}</b></td>
+ <td class='base' width='10%' bgcolor='$color{'color22'}' align='left'><b>$Lang::tr{'protocol'}</b></td>
+ <td class='base' width='10%' bgcolor='$color{'color22'}' align='left'> <b>$Lang::tr{'port'}</b></td>
+ <td class='base' width='13%' bgcolor='$color{'color22'}' align='left'> <b>$Lang::tr{'ip address'}</b></td>
+ <td class='base' width='30%' bgcolor='$color{'color22'}' align='left'> <b>$Lang::tr{'remark'}</b></td>
+ <td class='base' width='15%' bgcolor='$color{'color22'}'></td>
+ <td class='base' width='1%' bgcolor='$color{'color22'}'></td>
+ </tr>
+
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ID' value='$settings{'ID'}'>
+ <tr>
+ <td class='base'></td>
+ <td><select style='width:90px;' id='interface' name='REDIR_ENTRY_INTERFACE'>
+END
+ if ($netsettings{'GREEN_DEV'}) {
+ if ($entry_interface eq "green") {
+ print "<option value='green' selected='selected' {'green'}>$Lang::tr{'green'}</option>";
+ } else { print "<option value='green' {'green'}>$Lang::tr{'green'}</option>";}
+ }
+ if ($netsettings{'BLUE_DEV'}) {
+ if ($entry_interface eq "blue") {
+ print "<option value='blue' selected='selected' {'blue'}>$Lang::tr{'blue'}</option>";
+ } else { print "<option value='blue' {'blue'}>$Lang::tr{'blue'}</option>";}
+ }
+ if ($netsettings{'ORANGE_DEV'}) {
+ if ($entry_interface eq "orange") {
+ print "<option value='orange' selected='selected' {'orange'}>$Lang::tr{'orange'}</option>";
+ } else { print "<option value='orange' {'orange'}>$Lang::tr{'orange'}</option>";}
+ }
+
+ print "</select><td><select style='width:50px;' name='REDIR_ENTRY_PROTOCOL'>";
+ if ((!$entry_protocol) || ($entry_protocol eq "tcp")) {
+ print "<option selected='selected' id='protocol' value='tcp' {'tcp'}>tcp</option>";
+ print "<option value='udp' {'udp'}>udp</option>";
+ } elsif ($entry_protocol eq "udp") {
+ print "<option value='tcp' {'tcp'}>tcp</option>";
+ print "<option selected='selected' value='udp' {'udp'}>udp</option>";
+ }
+ print <<END;
+ </select></td>
+ <td><input type='text' name='REDIR_ENTRY_PORT' value='$entry_port' size='4'></td>
+ <td><input type='text' name='REDIR_ENTRY_ADDRESS' value='$entry_address' size='14'></td>
+ <td><input type='text' name='REDIR_ENTRY_REMARK' value='$entry_remark' size='35'></td>
+ <td width='10%' align='center'><input type='submit' name='ACTION' value=' $buttontext '></td>
+ <td class='base'></td>
+ </tr>
+ </form>
+ </table>
+ </div>
+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/packages/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 <info(a)ipfire.org> #
+# #
+# 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/>. #
+# #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER = 1.0
+
+THISAPP = portredir-$(VER)
+DIR_APP = $(DIR_SRC)/$(THISAPP)
+TARGET = $(DIR_INFO)/$(THISAPP)
+PROG = portredir
+PAK_VER = 1
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+install : $(TARGET)
+
+check :
+
+download :
+
+md5 :
+
+dist:
+ @$(PAK)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+ @$(PREBUILD)
+ @rm -rf $(DIR_APP) && cd $(DIR_SRC)
+
+ #install cgi
+ install -v -m 755 $(DIR_CONF)/portredir/portredir.cgi /srv/web/ipfire/cgi-bin/
+
+ #create configuration dir
+ -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/backup/addons/includes/portredir
+
+ # Install menu file
+ install -v -m 644 $(DIR_CONF)/portredir/EX-portredir.menu /var/ipfire/menu.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
}
buildinstaller() {
diff --git a/src/initscripts/packages/portredir b/src/initscripts/packages/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
+# port redirection rules
+#
+########################################################################
+
+. /etc/sysconfig/rc
+. ${rc_functions}
+
+IPT="/sbin/iptables";
+parent_chain="PREROUTING";
+chain="PORT_REDIRECT";
+
+confdir="/var/ipfire/portredir";
+settingsfile="${confdir}/settings";
+redirectsfile="${confdir}/redirects";
+SYSLOG="NO";
+VERBOSE="NO";
+
+eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings);
+eval $(/usr/local/bin/readhash ${settingsfile});
+
+logtext() {
+ if [ "${SYSLOG}" = "YES" ]; then logger -t "portredir" ${1}; fi;
+ if [ "${VERBOSE}" = "YES" ]; then echo ${1}; fi;}
+
+create_chain() {
+
+ local line=$(${IPT} -t nat -L ${parent_chain} --line-numbers |grep "SQUID" |awk '{printf($1)}');
+
+ if [[ "${REDIR_ENABLE_ADDON}" == "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 position ${line}...";
+ ${IPT} -t nat -I ${parent_chain} ${line} -j ${chain};
+ else
+ logtext "create chain ${chain} and link in ${parent_chain} at last position...";
+ ${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() {
+
+ local array=();
+ local redirects=();
+ local i;
+ index=();
+ iface=();
+ protocol=();
+ port=();
+ targetip=();
+ enabled=();
+
+ IFS=$'\n' read -d '' -ra redirects < ${redirectsfile};
+
+ for i in "${!redirects[@]}"
+ do
+ IFS=$',' read -ra array <<< ${redirects[i]};
+ index[i]=${array[0]};
+ iface[i]=${array[1]};
+ protocol[i]=${array[2]};
+ port[i]=${array[3]};
+ targetip[i]=${array[4]};
+ enabled[i]=${array[5]};
+ done
+
+ for i in "${!index[@]}"
+ do
+ if [[ ! -z "${GREEN_DEV}" && "${iface[i]}" = "green" && "${enabled[i]}" = "enabled" ]]; then
+
+ logtext "add redirect in ${chain} on ${GREEN_DEV} ip ${targetip[i]} protocol ${protocol[i]} port ${port[i]} ";
+ ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d ${targetip[i]} -p ${protocol[i]} -m ${protocol[i]} --dport ${port[i]} -j RETURN;
+ ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p ${protocol[i]} -m ${protocol[i]} --dport ${port[i]} -j REDIRECT;
+ fi
+ if [[ ! -z "${BLUE_DEV}" && "${iface[i]}" = "blue" && "${enabled[i]}" = "enabled" ]]; then
+ logtext "add redirect in ${chain} on ${BLUE_DEV} ip ${targetip[i]} protocol ${protocol[i]} port ${port[i]} ";
+ ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d ${targetip[i]} -p ${protocol[i]} -m ${protocol[i]} --dport ${port[i]} -j RETURN;
+ ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p ${protocol[i]} -m ${protocol[i]} --dport ${port[i]} -j REDIRECT;
+ fi
+ if [[ ! -z "${ORANGE_DEV}" && "${iface[i]}" = "orange" && "${enabled[i]}" = "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 ${protocol[i]} -m ${protocol[i]} --dport ${port[i]} -j RETURN;
+ ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p ${protocol[i]} -m ${protocol[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;
+
+ # Force DNS REDIRECTs on GREEN (udp, tcp, 53)
+ if [[ "${REDIR_DNS_GREEN}" == "on" && "${REDIR_CUSTOM_GREEN}" = "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}" == "on" && "${REDIR_CUSTOM_BLUE}" = "off" ]]; 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}" == "on" && "${REDIR_CUSTOM_ORANGE}" = "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 domain -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 domain -j REDIRECT
+ fi
+
+ # Force NTP REDIRECTs on GREEN (udp, 123)
+ if [[ "${REDIR_NTP_GREEN}" == "on" && "${REDIR_CUSTOM_GREEN}" = "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}" == "on" && "${REDIR_CUSTOM_BLUE}" = "off" ]]; 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}" == "on" && "${REDIR_CUSTOM_ORANGE}" = "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)
+ 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 = 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 portredirctrl \
getconntracktable wirelessclient torctrl ddnsctrl unboundctrl \
captivectrl
diff --git a/src/misc-progs/portredirctrl.c b/src/misc-progs/portredirctrl.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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#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") == 0) {
+ safe_system("/etc/rc.d/init.d/portredir start");
+ } else if (strcmp(argv[1], "stop") == 0) {
+ safe_system("/etc/rc.d/init.d/portredir stop");
+ } else if (strcmp(argv[1], "restart") == 0) {
+ safe_system("/etc/rc.d/init.d/portredir restart");
+ } else if (strcmp(argv[1], "enable") == 0) {
+ safe_system("touch /var/ipfire/portredir/enable");
+ safe_system("ln -snf /etc/rc.d/init.d/portredir /etc/rc.d/rc3.d/S23portredir >/dev/null 2>&1");
+ safe_system("ln -snf /etc/rc.d/init.d/portredir /etc/rc.d/rc0.d/K77portredir >/dev/null 2>&1");
+ safe_system("ln -snf /etc/rc.d/init.d/portredir /etc/rc.d/rc6.d/K77portredir >/dev/null 2>&1");
+ } else if (strcmp(argv[1], "disable") == 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 USA #
+# #
+# Copyright (C) 2021 IPFire-Team <info(a)ipfire.org>. #
+# #
+############################################################################
+#
+. /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/uninstall.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 USA #
+# #
+# Copyright (C) 2007 IPFire-Team <info(a)ipfire.org>. #
+# #
+############################################################################
+#
+. /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 USA #
+# #
+# Copyright (C) 2007 IPFire-Team <info(a)ipfire.org>. #
+# #
+############################################################################
+#
+. /opt/pakfire/lib/functions.sh
+./uninstall.sh
+./install.sh
--
2.18.0
next reply other threads:[~2021-06-27 13:48 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-27 13:48 Matthias Fischer [this message]
2021-06-28 16:04 ` Michael Tremer
[not found] <305D680D-4D10-4D99-9F1D-3589BDF08FA9@gmail.com>
2021-06-28 17:56 ` Michael Tremer
[not found] <A699ABA7-74D3-4551-A981-E2E3A0935F8E@gmail.com>
2021-07-01 8:08 ` Michael Tremer
[not found] <ADA23788-C972-417C-8F55-DD9D3B335BE9@gmail.com>
2021-07-01 15:24 ` Michael Tremer
[not found] <E41194E1-4002-4960-BF73-F57D6BCCD152@gmail.com>
2021-07-05 12:07 ` Stefan Schantl
[not found] <6EBF1B5C-79B2-4258-B117-C2A4EB16CCFD@gmail.com>
2021-07-05 12:08 ` Stefan Schantl
[not found] <CD95E831-4AE9-40B7-BB91-27B3F3164270@gmail.com>
2021-08-05 20:33 ` Michael Tremer
2021-08-06 15:57 ` Stefan Schantl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210627134819.2088-1-matthias.fischer@ipfire.org \
--to=matthias.fischer@ipfire.org \
--cc=development@lists.ipfire.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox