This allows to correctly assign an URL to a file without relying on unique base names. A custom read function is required because General::readhash() doesn't allow paths as hash keys. Modifying the existing functions could affect other CGIs and was therefore dismissed.
Fixes: #12806
Signed-off-by: Leo-Andres Hofmann hofmann@leo-andres.de --- config/cfgroot/header.pl | 33 ++++- config/cfgroot/manualpages | 144 +++++++++---------- html/html/themes/ipfire/include/functions.pl | 4 +- tools/check_manualpages.pl | 17 +-- 4 files changed, 110 insertions(+), 88 deletions(-)
diff --git a/config/cfgroot/header.pl b/config/cfgroot/header.pl index e97f90d67..e6d2b7c78 100644 --- a/config/cfgroot/header.pl +++ b/config/cfgroot/header.pl @@ -93,7 +93,7 @@ if ( -d "/var/ipfire/langs/${language}/" ) {
### Initialize user manual my %manualpages = (); -&General::readhash("${General::swroot}/main/manualpages", %manualpages); +&_read_manualpage_hash("${General::swroot}/main/manualpages");
### Load selected language and theme functions require "${swroot}/langs/en.pl"; @@ -558,18 +558,41 @@ sub colorize { } }
-# Get user manual URL for the specified configuration page, returns empty if no entry is configured +# Get user manual URL for a configuration page inside the "/cgi-bin/" +# (reads current page from the environment variables unless defined) +# Returns empty if no URL is available sub get_manualpage_url() { - my ($cgi_page) = @_; + my ($cgifile) = @_; + $cgifile //= substr($ENV{'SCRIPT_NAME'}, 9); # remove fixed "/cgi-bin/" path
# Ensure base url is configured return unless($manualpages{'BASE_URL'});
# Return URL - if($cgi_page && defined($manualpages{$cgi_page})) { - return "$manualpages{'BASE_URL'}/$manualpages{$cgi_page}"; + if($cgifile && defined($manualpages{$cgifile})) { + return "$manualpages{'BASE_URL'}/$manualpages{$cgifile}"; }
# No manual page configured, return nothing return; } + +# Private function to load a hash of configured user manual pages from file +# (run check_manualpages.pl to make sure the file is correct) +sub _read_manualpage_hash() { + my ($filename) = @_; + + open(my $file, "<", $filename) or return; # Fail silent + while(my $line = <$file>) { + chomp($line); + next if(substr($line, 0, 1) eq '#'); # Skip comments + next if(index($line, '=', 1) == -1); # Skip incomplete lines + + my($left, $value) = split(/=/, $line, 2); + if($left =~ /^([[:alnum:]/._-]+)$/) { + my $key = $1; + $manualpages{$key} = $value; + } + } + close($file); +} diff --git a/config/cfgroot/manualpages b/config/cfgroot/manualpages index 6c2e54b55..b92a81b56 100644 --- a/config/cfgroot/manualpages +++ b/config/cfgroot/manualpages @@ -1,88 +1,88 @@ -# Assign manual page URL path to CGI file ([cgi basename]=[path/to/page]) +# Assign manual page URL path to CGI file ([cgi file]=[path/to/page]) +# The CGI files are referenced relative to the "/cgi-bin/" path
-# Base URL (without trailing slash) +# Fixed base URL (without trailing slash) BASE_URL=https://wiki.ipfire.org -index=configuration/system/startpage
# System menu -index=configuration/system/startpage -mail=configuration/system/mail_service -remote=configuration/system/ssh -backup=configuration/system/backup -gui=configuration/system/userinterface -fireinfo=fireinfo -vulnerabilities=configuration/system/vulnerabilities -shutdown=configuration/system/shutdown -credits=configuration/system/credits +index.cgi=configuration/system/startpage +mail.cgi=configuration/system/mail_service +remote.cgi=configuration/system/ssh +backup.cgi=configuration/system/backup +gui.cgi=configuration/system/userinterface +fireinfo.cgi=fireinfo +vulnerabilities.cgi=configuration/system/vulnerabilities +shutdown.cgi=configuration/system/shutdown +credits.cgi=configuration/system/credits
# Status menu -system=configuration/status/system -memory=configuration/status/memory -services=configuration/status/services -media=configuration/status/drives -netexternal=configuration/status/network_ext -netinternal=configuration/status/network_int -netother=configuration/status/network_int -netovpnrw=configuration/status/network_ovpnrw -#netovpnsrv= -wio=addons/wio -hardwaregraphs=configuration/status/hardware_diagrams -entropy=configuration/status/entropy -connections=configuration/status/connections -traffic=configuration/status/nettraffic -#mdstat= +system.cgi=configuration/status/system +memory.cgi=configuration/status/memory +services.cgi=configuration/status/services +media.cgi=configuration/status/drives +netexternal.cgi=configuration/status/network_ext +netinternal.cgi=configuration/status/network_int +netother.cgi=configuration/status/network_int +netovpnrw.cgi=configuration/status/network_ovpnrw +#netovpnsrv.cgi= +wio.cgi=addons/wio +hardwaregraphs.cgi=configuration/status/hardware_diagrams +entropy.cgi=configuration/status/entropy +connections.cgi=configuration/status/connections +traffic.cgi=configuration/status/nettraffic +#mdstat.cgi=
# Network menu -zoneconf=configuration/network/zoneconf -dns=dns -proxy=configuration/network/proxy -urlfilter=configuration/network/proxy/url-filter -#updatexlrator=configuration/network/proxy/update_accelerator -dhcp=configuration/network/dhcp -captive=configuration/network/captive -connscheduler=configuration/network/connectionscheduler -hosts=configuration/network/hosts -dnsforward=configuration/network/dnsforward -routing=configuration/network/static -mac=configuration/network/mac-address -wakeonlan=configuration/network/wake-on-lan +zoneconf.cgi=configuration/network/zoneconf +dns.cgi=dns +proxy.cgi=configuration/network/proxy +urlfilter.cgi=configuration/network/proxy/url-filter +#updatexlrator.cgi=configuration/network/proxy/update_accelerator +dhcp.cgi=configuration/network/dhcp +captive.cgi=configuration/network/captive +connscheduler.cgi=configuration/network/connectionscheduler +hosts.cgi=configuration/network/hosts +dnsforward.cgi=configuration/network/dnsforward +routing.cgi=configuration/network/static +mac.cgi=configuration/network/mac-address +wakeonlan.cgi=configuration/network/wake-on-lan
# Services menu -vpnmain=configuration/services/ipsec -ovpnmain=configuration/services/openvpn -ddns=configuration/services/dyndns -time=configuration/services/ntp -qos=configuration/services/qos -guardian=addons/guardian -extrahd=configuration/services/extrahd +vpnmain.cgi=configuration/services/ipsec +ovpnmain.cgi=configuration/services/openvpn +ddns.cgi=configuration/services/dyndns +time.cgi=configuration/services/ntp +qos.cgi=configuration/services/qos +guardian.cgi=addons/guardian +extrahd.cgi=configuration/services/extrahd
# Firewall menu -firewall=configuration/firewall -fwhosts=configuration/firewall/fwgroups -optionsfw=configuration/firewall/options -ids=configuration/firewall/ips -location-block=configuration/firewall/geoip-block -wireless=configuration/firewall/accesstoblue -iptables=configuration/firewall/iptables +firewall.cgi=configuration/firewall +fwhosts.cgi=configuration/firewall/fwgroups +optionsfw.cgi=configuration/firewall/options +ids.cgi=configuration/firewall/ips +location-block.cgi=configuration/firewall/geoip-block +wireless.cgi=configuration/firewall/accesstoblue +iptables.cgi=configuration/firewall/iptables
# IPfire menu -pakfire=configuration/ipfire/pakfire -wlanap=addons/wireless -tor=addons/tor -mpfire=addons/mpfire -samba=addons/samba +pakfire.cgi=configuration/ipfire/pakfire +wlanap.cgi=addons/wireless +tor.cgi=addons/tor +mpfire.cgi=addons/mpfire +samba.cgi=addons/samba
# Logs menu -summary=configuration/logs/summary -config=configuration/logs/logsettings -proxylog=configuration/logs/proxy -calamaris=configuration/logs/proxyreports -accounting=addons/squid-accounting -firewalllog=configuration/logs/firewall -firewalllogip=configuration/logs/firewall-ip -firewalllogport=configuration/logs/firewall-port -firewalllogcountry=configuration/logs/firewall-country -ids=configuration/logs/ips -#ovpnclients= -urlfilter=configuration/logs/url-filter -log=configuration/logs/system +logs.cgi/summary.dat=configuration/logs/summary +logs.cgi/config.dat=configuration/logs/logsettings +logs.cgi/proxylog.dat=configuration/logs/proxy +logs.cgi/calamaris.dat=configuration/logs/proxyreports +logs.cgi/accounting.dat=addons/squid-accounting +logs.cgi/firewalllog.dat=configuration/logs/firewall +logs.cgi/firewalllogip.dat=configuration/logs/firewall-ip +logs.cgi/firewalllogport.dat=configuration/logs/firewall-port +logs.cgi/firewalllogcountry.dat=configuration/logs/firewall-country +logs.cgi/ids.dat=configuration/logs/ips +#logs.cgi/ovpnclients.dat= +logs.cgi/urlfilter.dat=configuration/logs/url-filter +logs.cgi/log.dat=configuration/logs/system diff --git a/html/html/themes/ipfire/include/functions.pl b/html/html/themes/ipfire/include/functions.pl index d74c962e4..40afb3ce3 100644 --- a/html/html/themes/ipfire/include/functions.pl +++ b/html/html/themes/ipfire/include/functions.pl @@ -102,8 +102,6 @@ sub openpage { my $boh = shift; my $extrahead = shift; my $suppressMenu = shift; - my @tmp = split(/./, basename($0)); - my $scriptName = @tmp[0];
@URI=split ('?', $ENV{'REQUEST_URI'} ); &General::readhash("${swroot}/main/settings", %settings); @@ -176,7 +174,7 @@ END ;
# Print user manual link -my $manual_url = &Header::get_manualpage_url($scriptName); +my $manual_url = &Header::get_manualpage_url(); if($manual_url) { print <<END <span><a href="$manual_url" title="$Lang::tr{'online help en'}" target="_blank"><img src="/images/help-browser.png" alt="$Lang::tr{'online help en'}"></a></span> diff --git a/tools/check_manualpages.pl b/tools/check_manualpages.pl index 75a560560..446e94649 100644 --- a/tools/check_manualpages.pl +++ b/tools/check_manualpages.pl @@ -25,18 +25,19 @@ use strict; # Import make.sh environment my $basedir = $ENV{'BASEDIR'};
-# Load configuration file (General::readhash isn't available yet) +# Load configuration file (Header::_read_manualpage_hash() isn't available yet) my $configfile = "${basedir}/config/cfgroot/manualpages"; my %manualpages = ();
open(my $file, "<", $configfile) or die "ERROR: Can't read from file '$configfile'!\n"; while(my $line = <$file>) { - $line =~ s/\R//g; - next unless($line =~ /=/); + chomp($line); + next if(substr($line, 0, 1) eq '#'); # Skip comments + next if(index($line, '=', 1) == -1); # Skip incomplete lines
my($left, $value) = split(/=/, $line, 2); - if($left =~ /(^[A-Za-z0-9_-]+$)/) { - my $key = $1; # Got alphanumeric key + if($left =~ /^([[:alnum:]/._-]+)$/) { + my $key = $1; $manualpages{$key} = $value; } } @@ -55,11 +56,11 @@ if ($baseurl =~ //\s*$/) {
# Loop trough configured manual pages foreach my $page (keys %manualpages) { - # Build absolute path and URL - my $cgifile = "${basedir}/html/cgi-bin/${page}.cgi"; + # Build absolute path (inside cgi-bin) and URL + my $cgifile = "${basedir}/html/cgi-bin/${page}"; my $url = "${baseurl}/$manualpages{$page}";
- print "${page}.cgi -> '$url'\n"; + print "cgi-bin/${page} -> '$url'\n";
# Check CGI file exists if(! -f $cgifile) {
This patch adds default values and removes a missing translation to fix "uninitialized value" and "odd number of elements" warnings.
Removes function calls from functions.pl that have already been handled by the header before it is loaded by eval().
Signed-off-by: Leo-Andres Hofmann hofmann@leo-andres.de --- config/cfgroot/header.pl | 4 +++- config/menu/20-status.menu | 4 ++-- config/menu/30-network.menu | 2 +- html/html/themes/ipfire/include/functions.pl | 14 ++++---------- langs/de/cgi-bin/de.pl | 1 - langs/fr/cgi-bin/fr.pl | 1 - 6 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/config/cfgroot/header.pl b/config/cfgroot/header.pl index e6d2b7c78..92e454dd1 100644 --- a/config/cfgroot/header.pl +++ b/config/cfgroot/header.pl @@ -46,7 +46,7 @@ my $menu = %menuhash; %settings = (); %ethsettings = (); %pppsettings = (); -@URI = (); +my @URI = split('?', $ENV{'REQUEST_URI'});
### Make sure this is an SSL request if ($ENV{'SERVER_ADDR'} && $ENV{'HTTPS'} ne 'on') { @@ -596,3 +596,5 @@ sub _read_manualpage_hash() { } close($file); } + +1; # End of package "Header" diff --git a/config/menu/20-status.menu b/config/menu/20-status.menu index 2bcf0d5e8..6ab68ec8c 100644 --- a/config/menu/20-status.menu +++ b/config/menu/20-status.menu @@ -49,7 +49,7 @@ $substatus->{'54.networkovpnsrv'} = { 'caption' => "$Lang::tr{'vpn statistic n2n'}", 'uri' => '/cgi-bin/netovpnsrv.cgi', - 'title' => "$Lang::tr{'vpn statistics n2n'}", + 'title' => "$Lang::tr{'vpn statistic n2n'}", 'enabled' => 1, }; $substatus->{'60.hardwaregraphs'} = { @@ -90,7 +90,7 @@ $substatus->{'75.atm-status'} = {'caption' => 'Atm-status', 'uri' => '/cgi-bin/atm-status.cgi', 'title' => 'Atm-status', - 'enabled' => `find /sys/class/atm/*/device 2>/dev/null`, + 'enabled' => `find /sys/class/atm/*/device 2>/dev/null` // 0, }; $substatus->{'76.mdstat'} = {'caption' => 'Mdstat', 'uri' => '/cgi-bin/mdstat.cgi', diff --git a/config/menu/30-network.menu b/config/menu/30-network.menu index 19571a870..faef89a41 100644 --- a/config/menu/30-network.menu +++ b/config/menu/30-network.menu @@ -67,7 +67,7 @@ 'caption' => $Lang::tr{'aliases'}, 'uri' => '/cgi-bin/aliases.cgi', 'title' => "$Lang::tr{'aliases'}", - 'enabled' => `grep "RED_TYPE=STATIC" /var/ipfire/ethernet/settings`, + 'enabled' => `grep "RED_TYPE=STATIC" /var/ipfire/ethernet/settings` // 0, }; $subnetwork->{'80.macadressmenu'} = { 'caption' => $Lang::tr{'mac address menu'}, diff --git a/html/html/themes/ipfire/include/functions.pl b/html/html/themes/ipfire/include/functions.pl index 40afb3ce3..5a9ddbf88 100644 --- a/html/html/themes/ipfire/include/functions.pl +++ b/html/html/themes/ipfire/include/functions.pl @@ -31,8 +31,6 @@ # IPFire default theme. # ###############################################################################
-require "${General::swroot}/lang.pl"; - ############################################################################### # # print menu html elements for submenu entries @@ -103,16 +101,11 @@ sub openpage { my $extrahead = shift; my $suppressMenu = shift;
- @URI=split ('?', $ENV{'REQUEST_URI'} ); - &General::readhash("${swroot}/main/settings", %settings); - &genmenu(); - my $headline = "IPFire"; if (($settings{'WINDOWWITHHOSTNAME'} eq 'on') || ($settings{'WINDOWWITHHOSTNAME'} eq '')) { $headline = "$settings{'HOSTNAME'}.$settings{'DOMAINNAME'}"; }
- print <<END; <!DOCTYPE html> <html> @@ -163,7 +156,10 @@ print <<END END ;
-&showmenu() if ($suppressMenu != 1); +unless($suppressMenu) { + &genmenu(); + &showmenu(); +}
print <<END <div class="bigbox fixed"> @@ -268,5 +264,3 @@ sub openbox { sub closebox { print "</div>"; } - -1; diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index 0be097609..ab9e0d52e 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -2880,7 +2880,6 @@ 'vpn start action start' => 'Immer An', 'vpn statistic n2n' => 'OpenVPN: Netz-zu-Netz-Statistik', 'vpn statistic rw' => 'OpenVPN: Roadwarrior-Statistik', -'vpn statistics n2n' => 'OpenVPN: Netz-zu-Netz-Statistiken', 'vpn subjectaltname' => 'SubjectAlternativeName', 'vpn subjectaltname missing' => 'SubjectAlternativeName darf nicht leer bleiben.', 'vpn wait' => 'WARTE', diff --git a/langs/fr/cgi-bin/fr.pl b/langs/fr/cgi-bin/fr.pl index 60ea0dcc5..74184a416 100644 --- a/langs/fr/cgi-bin/fr.pl +++ b/langs/fr/cgi-bin/fr.pl @@ -2956,7 +2956,6 @@ 'vpn start action start' => 'Toujours démarré', 'vpn statistic n2n' => 'OpenVPN (site-à-site)', 'vpn statistic rw' => 'OpenVPN (client nomade)', -'vpn statistics n2n' => 'OpenVPN (site-à-site)', 'vpn subjectaltname' => 'Nom de l'objet', 'vpn subjectaltname missing' => 'Le nom de l'objet ne peut être vide.', 'vpn wait' => 'ATTENTE',
Hi,
looking at this patch again, I'm unhappy with the default value operator. The "enabled" field is only numeric everywhere else. So I should prevent the grep output from ending up in this field, altough it would be accepted as a "truthy" value.
I'll send a better patch. Sorry for the noise!
Best regards Leo
Am 06.04.2022 um 15:39 schrieb Leo-Andres Hofmann:
This patch adds default values and removes a missing translation to fix "uninitialized value" and "odd number of elements" warnings.
Removes function calls from functions.pl that have already been handled by the header before it is loaded by eval().
Signed-off-by: Leo-Andres Hofmannhofmann@leo-andres.de
config/cfgroot/header.pl | 4 +++- config/menu/20-status.menu | 4 ++-- config/menu/30-network.menu | 2 +- html/html/themes/ipfire/include/functions.pl | 14 ++++---------- langs/de/cgi-bin/de.pl | 1 - langs/fr/cgi-bin/fr.pl | 1 - 6 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/config/cfgroot/header.pl b/config/cfgroot/header.pl index e6d2b7c78..92e454dd1 100644 --- a/config/cfgroot/header.pl +++ b/config/cfgroot/header.pl @@ -46,7 +46,7 @@ my $menu = %menuhash; %settings = (); %ethsettings = (); %pppsettings = (); -@URI = (); +my @URI = split('?', $ENV{'REQUEST_URI'});
### Make sure this is an SSL request if ($ENV{'SERVER_ADDR'} && $ENV{'HTTPS'} ne 'on') { @@ -596,3 +596,5 @@ sub _read_manualpage_hash() { } close($file); }
+1; # End of package "Header" diff --git a/config/menu/20-status.menu b/config/menu/20-status.menu index 2bcf0d5e8..6ab68ec8c 100644 --- a/config/menu/20-status.menu +++ b/config/menu/20-status.menu @@ -49,7 +49,7 @@ $substatus->{'54.networkovpnsrv'} = { 'caption' => "$Lang::tr{'vpn statistic n2n'}", 'uri' => '/cgi-bin/netovpnsrv.cgi',
'title' => "$Lang::tr{'vpn statistics n2n'}",
$substatus->{'60.hardwaregraphs'} = {'title' => "$Lang::tr{'vpn statistic n2n'}", 'enabled' => 1, };
@@ -90,7 +90,7 @@ $substatus->{'75.atm-status'} = {'caption' => 'Atm-status', 'uri' => '/cgi-bin/atm-status.cgi', 'title' => 'Atm-status',
'enabled' => `find /sys/class/atm/*/device 2>/dev/null`,
$substatus->{'76.mdstat'} = {'caption' => 'Mdstat', 'uri' => '/cgi-bin/mdstat.cgi','enabled' => `find /sys/class/atm/*/device 2>/dev/null` // 0, };
diff --git a/config/menu/30-network.menu b/config/menu/30-network.menu index 19571a870..faef89a41 100644 --- a/config/menu/30-network.menu +++ b/config/menu/30-network.menu @@ -67,7 +67,7 @@ 'caption' => $Lang::tr{'aliases'}, 'uri' => '/cgi-bin/aliases.cgi', 'title' => "$Lang::tr{'aliases'}",
'enabled' => `grep "RED_TYPE=STATIC" /var/ipfire/ethernet/settings`,
$subnetwork->{'80.macadressmenu'} = { 'caption' => $Lang::tr{'mac address menu'},'enabled' => `grep "RED_TYPE=STATIC" /var/ipfire/ethernet/settings` // 0, };
diff --git a/html/html/themes/ipfire/include/functions.pl b/html/html/themes/ipfire/include/functions.pl index 40afb3ce3..5a9ddbf88 100644 --- a/html/html/themes/ipfire/include/functions.pl +++ b/html/html/themes/ipfire/include/functions.pl @@ -31,8 +31,6 @@ # IPFire default theme. # ###############################################################################
-require "${General::swroot}/lang.pl";
- ############################################################################### # # print menu html elements for submenu entries
@@ -103,16 +101,11 @@ sub openpage { my $extrahead = shift; my $suppressMenu = shift;
@URI=split ('?', $ENV{'REQUEST_URI'} );
&General::readhash("${swroot}/main/settings", %settings);
&genmenu();
my $headline = "IPFire"; if (($settings{'WINDOWWITHHOSTNAME'} eq 'on') || ($settings{'WINDOWWITHHOSTNAME'} eq '')) { $headline = "$settings{'HOSTNAME'}.$settings{'DOMAINNAME'}"; }
print <<END;
<!DOCTYPE html>
<html>
@@ -163,7 +156,10 @@ print <<END END ;
-&showmenu() if ($suppressMenu != 1); +unless($suppressMenu) {
- &genmenu();
- &showmenu();
+}
print <<END
<div class="bigbox fixed"> @@ -268,5 +264,3 @@ sub openbox { sub closebox { print "</div>"; } - -1; diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index 0be097609..ab9e0d52e 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -2880,7 +2880,6 @@ 'vpn start action start' => 'Immer An', 'vpn statistic n2n' => 'OpenVPN: Netz-zu-Netz-Statistik', 'vpn statistic rw' => 'OpenVPN: Roadwarrior-Statistik', -'vpn statistics n2n' => 'OpenVPN: Netz-zu-Netz-Statistiken', 'vpn subjectaltname' => 'SubjectAlternativeName', 'vpn subjectaltname missing' => 'SubjectAlternativeName darf nicht leer bleiben.', 'vpn wait' => 'WARTE', diff --git a/langs/fr/cgi-bin/fr.pl b/langs/fr/cgi-bin/fr.pl index 60ea0dcc5..74184a416 100644 --- a/langs/fr/cgi-bin/fr.pl +++ b/langs/fr/cgi-bin/fr.pl @@ -2956,7 +2956,6 @@ 'vpn start action start' => 'Toujours démarré', 'vpn statistic n2n' => 'OpenVPN (site-à-site)', 'vpn statistic rw' => 'OpenVPN (client nomade)', -'vpn statistics n2n' => 'OpenVPN (site-à-site)', 'vpn subjectaltname' => 'Nom de l\'objet', 'vpn subjectaltname missing' => 'Le nom de l\'objet ne peut être vide.', 'vpn wait' => 'ATTENTE',