diff --git a/api.php b/api.php index dff1ae29..e06a43a7 100644 --- a/api.php +++ b/api.php @@ -20,8 +20,16 @@ $data = array(); // Common API functions if (isset($_GET['status'])) { - $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") { $data = array_merge($data, array("status" => "enabled")); } @@ -42,7 +50,7 @@ elseif (isset($_GET['enable']) && $auth) // Skip token validation if explicit auth string is given check_csrf($_GET['token']); } - exec('sudo pihole enable'); + pihole_execute('enable'); $data = array_merge($data, array("status" => "enabled")); unlink("../custom_disable_timer"); } @@ -63,12 +71,12 @@ elseif (isset($_GET['disable']) && $auth) if($disable > 0) { $timestamp = time(); - exec("sudo pihole disable ".$disable."s"); + pihole_execute("disable ".$disable."s"); file_put_contents("../custom_disable_timer",($timestamp+$disable)*1000); } else { - exec('sudo pihole disable'); + pihole_execute('disable'); unlink("../custom_disable_timer"); } $data = array_merge($data, array("status" => "disabled")); diff --git a/scripts/pi-hole/php/add.php b/scripts/pi-hole/php/add.php index 878b28ff..a04fe189 100644 --- a/scripts/pi-hole/php/add.php +++ b/scripts/pi-hole/php/add.php @@ -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); } ?> diff --git a/scripts/pi-hole/php/customdns.php b/scripts/pi-hole/php/customdns.php index 982981e2..10748f2a 100644 --- a/scripts/pi-hole/php/customdns.php +++ b/scripts/pi-hole/php/customdns.php @@ -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(); } diff --git a/scripts/pi-hole/php/func.php b/scripts/pi-hole/php/func.php index 269fce7f..3d539a52 100644 --- a/scripts/pi-hole/php/func.php +++ b/scripts/pi-hole/php/func.php @@ -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; +} + ?> diff --git a/scripts/pi-hole/php/groups.php b/scripts/pi-hole/php/groups.php index 2167295e..c8711b82 100644 --- a/scripts/pi-hole/php/groups.php +++ b/scripts/pi-hole/php/groups.php @@ -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); } diff --git a/scripts/pi-hole/php/header.php b/scripts/pi-hole/php/header.php index 81622eb2..7b60109f 100644 --- a/scripts/pi-hole/php/header.php +++ b/scripts/pi-hole/php/header.php @@ -341,12 +341,17 @@ if($auth) {

Status

Active'; - } elseif ($pistatus == "0") { + } elseif ($pistatus === "0") { echo ' Offline'; - } elseif ($pistatus == "-1") { + } elseif ($pistatus === "-1") { echo ' DNS service not running'; } else { echo ' Unknown'; diff --git a/scripts/pi-hole/php/savesettings.php b/scripts/pi-hole/php/savesettings.php index 6c8b1e89..e4202838 100644 --- a/scripts/pi-hole/php/savesettings.php +++ b/scripts/pi-hole/php/savesettings.php @@ -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)."
"; - $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))."
"; + $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 not 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
"; } 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("
", $output); if(strlen($error) == 0) { diff --git a/scripts/pi-hole/php/teleporter.php b/scripts/pi-hole/php/teleporter.php index 84f96bc8..e746e6c0 100644 --- a/scripts/pi-hole/php/teleporter.php +++ b/scripts/pi-hole/php/teleporter.php @@ -439,7 +439,7 @@ if(isset($_POST["action"])) if($importedsomething) { - exec("sudo pihole restartdns reload"); + pihole_execute("restartdns reload"); } unlink($fullfilename);