Execute pihole through wrapper

All different exec() calls basically just calls sudo pihole,
with various different syntaxes. Using a wrapper function
allows sanitization of arguments for better safety.

Signed-off-by: Samu Voutilainen <smar@smar.fi>
This commit is contained in:
Samu Voutilainen
2020-01-25 11:19:23 +02:00
parent ae13014565
commit 39ec67829b
8 changed files with 99 additions and 47 deletions

View File

@@ -86,7 +86,8 @@ switch($list) {
// Reload lists in pihole-FTL after having added something
if ($reload) {
echo shell_exec("sudo pihole restartdns reload-lists");
$output = pihole_execute("restartdns reload-lists");
echo implode("\n", $output);
}
?>

View File

@@ -81,7 +81,7 @@
if (get_ip_type($entry->ip) == $ipType)
return errorJsonResponse("This domain already has a custom DNS entry for an IPv" . $ipType);
exec("sudo pihole -a addcustomdns ".$ip." ".$domain);
pihole_execute("-a addcustomdns ".$ip." ".$domain);
return successJsonResponse();
}
@@ -117,7 +117,7 @@
if (!$found)
return errorJsonResponse("This domain/ip association does not exist");
exec("sudo pihole -a removecustomdns ".$ip." ".$domain);
pihole_execute("-a removecustomdns ".$ip." ".$domain);
return successJsonResponse();
}

View File

@@ -52,4 +52,33 @@ if(!function_exists('hash_equals')) {
}
}
/**
* More safely execute a command with pihole shell script.
*
* For example,
*
* pihole_execute("-h");
*
* would execute command
*
* sudo pihole -h
*
* and returns output of that command as a string.
*
* @param $argument_string String of arguments to run pihole with.
* @param $error_on_failure If true, a warning is raised if command execution fails. Defaults to true.
*/
function pihole_execute($argument_string, $error_on_failure = true) {
$escaped = escapeshellcmd($argument_string);
$output = null;
$return_status = -1;
$command = "sudo pihole " . $escaped;
exec($command, $output, $return_status);
if($return_status !== 0)
{
trigger_error("Executing {$command} failed.", E_USER_WARNING);
}
return $output;
}
?>

View File

@@ -746,5 +746,6 @@ if ($_POST['action'] == 'get_groups') {
}
// Reload lists in pihole-FTL after having added something
if ($reload) {
echo shell_exec('sudo pihole restartdns reload-lists');
$output = pihole_execute('restartdns reload-lists');
echo implode("\n", $output);
}

View File

@@ -341,12 +341,17 @@ if($auth) {
<div class="pull-left info">
<p>Status</p>
<?php
$pistatus = exec('sudo pihole status web');
if ($pistatus == "1") {
$pistatus = pihole_execute('status web');
if(isset($pistatus[0])) {
$pistatus = $pistatus[0];
} else {
$pistatus = null;
}
if ($pistatus === "1") {
echo '<a id="status"><i class="fa fa-circle text-green-light"></i> Active</a>';
} elseif ($pistatus == "0") {
} elseif ($pistatus === "0") {
echo '<a id="status"><i class="fa fa-circle text-red"></i> Offline</a>';
} elseif ($pistatus == "-1") {
} elseif ($pistatus === "-1") {
echo '<a id="status"><i class="fa fa-circle text-red"></i> DNS service not running</a>';
} else {
echo '<a id="status"><i class="fa fa-circle text-orange"></i> Unknown</a>';

View File

@@ -208,7 +208,7 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
// Test if this lease is already included
readStaticLeasesFile();
foreach($dhcp_static_leases as $lease) {
if($lease["hwaddr"] === $mac)
{
@@ -224,7 +224,7 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
}
}
exec("sudo pihole -a addstaticdhcp ".$mac." ".$ip." ".$hostname);
pihole_execute("-a addstaticdhcp ".$mac." ".$ip." ".$hostname);
$success .= "A new static address has been added";
return true;
} catch(Exception $exception) {
@@ -372,15 +372,23 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
// Fallback
$DNSinterface = "local";
}
exec("sudo pihole -a -i ".$DNSinterface." -web");
pihole_execute("-a -i ".$DNSinterface." -web");
// If there has been no error we can save the new DNS server IPs
if(!strlen($error))
{
$IPs = implode (",", $DNSservers);
$return = exec("sudo pihole -a setdns \"".$IPs."\" ".$extra);
$success .= htmlspecialchars($return)."<br>";
$success .= "The DNS settings have been updated (using ".$DNSservercount." DNS servers)";
$return = pihole_execute("-a setdns \"".$IPs."\" ".$extra);
if(!empty($return))
{
$success .= htmlspecialchars(end($return))."<br>";
$success .= "The DNS settings have been updated (using ".$DNSservercount." DNS servers)";
}
else
{
$success .= "Updating DNS settings failed. Result:";
$success .= implode($return);
}
}
else
{
@@ -394,17 +402,17 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
if($_POST["action"] === "Disable")
{
exec("sudo pihole -l off");
pihole_execute("-l off");
$success .= "Logging has been disabled and logs have been flushed";
}
elseif($_POST["action"] === "Disable-noflush")
{
exec("sudo pihole -l off noflush");
pihole_execute("-l off noflush");
$success .= "Logging has been disabled, your logs have <strong>not</strong> been flushed";
}
else
{
exec("sudo pihole -l on");
pihole_execute("-l on");
$success .= "Logging has been enabled";
}
@@ -461,8 +469,8 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
if(!strlen($error))
{
// All entries are okay
exec("sudo pihole -a setexcludedomains ".$domainlist);
exec("sudo pihole -a setexcludeclients ".$clientlist);
pihole_execute("-a setexcludedomains ".$domainlist);
pihole_execute("-a setexcludeclients ".$clientlist);
$success .= "The API settings have been updated<br>";
}
else
@@ -473,7 +481,7 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
// Set query log options
if(isset($_POST["querylog-permitted"]) && isset($_POST["querylog-blocked"]))
{
exec("sudo pihole -a setquerylog all");
pihole_execute("-a setquerylog all");
if(!isset($_POST["privacyMode"]))
{
$success .= "All entries will be shown in Query Log";
@@ -485,7 +493,7 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
}
elseif(isset($_POST["querylog-permitted"]))
{
exec("sudo pihole -a setquerylog permittedonly");
pihole_execute("-a setquerylog permittedonly");
if(!isset($_POST["privacyMode"]))
{
$success .= "Only permitted will be shown in Query Log";
@@ -497,24 +505,24 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
}
elseif(isset($_POST["querylog-blocked"]))
{
exec("sudo pihole -a setquerylog blockedonly");
pihole_execute("-a setquerylog blockedonly");
$success .= "Only blocked entries will be shown in Query Log";
}
else
{
exec("sudo pihole -a setquerylog nothing");
pihole_execute("-a setquerylog nothing");
$success .= "No entries will be shown in Query Log";
}
if(isset($_POST["privacyMode"]))
{
exec("sudo pihole -a privacymode true");
pihole_execute("-a privacymode true");
$success .= " (privacy mode enabled)";
}
else
{
exec("sudo pihole -a privacymode false");
pihole_execute("-a privacymode false");
}
break;
@@ -522,15 +530,15 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
case "webUI":
if($_POST["tempunit"] == "F")
{
exec('sudo pihole -a -f');
pihole_execute('-a -f');
}
elseif($_POST["tempunit"] == "K")
{
exec('sudo pihole -a -k');
pihole_execute('-a -k');
}
else
{
exec('sudo pihole -a -c');
pihole_execute('-a -c');
}
$adminemail = trim($_POST["adminemail"]);
if(strlen($adminemail) == 0 || !isset($adminemail))
@@ -543,36 +551,36 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
}
else
{
exec('sudo pihole -a -e \''.$adminemail.'\'');
pihole_execute('-a -e \''.$adminemail.'\'');
}
if(isset($_POST["boxedlayout"]))
{
exec('sudo pihole -a layout boxed');
pihole_execute('-a layout boxed');
}
else
{
exec('sudo pihole -a layout traditional');
pihole_execute('-a layout traditional');
}
$success .= "The webUI settings have been updated";
break;
case "poweroff":
exec("sudo pihole -a poweroff");
pihole_execute("-a poweroff");
$success = "The system will poweroff in 5 seconds...";
break;
case "reboot":
exec("sudo pihole -a reboot");
pihole_execute("-a reboot");
$success = "The system will reboot in 5 seconds...";
break;
case "restartdns":
exec("sudo pihole -a restartdns");
pihole_execute("-a restartdns");
$success = "The DNS server has been restarted";
break;
case "flushlogs":
exec("sudo pihole -f");
pihole_execute("-f");
$success = "The Pi-hole log file has been flushed";
break;
@@ -599,7 +607,7 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
if(!strlen($error))
{
exec("sudo pihole -a removestaticdhcp ".$mac);
pihole_execute("-a removestaticdhcp ".$mac);
$success .= "The static address with MAC address ".htmlspecialchars($mac)." has been removed";
}
break;
@@ -666,13 +674,13 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
if(!strlen($error))
{
exec("sudo pihole -a enabledhcp ".$from." ".$to." ".$router." ".$leasetime." ".$domain." ".$ipv6." ".$rapidcommit);
pihole_execute("-a enabledhcp ".$from." ".$to." ".$router." ".$leasetime." ".$domain." ".$ipv6." ".$rapidcommit);
$success .= "The DHCP server has been activated ".htmlspecialchars($type);
}
}
else
{
exec("sudo pihole -a disabledhcp");
pihole_execute("-a disabledhcp");
$success = "The DHCP server has been deactivated";
}
@@ -690,11 +698,11 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
}
// Store privacy level
exec("sudo pihole -a privacylevel ".$level);
pihole_execute("-a privacylevel ".$level);
if($privacylevel > $level)
{
exec("sudo pihole -a restartdns");
pihole_execute("-a restartdns");
$success .= "The privacy level has been decreased and the DNS resolver has been restarted";
}
elseif($privacylevel < $level)
@@ -713,7 +721,7 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
break;
// Flush network table
case "flusharp":
exec("sudo pihole arpflush quiet", $output);
pihole_execute("arpflush quiet", $output);
$error = implode("<br>", $output);
if(strlen($error) == 0)
{

View File

@@ -439,7 +439,7 @@ if(isset($_POST["action"]))
if($importedsomething)
{
exec("sudo pihole restartdns reload");
pihole_execute("restartdns reload");
}
unlink($fullfilename);