From patchwork Wed Apr 6 13:39:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo-Andres Hofmann X-Patchwork-Id: 5450 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4KYQcK3fqWz3x1x for ; Wed, 6 Apr 2022 13:40:01 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4KYQcG564Lz4Mc; Wed, 6 Apr 2022 13:39:58 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4KYQcG33f2z3019; Wed, 6 Apr 2022 13:39:58 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4KYQcD6H72z2xks for ; Wed, 6 Apr 2022 13:39:56 +0000 (UTC) Received: from arche.uberspace.de (arche.uberspace.de [185.26.156.147]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 4KYQc73TFxzZ5 for ; Wed, 6 Apr 2022 13:39:51 +0000 (UTC) Received: (qmail 17641 invoked by uid 990); 6 Apr 2022 13:39:50 -0000 From: Leo-Andres Hofmann To: development@lists.ipfire.org Subject: [PATCH 1/2] manualpages: Add path and file extension to the configuration Date: Wed, 6 Apr 2022 15:39:39 +0200 Message-Id: <20220406133940.803-1-hofmann@leo-andres.de> X-Mailer: git-send-email 2.27.0.windows.1 MIME-Version: 1.0 X-Rspamd-Bar: - X-Rspamd-Report: R_MISSING_CHARSET(0.5) MIME_GOOD(-0.1) MID_CONTAINS_FROM(1) BAYES_HAM(-3) X-Rspamd-Score: -1.6 Received: from unknown (HELO unkown) (::1) by arche.uberspace.de (Haraka/2.8.28) with ESMTPSA; Wed, 06 Apr 2022 15:39:50 +0200 ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1649252391; a=rsa-sha256; cv=none; b=oZfnsaNG+f8vCYPQYPXbmbULvwMzD5+VkICeSJaT4QtkjCf2vOUjKUhvLqPAZEwL+F7Ytf r/1CEQ5016agZsJaemC0lehap0ZNQ0po4Gov8/EhKFArSw0m54z3WG2HDhmaHT5xWJ97CX k+s0p+Rcaqw+tZAZ0KG8f1nYNhn+J/Kw6+Qo+LoqzB3KS6GFH3wQ5XfsL/riW3RFhymvnP w36nDIJ+KDuWABswFyBLHnD+EYE4ff0hh68xsL2k89KcaClgBnuuSCxXssqS1FAlDSwK+j QbD5kMVFpm9FLU65Ol9T1HQP0aLcrsUO68yr/Z82ouptrp2Sshypi39o/qUarA== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=pass (policy=quarantine) header.from=leo-andres.de; spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1649252391; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=zRhjJ1MMLGheLTQFmS/NdAlJj2zg2v3sESX6Oj2rmFw=; b=Sh0NDynmFJ0tlMk47u+t3v+laZp6zOIFli/bf1Onq0QNJGjsVPq+Rs3Sxh0csDJ0Ttt5x0 ic64XJLabx4/XG0H1gIq46I74nNCh8k6BXP6munvZZ/VYN+ya3CxCJMmCkhLTpdPALqKUK wizaQm7/M5OQpFoTHFTcvvvIG2GnlldjABt4HnIFBvH8vcBK6BvN8HpXaVAi8TehIymeBE nVmn41CQPMwQIa3U8Jz4Sa3OO/W+42WVsz2RGqbh6twTRWk+C7BJ9/wU0J1gKNjKXuZTZu 9usa2T7BDiXepfVX8AXk8E9w7EiO91/5uCcvjl8nayI0Ow3AQ+phFTOgcEoZCQ== X-Rspamd-Queue-Id: 4KYQc73TFxzZ5 X-Rspamd-Server: mail01.haj.ipfire.org X-Spamd-Result: default: False [1.37 / 11.00]; BAYES_SPAM(2.01)[89.03%]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.98)[-0.984]; SPF_REPUTATION_HAM(-0.85)[-0.85424015529544]; DMARC_POLICY_ALLOW(-0.50)[leo-andres.de,quarantine]; MX_INVALID(0.50)[]; R_MISSING_CHARSET(0.50)[]; R_SPF_ALLOW(-0.20)[+mx]; MIME_GOOD(-0.10)[text/plain]; IP_REPUTATION_HAM(-0.01)[asn: 205766(0.00), country: DE(-0.01), ip: 185.26.156.147(0.00)]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCVD_IN_DNSWL_NONE(0.00)[185.26.156.147:from]; RCPT_COUNT_ONE(0.00)[1]; FROM_HAS_DN(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:205766, ipnet:185.26.156.0/24, country:DE]; ARC_SIGNED(0.00)[lists.ipfire.org:s=202003rsa:i=1]; TO_DN_NONE(0.00)[]; ARC_NA(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; R_DKIM_NA(0.00)[]; RCVD_TLS_ALL(0.00)[] Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=pass (policy=quarantine) header.from=leo-andres.de; spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" 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 --- 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 <$Lang::tr{'online help en'} 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) {