Use 4 spaces to indent PHP files.

Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
This commit is contained in:
RD WebDesign
2022-08-01 01:18:26 -03:00
parent 0d62267ceb
commit 2bc918ad6e
46 changed files with 2098 additions and 2018 deletions
+149 -148
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license */ * Please see LICENSE file for your rights under this license
*/
$api = true; $api = true;
require_once("scripts/pi-hole/php/FTL.php"); require_once("scripts/pi-hole/php/FTL.php");
@@ -17,181 +18,181 @@ $data = array();
// Common API functions // Common API functions
if (isset($_GET['enable']) && $auth) { if (isset($_GET['enable']) && $auth) {
if(isset($_GET["auth"])) if(isset($_GET["auth"]))
{ {
if($_GET["auth"] !== $pwhash) if($_GET["auth"] !== $pwhash)
die("Not authorized!"); die("Not authorized!");
} }
else else
{ {
// Skip token validation if explicit auth string is given // Skip token validation if explicit auth string is given
check_csrf($_GET['token']); check_csrf($_GET['token']);
} }
pihole_execute('enable'); pihole_execute('enable');
$data = array_merge($data, array("status" => "enabled")); $data = array_merge($data, array("status" => "enabled"));
if (file_exists("../custom_disable_timer")) if (file_exists("../custom_disable_timer"))
{ {
unlink("../custom_disable_timer"); unlink("../custom_disable_timer");
} }
} }
elseif (isset($_GET['disable']) && $auth) elseif (isset($_GET['disable']) && $auth)
{ {
if(isset($_GET["auth"])) if(isset($_GET["auth"]))
{ {
if($_GET["auth"] !== $pwhash) if($_GET["auth"] !== $pwhash)
die("Not authorized!"); die("Not authorized!");
} }
else else
{ {
// Skip token validation if explicit auth string is given // Skip token validation if explicit auth string is given
check_csrf($_GET['token']); check_csrf($_GET['token']);
} }
$disable = intval($_GET['disable']); $disable = intval($_GET['disable']);
// intval returns the integer value on success, or 0 on failure // intval returns the integer value on success, or 0 on failure
if($disable > 0) if($disable > 0)
{ {
$timestamp = time(); $timestamp = time();
pihole_execute("disable ".$disable."s"); pihole_execute("disable ".$disable."s");
file_put_contents("../custom_disable_timer",($timestamp+$disable)*1000); file_put_contents("../custom_disable_timer",($timestamp+$disable)*1000);
} }
else else
{ {
pihole_execute('disable'); pihole_execute('disable');
if (file_exists("../custom_disable_timer")) if (file_exists("../custom_disable_timer"))
{ {
unlink("../custom_disable_timer"); unlink("../custom_disable_timer");
} }
} }
$data = array_merge($data, array("status" => "disabled")); $data = array_merge($data, array("status" => "disabled"));
} }
elseif (isset($_GET['versions'])) elseif (isset($_GET['versions']))
{ {
// Determine if updates are available for Pi-hole // Determine if updates are available for Pi-hole
// using the same script that we use for the footer // using the same script that we use for the footer
// on the dashboard (update notifications are // on the dashboard (update notifications are
// suppressed if on development branches) // suppressed if on development branches)
require "scripts/pi-hole/php/update_checker.php"; require "scripts/pi-hole/php/update_checker.php";
$updates = array("core_update" => $core_update, $updates = array("core_update" => $core_update,
"web_update" => $web_update, "web_update" => $web_update,
"FTL_update" => $FTL_update); "FTL_update" => $FTL_update);
$current = array("core_current" => $core_current, $current = array("core_current" => $core_current,
"web_current" => $web_current, "web_current" => $web_current,
"FTL_current" => $FTL_current); "FTL_current" => $FTL_current);
$latest = array("core_latest" => $core_latest, $latest = array("core_latest" => $core_latest,
"web_latest" => $web_latest, "web_latest" => $web_latest,
"FTL_latest" => $FTL_latest); "FTL_latest" => $FTL_latest);
$branches = array("core_branch" => $core_branch, $branches = array("core_branch" => $core_branch,
"web_branch" => $web_branch, "web_branch" => $web_branch,
"FTL_branch" => $FTL_branch); "FTL_branch" => $FTL_branch);
$data = array_merge($data, $updates); $data = array_merge($data, $updates);
$data = array_merge($data, $current); $data = array_merge($data, $current);
$data = array_merge($data, $latest); $data = array_merge($data, $latest);
$data = array_merge($data, $branches); $data = array_merge($data, $branches);
} }
elseif (isset($_GET['list'])) elseif (isset($_GET['list']))
{ {
if (!$auth) if (!$auth)
die("Not authorized!"); die("Not authorized!");
if(!isset($_GET["list"])) if(!isset($_GET["list"]))
die("List has not been specified."); die("List has not been specified.");
switch ($_GET["list"]) { switch ($_GET["list"]) {
case 'black': case 'black':
$_POST['type'] = ListType::blacklist; $_POST['type'] = ListType::blacklist;
break; break;
case 'regex_black': case 'regex_black':
$_POST['type'] = ListType::regex_blacklist; $_POST['type'] = ListType::regex_blacklist;
break; break;
case 'white': case 'white':
$_POST['type'] = ListType::whitelist; $_POST['type'] = ListType::whitelist;
break; break;
case 'regex_white': case 'regex_white':
$_POST['type'] = ListType::regex_whitelist; $_POST['type'] = ListType::regex_whitelist;
break; break;
default: default:
die("Invalid list [supported: black, regex_black, white, regex_white]"); die("Invalid list [supported: black, regex_black, white, regex_white]");
} }
if (isset($_GET['add'])) if (isset($_GET['add']))
{ {
// Set POST parameters and invoke script to add domain to list // Set POST parameters and invoke script to add domain to list
$_POST['domain'] = $_GET['add']; $_POST['domain'] = $_GET['add'];
$_POST['action'] = 'add_domain'; $_POST['action'] = 'add_domain';
require("scripts/pi-hole/php/groups.php"); require("scripts/pi-hole/php/groups.php");
} }
elseif (isset($_GET['sub'])) elseif (isset($_GET['sub']))
{ {
// Set POST parameters and invoke script to remove domain from list // Set POST parameters and invoke script to remove domain from list
$_POST['domain'] = $_GET['sub']; $_POST['domain'] = $_GET['sub'];
$_POST['action'] = 'delete_domain_string'; $_POST['action'] = 'delete_domain_string';
require("scripts/pi-hole/php/groups.php"); require("scripts/pi-hole/php/groups.php");
} }
else else
{ {
// Set POST parameters and invoke script to get all domains // Set POST parameters and invoke script to get all domains
$_POST['action'] = 'get_domains'; $_POST['action'] = 'get_domains';
require("scripts/pi-hole/php/groups.php"); require("scripts/pi-hole/php/groups.php");
} }
return; return;
} }
elseif(isset($_GET['customdns']) && $auth) elseif(isset($_GET['customdns']) && $auth)
{ {
if (isset($_GET["auth"])) { if (isset($_GET["auth"])) {
if ($_GET["auth"] !== $pwhash) { if ($_GET["auth"] !== $pwhash) {
die("Not authorized!"); die("Not authorized!");
} }
} else { } else {
// Skip token validation if explicit auth string is given // Skip token validation if explicit auth string is given
check_csrf($_GET['token']); check_csrf($_GET['token']);
} }
switch ($_GET["action"]) { switch ($_GET["action"]) {
case 'get': case 'get':
$data = echoCustomDNSEntries(); $data = echoCustomDNSEntries();
break; break;
case 'add': case 'add':
$data = addCustomDNSEntry(); $data = addCustomDNSEntry();
break; break;
case 'delete': case 'delete':
$data = deleteCustomDNSEntry(); $data = deleteCustomDNSEntry();
break; break;
default: default:
die("Wrong action"); die("Wrong action");
} }
} }
elseif(isset($_GET['customcname']) && $auth) elseif(isset($_GET['customcname']) && $auth)
{ {
if (isset($_GET["auth"])) { if (isset($_GET["auth"])) {
if ($_GET["auth"] !== $pwhash) { if ($_GET["auth"] !== $pwhash) {
die("Not authorized!"); die("Not authorized!");
} }
} else { } else {
// Skip token validation if explicit auth string is given // Skip token validation if explicit auth string is given
check_csrf($_GET['token']); check_csrf($_GET['token']);
} }
switch ($_GET["action"]) { switch ($_GET["action"]) {
case 'get': case 'get':
$data = echoCustomCNAMEEntries(); $data = echoCustomCNAMEEntries();
break; break;
case 'add': case 'add':
$data = addCustomCNAMEEntry(); $data = addCustomCNAMEEntry();
break; break;
case 'delete': case 'delete':
$data = deleteCustomCNAMEEntry(); $data = deleteCustomCNAMEEntry();
break; break;
default: default:
die("Wrong action"); die("Wrong action");
} }
} }
// Other API functions // Other API functions
+223 -223
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license */ * Please see LICENSE file for your rights under this license
*/
if (!isset($api)) { if (!isset($api)) {
die("Direct call to api_FTL.php is not allowed!"); die("Direct call to api_FTL.php is not allowed!");
@@ -21,14 +22,14 @@ if (isset($_GET['version'])) {
if (isset($_GET['status'])) { if (isset($_GET['status'])) {
$return = callFTLAPI("stats"); $return = callFTLAPI("stats");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
if (in_array("status enabled", $return)) { if (in_array("status enabled", $return)) {
$data = array_merge($data, array("status" => "enabled")); $data = array_merge($data, array("status" => "enabled"));
} else { } else {
$data = array_merge($data, array("status" => "disabled")); $data = array_merge($data, array("status" => "disabled"));
} }
} }
} }
if (isset($_GET['summary']) || isset($_GET['summaryRaw']) || !count($_GET)) { if (isset($_GET['summary']) || isset($_GET['summaryRaw']) || !count($_GET)) {
@@ -36,67 +37,67 @@ if (isset($_GET['summary']) || isset($_GET['summaryRaw']) || !count($_GET)) {
$return = callFTLAPI("stats"); $return = callFTLAPI("stats");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$stats = []; $stats = [];
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
if ($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1]) || $tmp[0] === "status") { if ($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1]) || $tmp[0] === "status") {
// Expect string response // Expect string response
$stats[$tmp[0]] = $tmp[1]; $stats[$tmp[0]] = $tmp[1];
} elseif (isset($_GET['summary'])) { } elseif (isset($_GET['summary'])) {
// "summary" expects a formmated string response // "summary" expects a formmated string response
if ($tmp[0] !== "ads_percentage_today") { if ($tmp[0] !== "ads_percentage_today") {
$stats[$tmp[0]] = number_format($tmp[1]); $stats[$tmp[0]] = number_format($tmp[1]);
} else { } else {
$stats[$tmp[0]] = number_format($tmp[1], 1, '.', ''); $stats[$tmp[0]] = number_format($tmp[1], 1, '.', '');
} }
} else { } else {
// Expect float response // Expect float response
$stats[$tmp[0]] = floatval($tmp[1]); $stats[$tmp[0]] = floatval($tmp[1]);
} }
} }
$stats['gravity_last_updated'] = gravity_last_update(true); $stats['gravity_last_updated'] = gravity_last_update(true);
$data = array_merge($data,$stats); $data = array_merge($data,$stats);
} }
} }
if (isset($_GET["getMaxlogage"]) && $auth) { if (isset($_GET["getMaxlogage"]) && $auth) {
$return = callFTLAPI("maxlogage"); $return = callFTLAPI("maxlogage");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
// Convert seconds to hours and rounds to one decimal place. // Convert seconds to hours and rounds to one decimal place.
$ret = round(intval($return[0]) / 3600, 1); $ret = round(intval($return[0]) / 3600, 1);
// Return 24h if value is 0, empty, null or non numeric. // Return 24h if value is 0, empty, null or non numeric.
$ret = $ret ?: 24; $ret = $ret ?: 24;
$data = array_merge($data, array("maxlogage" => $ret)); $data = array_merge($data, array("maxlogage" => $ret));
} }
} }
if (isset($_GET['overTimeData10mins'])) { if (isset($_GET['overTimeData10mins'])) {
$return = callFTLAPI("overTime"); $return = callFTLAPI("overTime");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$domains_over_time = array(); $domains_over_time = array();
$ads_over_time = array(); $ads_over_time = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
$domains_over_time[intval($tmp[0])] = intval($tmp[1]); $domains_over_time[intval($tmp[0])] = intval($tmp[1]);
$ads_over_time[intval($tmp[0])] = intval($tmp[2]); $ads_over_time[intval($tmp[0])] = intval($tmp[2]);
} }
$result = array( $result = array(
'domains_over_time' => $domains_over_time, 'domains_over_time' => $domains_over_time,
'ads_over_time' => $ads_over_time 'ads_over_time' => $ads_over_time
); );
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['topItems']) && $auth) { if (isset($_GET['topItems']) && $auth) {
@@ -109,18 +110,18 @@ if (isset($_GET['topItems']) && $auth) {
} }
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$top_queries = array(); $top_queries = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
if (count($tmp) == 2) { if (count($tmp) == 2) {
$tmp[2]=""; $tmp[2]="";
} }
$domain = utf8_encode($tmp[2]); $domain = utf8_encode($tmp[2]);
$top_queries[$domain] = intval($tmp[1]); $top_queries[$domain] = intval($tmp[1]);
}
} }
}
if ($_GET['topItems'] === "audit") { if ($_GET['topItems'] === "audit") {
$return = callFTLAPI("top-ads for audit"); $return = callFTLAPI("top-ads for audit");
@@ -131,26 +132,26 @@ if (isset($_GET['topItems']) && $auth) {
} }
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$top_ads = array(); $top_ads = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
$domain = utf8_encode($tmp[2]); $domain = utf8_encode($tmp[2]);
if (count($tmp) > 3) { if (count($tmp) > 3) {
$top_ads[$domain." (".$tmp[3].")"] = intval($tmp[1]); $top_ads[$domain." (".$tmp[3].")"] = intval($tmp[1]);
} else { } else {
$top_ads[$domain] = intval($tmp[1]); $top_ads[$domain] = intval($tmp[1]);
} }
} }
$result = array( $result = array(
'top_queries' => $top_queries, 'top_queries' => $top_queries,
'top_ads' => $top_ads 'top_ads' => $top_ads
); );
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth) { if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth) {
@@ -167,23 +168,23 @@ if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth) {
$return = callFTLAPI("top-clients"); $return = callFTLAPI("top-clients");
} }
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$top_clients = array(); $top_clients = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
$clientip = utf8_encode($tmp[2]); $clientip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) { if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$clientname = utf8_encode($tmp[3]); $clientname = utf8_encode($tmp[3]);
$top_clients[$clientname."|".$clientip] = intval($tmp[1]); $top_clients[$clientname."|".$clientip] = intval($tmp[1]);
} else { } else {
$top_clients[$clientip] = intval($tmp[1]); $top_clients[$clientip] = intval($tmp[1]);
} }
} }
$result = array('top_sources' => $top_clients); $result = array('top_sources' => $top_clients);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['topClientsBlocked']) && $auth) { if (isset($_GET['topClientsBlocked']) && $auth) {
@@ -198,23 +199,23 @@ if (isset($_GET['topClientsBlocked']) && $auth) {
$return = callFTLAPI("top-clients blocked"); $return = callFTLAPI("top-clients blocked");
} }
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$top_clients = array(); $top_clients = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
$clientip = utf8_encode($tmp[2]); $clientip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) { if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$clientname = utf8_encode($tmp[3]); $clientname = utf8_encode($tmp[3]);
$top_clients[$clientname."|".$clientip] = intval($tmp[1]); $top_clients[$clientname."|".$clientip] = intval($tmp[1]);
} else { } else {
$top_clients[$clientip] = intval($tmp[1]); $top_clients[$clientip] = intval($tmp[1]);
} }
} }
$result = array('top_sources_blocked' => $top_clients); $result = array('top_sources_blocked' => $top_clients);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['getForwardDestinations']) && $auth) { if (isset($_GET['getForwardDestinations']) && $auth) {
@@ -224,57 +225,57 @@ if (isset($_GET['getForwardDestinations']) && $auth) {
$return = callFTLAPI("forward-dest"); $return = callFTLAPI("forward-dest");
} }
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$forward_dest = array(); $forward_dest = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
$forwardip = utf8_encode($tmp[2]); $forwardip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) { if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$forwardname = utf8_encode($tmp[3]); $forwardname = utf8_encode($tmp[3]);
$forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]); $forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
} else { } else {
$forward_dest[$forwardip] = floatval($tmp[1]); $forward_dest[$forwardip] = floatval($tmp[1]);
} }
} }
$result = array('forward_destinations' => $forward_dest); $result = array('forward_destinations' => $forward_dest);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['getQueryTypes']) && $auth) { if (isset($_GET['getQueryTypes']) && $auth) {
$return = callFTLAPI("querytypes"); $return = callFTLAPI("querytypes");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$querytypes = array(); $querytypes = array();
foreach ($return as $ret) { foreach ($return as $ret) {
$tmp = explode(": ",$ret); $tmp = explode(": ",$ret);
// Reply cannot contain non-ASCII characters // Reply cannot contain non-ASCII characters
$querytypes[$tmp[0]] = floatval($tmp[1]); $querytypes[$tmp[0]] = floatval($tmp[1]);
} }
$result = array('querytypes' => $querytypes); $result = array('querytypes' => $querytypes);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['getCacheInfo']) && $auth) { if (isset($_GET['getCacheInfo']) && $auth) {
$return = callFTLAPI("cacheinfo"); $return = callFTLAPI("cacheinfo");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$cacheinfo = array(); $cacheinfo = array();
foreach ($return as $ret) { foreach ($return as $ret) {
$tmp = explode(": ",$ret); $tmp = explode(": ",$ret);
// Reply cannot contain non-ASCII characters // Reply cannot contain non-ASCII characters
$cacheinfo[$tmp[0]] = floatval($tmp[1]); $cacheinfo[$tmp[0]] = floatval($tmp[1]);
} }
$result = array('cacheinfo' => $cacheinfo); $result = array('cacheinfo' => $cacheinfo);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['getAllQueries']) && $auth) { if (isset($_GET['getAllQueries']) && $auth) {
@@ -304,38 +305,37 @@ if (isset($_GET['getAllQueries']) && $auth) {
} }
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
// Set the header // Set the header
header('Content-type: application/json'); header('Content-type: application/json');
// Start the JSON string // Start the JSON string
echo '{"data":['; echo '{"data":[';
$first = true; $first = true;
foreach($return as $line) { foreach($return as $line) {
// Insert a comma before the next record (except on the first one)
if (!$first) {
echo ",";
} else {
$first = false;
}
// Insert a comma before the next record (except on the first one) $row = str_getcsv($line," ");
if (!$first) { // UTF-8 encode domain
echo ","; $domain = utf8_encode(str_replace("~"," ",$row[2]));
} else { // UTF-8 encode client host name
$first = false; $client = utf8_encode($row[3]);
}
$row = str_getcsv($line," "); // Insert into array and output it in JSON format
// UTF-8 encode domain // array: time type domain client status dnssecStatus reply response_time CNAMEDomain regexID upstream destination EDE
$domain = utf8_encode(str_replace("~"," ",$row[2])); echo json_encode([$row[0], $row[1], $domain, $client, $row[4], $row[5], $row[6], $row[7], $row[8], $row[9], $row[10], $row[11]]);
// UTF-8 encode client host name }
$client = utf8_encode($row[3]); // Finish the JSON string
echo ']}';
// Insert into array and output it in JSON format // exit at the end
// array: time type domain client status dnssecStatus reply response_time CNAMEDomain regexID upstream destination EDE exit();
echo json_encode([$row[0], $row[1], $domain, $client, $row[4], $row[5], $row[6], $row[7], $row[8], $row[9], $row[10], $row[11]]);
}
// Finish the JSON string
echo ']}';
// exit at the end
exit();
} }
} }
@@ -348,94 +348,94 @@ if (isset($_GET['getForwardDestinationNames']) && $auth) {
$return = callFTLAPI("forward-names"); $return = callFTLAPI("forward-names");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$forward_dest = array(); $forward_dest = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
$forwardip = utf8_encode($tmp[2]); $forwardip = utf8_encode($tmp[2]);
if (count($tmp) > 3) { if (count($tmp) > 3) {
$forwardname = utf8_encode($tmp[3]); $forwardname = utf8_encode($tmp[3]);
$forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]); $forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
} else { } else {
$forward_dest[$forwardip] = floatval($tmp[1]); $forward_dest[$forwardip] = floatval($tmp[1]);
} }
} }
$result = array('forward_destinations' => $forward_dest); $result = array('forward_destinations' => $forward_dest);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['overTimeDataQueryTypes']) && $auth) { if (isset($_GET['overTimeDataQueryTypes']) && $auth) {
$return = callFTLAPI("QueryTypesoverTime"); $return = callFTLAPI("QueryTypesoverTime");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$over_time = array(); $over_time = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
for ($i=0; $i < count($tmp)-1; $i++) { for ($i=0; $i < count($tmp)-1; $i++) {
$over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]); $over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
} }
} }
$result = array('over_time' => $over_time); $result = array('over_time' => $over_time);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['getClientNames']) && $auth) { if (isset($_GET['getClientNames']) && $auth) {
$return = callFTLAPI("client-names"); $return = callFTLAPI("client-names");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$client_names = array(); $client_names = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ", $line); $tmp = explode(" ", $line);
$client_names[] = array( $client_names[] = array(
"name" => utf8_encode($tmp[0]), "name" => utf8_encode($tmp[0]),
"ip" => utf8_encode($tmp[1]) "ip" => utf8_encode($tmp[1])
); );
} }
$result = array('clients' => $client_names); $result = array('clients' => $client_names);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['overTimeDataClients']) && $auth) { if (isset($_GET['overTimeDataClients']) && $auth) {
$return = callFTLAPI("ClientsoverTime"); $return = callFTLAPI("ClientsoverTime");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$over_time = array(); $over_time = array();
foreach ($return as $line) { foreach ($return as $line) {
$tmp = explode(" ",$line); $tmp = explode(" ",$line);
for ($i=0; $i < count($tmp)-1; $i++) { for ($i=0; $i < count($tmp)-1; $i++) {
$over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]); $over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
} }
} }
$result = array('over_time' => $over_time); $result = array('over_time' => $over_time);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
} }
if (isset($_GET['delete_lease']) && $auth) { if (isset($_GET['delete_lease']) && $auth) {
$return = callFTLAPI("delete-lease ".$_GET['delete_lease']); $return = callFTLAPI("delete-lease ".$_GET['delete_lease']);
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$data["delete_lease"] = $return[0]; $data["delete_lease"] = $return[0];
} }
} }
if (isset($_GET['dns-port']) && $auth) { if (isset($_GET['dns-port']) && $auth) {
$return = callFTLAPI("dns-port"); $return = callFTLAPI("dns-port");
if (array_key_exists("FTLnotrunning", $return)) { if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true); $data = array("FTLnotrunning" => true);
} else { } else {
$data["dns-port"] = $return[0]; $data["dns-port"] = $return[0];
} }
} }
?> ?>
+319 -318
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license */ * Please see LICENSE file for your rights under this license
*/
$api = true; $api = true;
header('Content-type: application/json'); header('Content-type: application/json');
@@ -27,428 +28,428 @@ $db = SQLite3_connect($QUERYDB);
if(isset($_GET["network"]) && $auth) if(isset($_GET["network"]) && $auth)
{ {
$network = array(); $network = array();
$results = $db->query('SELECT * FROM network'); $results = $db->query('SELECT * FROM network');
while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC)) while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{ {
$id = intval($res["id"]); $id = intval($res["id"]);
// Get IP addresses and host names for this device // Get IP addresses and host names for this device
$res["ip"] = array(); $res["ip"] = array();
$res["name"] = array(); $res["name"] = array();
$network_addresses = $db->query("SELECT ip,name FROM network_addresses WHERE network_id = $id ORDER BY lastSeen DESC"); $network_addresses = $db->query("SELECT ip,name FROM network_addresses WHERE network_id = $id ORDER BY lastSeen DESC");
while($network_addresses !== false && $network_address = $network_addresses->fetchArray(SQLITE3_ASSOC)) while($network_addresses !== false && $network_address = $network_addresses->fetchArray(SQLITE3_ASSOC))
{ {
array_push($res["ip"],$network_address["ip"]); array_push($res["ip"],$network_address["ip"]);
if($network_address["name"] !== null) if($network_address["name"] !== null)
array_push($res["name"],utf8_encode($network_address["name"])); array_push($res["name"],utf8_encode($network_address["name"]));
else else
array_push($res["name"],""); array_push($res["name"],"");
} }
$network_addresses->finalize(); $network_addresses->finalize();
// UTF-8 encode vendor // UTF-8 encode vendor
$res["macVendor"] = utf8_encode($res["macVendor"]); $res["macVendor"] = utf8_encode($res["macVendor"]);
array_push($network, $res); array_push($network, $res);
} }
$results->finalize(); $results->finalize();
$data = array_merge($data, array('network' => $network)); $data = array_merge($data, array('network' => $network));
} }
if (isset($_GET['getAllQueries']) && $auth) if (isset($_GET['getAllQueries']) && $auth)
{ {
$allQueries = array(); $allQueries = array();
if($_GET['getAllQueries'] !== "empty") if($_GET['getAllQueries'] !== "empty")
{ {
$from = intval($_GET["from"]); $from = intval($_GET["from"]);
$until = intval($_GET["until"]); $until = intval($_GET["until"]);
// Use table "query_storage" // Use table "query_storage"
// - replace domain ID with domain // - replace domain ID with domain
// - replace client ID with client name // - replace client ID with client name
// - replace forward ID with forward destination // - replace forward ID with forward destination
$dbquery = "SELECT timestamp, type,"; $dbquery = "SELECT timestamp, type,";
$dbquery .= " CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,"; $dbquery .= " CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,";
$dbquery .= " CASE typeof(client) WHEN 'integer' THEN ("; $dbquery .= " CASE typeof(client) WHEN 'integer' THEN (";
$dbquery .= " SELECT CASE TRIM(name) WHEN '' THEN c.ip ELSE c.name END name FROM client_by_id c WHERE c.id = q.client"; $dbquery .= " SELECT CASE TRIM(name) WHEN '' THEN c.ip ELSE c.name END name FROM client_by_id c WHERE c.id = q.client";
$dbquery .= " ) ELSE client END client,"; $dbquery .= " ) ELSE client END client,";
$dbquery .= " CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,"; $dbquery .= " CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,";
$dbquery .= " status, reply_type, reply_time, dnssec"; $dbquery .= " status, reply_type, reply_time, dnssec";
$dbquery .= " FROM query_storage q"; $dbquery .= " FROM query_storage q";
$dbquery .= " WHERE timestamp >= :from AND timestamp <= :until "; $dbquery .= " WHERE timestamp >= :from AND timestamp <= :until ";
if(isset($_GET["types"])) if(isset($_GET["types"]))
{ {
$types = $_GET["types"]; $types = $_GET["types"];
if(preg_match("/^[0-9]+(?:,[0-9]+)*$/", $types) === 1) if(preg_match("/^[0-9]+(?:,[0-9]+)*$/", $types) === 1)
{ {
// Append selector to DB query. The used regex ensures // Append selector to DB query. The used regex ensures
// that only numbers, separated by commas are accepted // that only numbers, separated by commas are accepted
// to avoid code injection and other malicious things // to avoid code injection and other malicious things
// We accept only valid lists like "1,2,3" // We accept only valid lists like "1,2,3"
// We reject ",2,3", "1,2," and similar arguments // We reject ",2,3", "1,2," and similar arguments
$dbquery .= "AND status IN (".$types.") "; $dbquery .= "AND status IN (".$types.") ";
} }
else else
{ {
die("Error. Selector types specified using an invalid format."); die("Error. Selector types specified using an invalid format.");
} }
} }
$dbquery .= "ORDER BY timestamp ASC"; $dbquery .= "ORDER BY timestamp ASC";
$stmt = $db->prepare($dbquery); $stmt = $db->prepare($dbquery);
$stmt->bindValue(":from", intval($from), SQLITE3_INTEGER); $stmt->bindValue(":from", intval($from), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($until), SQLITE3_INTEGER); $stmt->bindValue(":until", intval($until), SQLITE3_INTEGER);
$results = $stmt->execute(); $results = $stmt->execute();
// Start the JSON string // Start the JSON string
echo '{"data":['; echo '{"data":[';
if (!is_bool($results)) { if (!is_bool($results)) {
$first = true; $first = true;
while ($row = $results->fetchArray(SQLITE3_ASSOC)) { while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
// Insert a comma before the next record (except on the first one) // Insert a comma before the next record (except on the first one)
if (!$first) { if (!$first) {
echo ","; echo ",";
} else { } else {
$first = false; $first = false;
} }
// Format, encode, transform each field (if necessary). // Format, encode, transform each field (if necessary).
$time = $row["timestamp"]; $time = $row["timestamp"];
$query_type = getQueryTypeStr($row["type"]); // Convert query type ID to name $query_type = getQueryTypeStr($row["type"]); // Convert query type ID to name
$domain = utf8_encode(str_replace("~"," ",$row["domain"])); $domain = utf8_encode(str_replace("~"," ",$row["domain"]));
$client = $row["client"]; $client = $row["client"];
$status = $row["status"]; $status = $row["status"];
$destination = utf8_encode($row["forward"]); $destination = utf8_encode($row["forward"]);
$reply_type = $row["reply_type"]; $reply_type = $row["reply_type"];
$reply_time = $row["reply_time"]; $reply_time = $row["reply_time"];
$dnssec = $row["dnssec"]; $dnssec = $row["dnssec"];
// Insert into array and output it in JSON format // Insert into array and output it in JSON format
echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]); echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]);
} }
} }
// Finish the JSON string // Finish the JSON string
echo ']}'; echo ']}';
// exit at the end // exit at the end
exit(); exit();
} }
// only used if getAllQueries==empty // only used if getAllQueries==empty
$result = array('data' => $allQueries); $result = array('data' => $allQueries);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['topClients']) && $auth) if (isset($_GET['topClients']) && $auth)
{ {
// $from = intval($_GET["from"]); // $from = intval($_GET["from"]);
$limit = ""; $limit = "";
if(isset($_GET["from"]) && isset($_GET["until"])) if(isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = "WHERE timestamp >= :from AND timestamp <= :until"; $limit = "WHERE timestamp >= :from AND timestamp <= :until";
} }
elseif(isset($_GET["from"]) && !isset($_GET["until"])) elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{ {
$limit = "WHERE timestamp >= :from"; $limit = "WHERE timestamp >= :from";
} }
elseif(!isset($_GET["from"]) && isset($_GET["until"])) elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = "WHERE timestamp <= :until"; $limit = "WHERE timestamp <= :until";
} }
$dbquery = "SELECT CASE typeof(client) WHEN 'integer' THEN ("; $dbquery = "SELECT CASE typeof(client) WHEN 'integer' THEN (";
$dbquery .= " SELECT CASE TRIM(name) WHEN '' THEN c.ip ELSE c.name END name FROM client_by_id c WHERE c.id = q.client)"; $dbquery .= " SELECT CASE TRIM(name) WHEN '' THEN c.ip ELSE c.name END name FROM client_by_id c WHERE c.id = q.client)";
$dbquery .= " ELSE client END client, count(client) FROM query_storage q ".$limit." GROUP BY client ORDER BY count(client) DESC LIMIT 20"; $dbquery .= " ELSE client END client, count(client) FROM query_storage q ".$limit." GROUP BY client ORDER BY count(client) DESC LIMIT 20";
$stmt = $db->prepare($dbquery); $stmt = $db->prepare($dbquery);
$stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER); $stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER); $stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute(); $results = $stmt->execute();
$clientnums = array(); $clientnums = array();
if(!is_bool($results)) if(!is_bool($results))
while ($row = $results->fetchArray()) while ($row = $results->fetchArray())
{ {
// $row[0] is the client IP // $row[0] is the client IP
if(array_key_exists($row[0], $clientnums)) if(array_key_exists($row[0], $clientnums))
{ {
// Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database) // Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database)
$clientnums[$row[0]] += intval($row[1]); $clientnums[$row[0]] += intval($row[1]);
} }
else else
{ {
// Entry does not yet exist // Entry does not yet exist
$clientnums[$row[0]] = intval($row[1]); $clientnums[$row[0]] = intval($row[1]);
} }
} }
// Sort by number of hits // Sort by number of hits
arsort($clientnums); arsort($clientnums);
// Extract only the first ten entries // Extract only the first ten entries
$clientnums = array_slice($clientnums, 0, 10); $clientnums = array_slice($clientnums, 0, 10);
$result = array('top_sources' => $clientnums); $result = array('top_sources' => $clientnums);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['topDomains']) && $auth) if (isset($_GET['topDomains']) && $auth)
{ {
$limit = ""; $limit = "";
if(isset($_GET["from"]) && isset($_GET["until"])) if(isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = " AND timestamp >= :from AND timestamp <= :until"; $limit = " AND timestamp >= :from AND timestamp <= :until";
} }
elseif(isset($_GET["from"]) && !isset($_GET["until"])) elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{ {
$limit = " AND timestamp >= :from"; $limit = " AND timestamp >= :from";
} }
elseif(!isset($_GET["from"]) && isset($_GET["until"])) elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = " AND timestamp <= :until"; $limit = " AND timestamp <= :until";
} }
// Select top permitted domains only // Select top permitted domains only
$stmt = $db->prepare('SELECT domain,count(domain) FROM queries WHERE status IN (2,3,12,13,14)'.$limit.' GROUP by domain order by count(domain) desc limit 20'); $stmt = $db->prepare('SELECT domain,count(domain) FROM queries WHERE status IN (2,3,12,13,14)'.$limit.' GROUP by domain order by count(domain) desc limit 20');
$stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER); $stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER); $stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute(); $results = $stmt->execute();
$domains = array(); $domains = array();
if(!is_bool($results)) if(!is_bool($results))
while ($row = $results->fetchArray()) while ($row = $results->fetchArray())
{ {
// Convert domain to lower case UTF-8 // Convert domain to lower case UTF-8
$c = utf8_encode(strtolower($row[0])); $c = utf8_encode(strtolower($row[0]));
if(array_key_exists($c, $domains)) if(array_key_exists($c, $domains))
{ {
// Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database) // Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database)
$domains[$c] += intval($row[1]); $domains[$c] += intval($row[1]);
} }
else else
{ {
// Entry does not yet exist // Entry does not yet exist
$domains[$c] = intval($row[1]); $domains[$c] = intval($row[1]);
} }
} }
// Sort by number of hits // Sort by number of hits
arsort($domains); arsort($domains);
// Extract only the first ten entries // Extract only the first ten entries
$domains = array_slice($domains, 0, 10); $domains = array_slice($domains, 0, 10);
$result = array('top_domains' => $domains); $result = array('top_domains' => $domains);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['topAds']) && $auth) if (isset($_GET['topAds']) && $auth)
{ {
$limit = ""; $limit = "";
if(isset($_GET["from"]) && isset($_GET["until"])) if(isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = " AND timestamp >= :from AND timestamp <= :until"; $limit = " AND timestamp >= :from AND timestamp <= :until";
} }
elseif(isset($_GET["from"]) && !isset($_GET["until"])) elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{ {
$limit = " AND timestamp >= :from"; $limit = " AND timestamp >= :from";
} }
elseif(!isset($_GET["from"]) && isset($_GET["until"])) elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = " AND timestamp <= :until"; $limit = " AND timestamp <= :until";
} }
$stmt = $db->prepare('SELECT domain,count(domain) FROM queries WHERE status IN (1,4,5,6,7,8,9,10,11)'.$limit.' GROUP by domain order by count(domain) desc limit 10'); $stmt = $db->prepare('SELECT domain,count(domain) FROM queries WHERE status IN (1,4,5,6,7,8,9,10,11)'.$limit.' GROUP by domain order by count(domain) desc limit 10');
$stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER); $stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER); $stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute(); $results = $stmt->execute();
$addomains = array(); $addomains = array();
if(!is_bool($results)) if(!is_bool($results))
while ($row = $results->fetchArray()) while ($row = $results->fetchArray())
{ {
$addomains[utf8_encode($row[0])] = intval($row[1]); $addomains[utf8_encode($row[0])] = intval($row[1]);
} }
$result = array('top_ads' => $addomains); $result = array('top_ads' => $addomains);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['getMinTimestamp']) && $auth) if (isset($_GET['getMinTimestamp']) && $auth)
{ {
$results = $db->query('SELECT MIN(timestamp) FROM queries'); $results = $db->query('SELECT MIN(timestamp) FROM queries');
if(!is_bool($results)) if(!is_bool($results))
$result = array('mintimestamp' => $results->fetchArray()[0]); $result = array('mintimestamp' => $results->fetchArray()[0]);
else else
$result = array(); $result = array();
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['getMaxTimestamp']) && $auth) if (isset($_GET['getMaxTimestamp']) && $auth)
{ {
$results = $db->query('SELECT MAX(timestamp) FROM queries'); $results = $db->query('SELECT MAX(timestamp) FROM queries');
if(!is_bool($results)) if(!is_bool($results))
$result = array('maxtimestamp' => $results->fetchArray()[0]); $result = array('maxtimestamp' => $results->fetchArray()[0]);
else else
$result = array(); $result = array();
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['getQueriesCount']) && $auth) if (isset($_GET['getQueriesCount']) && $auth)
{ {
$results = $db->query('SELECT COUNT(timestamp) FROM queries'); $results = $db->query('SELECT COUNT(timestamp) FROM queries');
if(!is_bool($results)) if(!is_bool($results))
$result = array('count' => $results->fetchArray()[0]); $result = array('count' => $results->fetchArray()[0]);
else else
$result = array(); $result = array();
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['getDBfilesize']) && $auth) if (isset($_GET['getDBfilesize']) && $auth)
{ {
$filesize = filesize("/etc/pihole/pihole-FTL.db"); $filesize = filesize("/etc/pihole/pihole-FTL.db");
$result = array('filesize' => $filesize); $result = array('filesize' => $filesize);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['getGraphData']) && $auth) if (isset($_GET['getGraphData']) && $auth)
{ {
$limit = ""; $limit = "";
if(isset($_GET["from"]) && isset($_GET["until"])) if(isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = " AND timestamp >= :from AND timestamp <= :until"; $limit = " AND timestamp >= :from AND timestamp <= :until";
} }
elseif(isset($_GET["from"]) && !isset($_GET["until"])) elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{ {
$limit = " AND timestamp >= :from"; $limit = " AND timestamp >= :from";
} }
elseif(!isset($_GET["from"]) && isset($_GET["until"])) elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{ {
$limit = " AND timestamp <= :until"; $limit = " AND timestamp <= :until";
} }
$interval = 600; $interval = 600;
if(isset($_GET["interval"])) if(isset($_GET["interval"]))
{ {
$q = intval($_GET["interval"]); $q = intval($_GET["interval"]);
if($q >= 10) if($q >= 10)
$interval = $q; $interval = $q;
} }
// Round $from and $until to match the requested $interval // Round $from and $until to match the requested $interval
$from = intval((intval($_GET['from'])/$interval)*$interval); $from = intval((intval($_GET['from'])/$interval)*$interval);
$until = intval((intval($_GET['until'])/$interval)*$interval); $until = intval((intval($_GET['until'])/$interval)*$interval);
// Count permitted queries in intervals // Count permitted queries in intervals
$stmt = $db->prepare('SELECT (timestamp/:interval)*:interval interval, COUNT(*) FROM queries WHERE (status != 0 )'.$limit.' GROUP by interval ORDER by interval'); $stmt = $db->prepare('SELECT (timestamp/:interval)*:interval interval, COUNT(*) FROM queries WHERE (status != 0 )'.$limit.' GROUP by interval ORDER by interval');
$stmt->bindValue(":from", $from, SQLITE3_INTEGER); $stmt->bindValue(":from", $from, SQLITE3_INTEGER);
$stmt->bindValue(":until", $until, SQLITE3_INTEGER); $stmt->bindValue(":until", $until, SQLITE3_INTEGER);
$stmt->bindValue(":interval", $interval, SQLITE3_INTEGER); $stmt->bindValue(":interval", $interval, SQLITE3_INTEGER);
$results = $stmt->execute(); $results = $stmt->execute();
// Parse the DB result into graph data, filling in missing interval sections with zero // Parse the DB result into graph data, filling in missing interval sections with zero
function parseDBData($results, $interval, $from, $until) { function parseDBData($results, $interval, $from, $until) {
$data = array(); $data = array();
$first_db_timestamp = -1; $first_db_timestamp = -1;
if(!is_bool($results)) { if(!is_bool($results)) {
// Read in the data // Read in the data
while($row = $results->fetchArray()) { while($row = $results->fetchArray()) {
// $data[timestamp] = value_in_this_interval // $data[timestamp] = value_in_this_interval
$data[$row[0]] = intval($row[1]); $data[$row[0]] = intval($row[1]);
if($first_db_timestamp === -1) if($first_db_timestamp === -1)
$first_db_timestamp = intval($row[0]); $first_db_timestamp = intval($row[0]);
} }
} }
// It is unpredictable what the first timestamp returned by the database // It is unpredictable what the first timestamp returned by the database
// will be. This depends on live data. Hence, we re-align the FROM // will be. This depends on live data. Hence, we re-align the FROM
// timestamp to avoid unaligned holes appearing as additional // timestamp to avoid unaligned holes appearing as additional
// (incorrect) data points // (incorrect) data points
$aligned_from = $from + (($first_db_timestamp - $from) % $interval); $aligned_from = $from + (($first_db_timestamp - $from) % $interval);
// Fill gaps in returned data // Fill gaps in returned data
for($i = $aligned_from; $i < $until; $i += $interval) { for($i = $aligned_from; $i < $until; $i += $interval) {
if(!array_key_exists($i, $data)) if(!array_key_exists($i, $data))
$data[$i] = 0; $data[$i] = 0;
} }
return $data; return $data;
} }
$domains = parseDBData($results, $interval, $from, $until); $domains = parseDBData($results, $interval, $from, $until);
$result = array('domains_over_time' => $domains); $result = array('domains_over_time' => $domains);
$data = array_merge($data, $result); $data = array_merge($data, $result);
// Count blocked queries in intervals // Count blocked queries in intervals
$stmt = $db->prepare('SELECT (timestamp/:interval)*:interval interval, COUNT(*) FROM queries WHERE status IN (1,4,5,6,7,8,9,10,11)'.$limit.' GROUP by interval ORDER by interval'); $stmt = $db->prepare('SELECT (timestamp/:interval)*:interval interval, COUNT(*) FROM queries WHERE status IN (1,4,5,6,7,8,9,10,11)'.$limit.' GROUP by interval ORDER by interval');
$stmt->bindValue(":from", $from, SQLITE3_INTEGER); $stmt->bindValue(":from", $from, SQLITE3_INTEGER);
$stmt->bindValue(":until", $until, SQLITE3_INTEGER); $stmt->bindValue(":until", $until, SQLITE3_INTEGER);
$stmt->bindValue(":interval", $interval, SQLITE3_INTEGER); $stmt->bindValue(":interval", $interval, SQLITE3_INTEGER);
$results = $stmt->execute(); $results = $stmt->execute();
$addomains = parseDBData($results, $interval, $from, $until); $addomains = parseDBData($results, $interval, $from, $until);
$result = array('ads_over_time' => $addomains); $result = array('ads_over_time' => $addomains);
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if (isset($_GET['status']) && $auth) if (isset($_GET['status']) && $auth)
{ {
$extra = ";"; $extra = ";";
if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN') if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN')
$extra = "WHERE type != 'DNSMASQ_WARN';"; $extra = "WHERE type != 'DNSMASQ_WARN';";
$results = $db->query('SELECT COUNT(*) FROM message '.$extra); $results = $db->query('SELECT COUNT(*) FROM message '.$extra);
if(!is_bool($results)) if(!is_bool($results))
$result = array('message_count' => $results->fetchArray()[0]); $result = array('message_count' => $results->fetchArray()[0]);
else else
$result = array(); $result = array();
$data = array_merge($data, $result); $data = array_merge($data, $result);
} }
if(isset($_GET["messages"]) && $auth) if(isset($_GET["messages"]) && $auth)
{ {
$extra = ";"; $extra = ";";
if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN') if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN')
$extra = "WHERE type != 'DNSMASQ_WARN';"; $extra = "WHERE type != 'DNSMASQ_WARN';";
$messages = array(); $messages = array();
$results = $db->query('SELECT * FROM message '.$extra); $results = $db->query('SELECT * FROM message '.$extra);
while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC)) while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{ {
// Convert string to to UTF-8 encoding to ensure php-json can handle it. // Convert string to to UTF-8 encoding to ensure php-json can handle it.
// Furthermore, convert special characters to HTML entities to prevent XSS attacks. // Furthermore, convert special characters to HTML entities to prevent XSS attacks.
foreach ($res as $key => $value) { foreach ($res as $key => $value) {
if (is_string($value)) if (is_string($value))
$res[$key] = htmlspecialchars(utf8_encode($value)); $res[$key] = htmlspecialchars(utf8_encode($value));
} }
array_push($messages, $res); array_push($messages, $res);
} }
$data = array_merge($data, array('messages' => $messages)); $data = array_merge($data, array('messages' => $messages));
} }
if(isset($_GET["jsonForceObject"])) if(isset($_GET["jsonForceObject"]))
{ {
echo json_encode($data, JSON_FORCE_OBJECT); echo json_encode($data, JSON_FORCE_OBJECT);
} }
else else
{ {
echo json_encode($data); echo json_encode($data);
} }
+55 -52
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
@@ -15,62 +18,62 @@
<div class="row"> <div class="row">
<div class="col-xs-12 col-lg-6"> <div class="col-xs-12 col-lg-6">
<div class="box" id="domain-frequency"> <div class="box" id="domain-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Allowed queries</h3> <h3 class="box-title">Allowed queries</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay"> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
<div class="col-xs-12 col-lg-6"> <div class="col-xs-12 col-lg-6">
<div class="box" id="ad-frequency"> <div class="box" id="ad-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Blocked queries</h3> <h3 class="box-title">Blocked queries</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay"> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
</div> </div>
@@ -79,5 +82,5 @@
<script src="scripts/pi-hole/js/auditlog.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/auditlog.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+10 -9
View File
@@ -5,7 +5,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php"; require "scripts/pi-hole/php/header.php";
?> ?>
@@ -40,9 +41,9 @@ require "scripts/pi-hole/php/header.php";
</div> </div>
</div> </div>
<div class="box-footer clearfix"> <div class="box-footer clearfix">
<strong>Note:</strong> <strong>Note:</strong>
<p>The target of a <code>CNAME</code> must be a domain that the Pi-hole already has in its cache or is authoritative for. This is a universal limitation of <code>CNAME</code> records.</p> <p>The target of a <code>CNAME</code> must be a domain that the Pi-hole already has in its cache or is authoritative for. This is a universal limitation of <code>CNAME</code> records.</p>
<p>The reason for this is that Pi-hole will not send additional queries upstream when serving <code>CNAME</code> replies. As consequence, if you set a target that isn't already known, the reply to the client may be incomplete. Pi-hole just returns the information it knows at the time of the query. This results in certain limitations for <code>CNAME</code> targets, <p>The reason for this is that Pi-hole will not send additional queries upstream when serving <code>CNAME</code> replies. As consequence, if you set a target that isn't already known, the reply to the client may be incomplete. Pi-hole just returns the information it knows at the time of the query. This results in certain limitations for <code>CNAME</code> targets,
for instance, only <i>active</i> DHCP leases work as targets - mere DHCP <i>leases</i> aren't sufficient as they aren't (yet) valid DNS records.</p> for instance, only <i>active</i> DHCP leases work as targets - mere DHCP <i>leases</i> aren't sufficient as they aren't (yet) valid DNS records.</p>
<p>Additionally, you can't <code>CNAME</code> external domains (<code>bing.com</code> to <code>google.com</code>) successfully as this could result in invalid SSL certificate errors when the target server does not serve content for the requested domain.</p> <p>Additionally, you can't <code>CNAME</code> external domains (<code>bing.com</code> to <code>google.com</code>) successfully as this could result in invalid SSL certificate errors when the target server does not serve content for the requested domain.</p>
<button type="button" id="btnAdd" class="btn btn-primary pull-right">Add</button> <button type="button" id="btnAdd" class="btn btn-primary pull-right">Add</button>
@@ -63,11 +64,11 @@ require "scripts/pi-hole/php/header.php";
<div class="box-body"> <div class="box-body">
<table id="customCNAMETable" class="table table-striped table-bordered" width="100%"> <table id="customCNAMETable" class="table table-striped table-bordered" width="100%">
<thead> <thead>
<tr> <tr>
<th>Domain</th> <th>Domain</th>
<th>Target</th> <th>Target</th>
<th>Action</th> <th>Action</th>
</tr> </tr>
</thead> </thead>
</table> </table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Clear Filters</button> <button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Clear Filters</button>
+47 -45
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Sourceing CSS colors from stylesheet to be used in JS code --> <!-- Sourceing CSS colors from stylesheet to be used in JS code -->
<span class="queries-permitted"></span> <span class="queries-permitted"></span>
@@ -17,64 +20,63 @@
<h1>Compute graphical statistics from the Pi-hole query database</h1> <h1>Compute graphical statistics from the Pi-hole query database</h1>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Select date and time range Select date and time range
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon"> <div class="input-group-addon">
<i class="far fa-clock"></i> <i class="far fa-clock"></i>
</div> </div>
<input type="button" class="form-control pull-right" id="querytime" value="Click to select date and time range"> <input type="button" class="form-control pull-right" id="querytime" value="Click to select date and time range">
</div>
</div>
</div>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden> <div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
Depending on how large of a range you specified, the request may time out while Pi-hole tries to retrieve all the data.<br/><span id="err"></span> Depending on how large of a range you specified, the request may time out while Pi-hole tries to retrieve all the data.<br/><span id="err"></span>
</div>
</div> </div>
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="queries-over-time"> <div class="box" id="queries-over-time">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Queries over the selected time period Queries over the selected time period
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="chart"> <div class="chart">
<canvas id="queryOverTimeChart" width="800" height="250"></canvas> <canvas id="queryOverTimeChart" width="800" height="250"></canvas>
</div>
</div>
</div>
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div> </div>
</div>
</div> </div>
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
</div> </div>
</div>
</div> </div>
<script src="scripts/vendor/daterangepicker.min.js?v=<?=$cacheVer?>"></script> <script src="scripts/vendor/daterangepicker.min.js?v=<?=$cacheVer?>"></script>
<script src="scripts/pi-hole/js/db_graph.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/db_graph.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+97 -94
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Sourceing CSS colors from stylesheet to be used in JS code --> <!-- Sourceing CSS colors from stylesheet to be used in JS code -->
@@ -18,27 +21,27 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Select date and time range Select date and time range
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon"> <div class="input-group-addon">
<i class="far fa-clock"></i> <i class="far fa-clock"></i>
</div> </div>
<input type="button" class="form-control pull-right" id="querytime" value="Click to select date and time range"> <input type="button" class="form-control pull-right" id="querytime" value="Click to select date and time range">
</div>
</div>
</div>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden> <div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
@@ -57,90 +60,90 @@ else
?> ?>
<div class="row"> <div class="row">
<div class="<?php echo $tablelayout; ?>"> <div class="<?php echo $tablelayout; ?>">
<div class="box" id="domain-frequency"> <div class="box" id="domain-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Top Domains</h3> <h3 class="box-title">Top Domains</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay" hidden> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
<div class="<?php echo $tablelayout; ?>"> <div class="<?php echo $tablelayout; ?>">
<div class="box" id="ad-frequency"> <div class="box" id="ad-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Top Blocked Domains</h3> <h3 class="box-title">Top Blocked Domains</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay" hidden> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
<div class="<?php echo $tablelayout; ?>"> <div class="<?php echo $tablelayout; ?>">
<div class="box" id="client-frequency"> <div class="box" id="client-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Top Clients</h3> <h3 class="box-title">Top Clients</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Client</th>
<th>Requests</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Client</th>
<th>Requests</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay" hidden> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
</div> </div>
@@ -149,5 +152,5 @@ else
<script src="scripts/pi-hole/js/db_lists.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/db_lists.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+87 -84
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
@@ -14,60 +17,60 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">
Select date and time range Select date and time range
</h3> </h3>
</div>
<div class="box-body">
<div class="alert alert-info reload-box">
<div>
<span><i class="fa fa-exclamation-circle"></i>&nbsp; New options selected. Please reload the data or choose another time range.</span>
<button type="button" class="btn btn-primary bt-reload">Reload Data</button>
</div> </div>
</div> <div class="box-body">
<div class="row"> <div class="alert alert-info reload-box">
<div class="form-group col-md-12"> <div>
<div class="input-group"> <span><i class="fa fa-exclamation-circle"></i>&nbsp; New options selected. Please reload the data or choose another time range.</span>
<div class="input-group-addon"> <button type="button" class="btn btn-primary bt-reload">Reload Data</button>
<i class="far fa-clock"></i> </div>
</div>
<input type="button" class="form-control pull-right" id="querytime" value="Click to select date and time range">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<label>Query status:</label>
</div>
<div class="form-group">
<div class="col-md-3">
<div><input type="checkbox" id="type_forwarded" checked><label for="type_forwarded">Permitted: forwarded</label><br></div>
<div><input type="checkbox" id="type_cached" checked><label for="type_cached">Permitted: cached</label></div>
<div><input type="checkbox" id="type_retried" checked><label for="type_retried">Permitted: retried</label></div>
</div> </div>
<div class="col-md-3"> <div class="row">
<div><input type="checkbox" id="type_gravity" checked><label for="type_gravity">Blocked: gravity</label><br></div> <div class="form-group col-md-12">
<div><input type="checkbox" id="type_external" checked><label for="type_external">Blocked: external</label></div> <div class="input-group">
<div><input type="checkbox" id="type_dbbusy" checked><label for="type_dbbusy">Blocked: database busy</label></div> <div class="input-group-addon">
<i class="far fa-clock"></i>
</div>
<input type="button" class="form-control pull-right" id="querytime" value="Click to select date and time range">
</div>
</div>
</div> </div>
<div class="col-md-3"> <div class="row">
<div><input type="checkbox" id="type_blacklist" checked><label for="type_blacklist">Blocked: exact blacklist</label><br></div> <div class="col-md-12">
<div><input type="checkbox" id="type_regex" checked><label for="type_regex">Blocked: regex blacklist</label></div> <label>Query status:</label>
<div><input type="checkbox" id="type_special_domain" checked><label for="type_special_domain">Blocked: special domain</label></div> </div>
</div> <div class="form-group">
<div class="col-md-3"> <div class="col-md-3">
<div><input type="checkbox" id="type_gravity_CNAME" checked><label for="type_gravity_CNAME">Blocked: gravity (CNAME)</label><br></div> <div><input type="checkbox" id="type_forwarded" checked><label for="type_forwarded">Permitted: forwarded</label><br></div>
<div><input type="checkbox" id="type_blacklist_CNAME" checked><label for="type_blacklist_CNAME">Blocked: exact blacklist (CNAME)</label><br></div> <div><input type="checkbox" id="type_cached" checked><label for="type_cached">Permitted: cached</label></div>
<div><input type="checkbox" id="type_regex_CNAME" checked><label for="type_regex_CNAME">Blocked: regex blacklist (CNAME)</label></div> <div><input type="checkbox" id="type_retried" checked><label for="type_retried">Permitted: retried</label></div>
</div>
<div class="col-md-3">
<div><input type="checkbox" id="type_gravity" checked><label for="type_gravity">Blocked: gravity</label><br></div>
<div><input type="checkbox" id="type_external" checked><label for="type_external">Blocked: external</label></div>
<div><input type="checkbox" id="type_dbbusy" checked><label for="type_dbbusy">Blocked: database busy</label></div>
</div>
<div class="col-md-3">
<div><input type="checkbox" id="type_blacklist" checked><label for="type_blacklist">Blocked: exact blacklist</label><br></div>
<div><input type="checkbox" id="type_regex" checked><label for="type_regex">Blocked: regex blacklist</label></div>
<div><input type="checkbox" id="type_special_domain" checked><label for="type_special_domain">Blocked: special domain</label></div>
</div>
<div class="col-md-3">
<div><input type="checkbox" id="type_gravity_CNAME" checked><label for="type_gravity_CNAME">Blocked: gravity (CNAME)</label><br></div>
<div><input type="checkbox" id="type_blacklist_CNAME" checked><label for="type_blacklist_CNAME">Blocked: exact blacklist (CNAME)</label><br></div>
<div><input type="checkbox" id="type_regex_CNAME" checked><label for="type_regex_CNAME">Blocked: regex blacklist (CNAME)</label></div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden> <div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
@@ -166,40 +169,40 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="recent-queries"> <div class="box" id="recent-queries">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Recent Queries</h3> <h3 class="box-title">Recent Queries</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="all-queries" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</tfoot>
</table>
</div>
<!-- /.box-body -->
</div> </div>
<!-- /.box-header --> <!-- /.box -->
<div class="box-body">
<table id="all-queries" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</tfoot>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
@@ -208,5 +211,5 @@
<script src="scripts/pi-hole/js/db_queries.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/db_queries.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+1 -1
View File
@@ -39,5 +39,5 @@ require "scripts/pi-hole/php/header.php";
<script src="scripts/pi-hole/js/debug.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/debug.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+11 -10
View File
@@ -5,7 +5,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php"; require "scripts/pi-hole/php/header.php";
?> ?>
@@ -40,15 +41,15 @@ require "scripts/pi-hole/php/header.php";
</div> </div>
</div> </div>
<div class="box-footer clearfix"> <div class="box-footer clearfix">
<strong>Note:</strong> <strong>Note:</strong>
<p>The order of locally defined DNS records is: </p> <p>The order of locally defined DNS records is: </p>
<ol> <ol>
<li>The device's host name and <code>pi.hole</code></li> <li>The device's host name and <code>pi.hole</code></li>
<li>Configured in a config file in <code>/etc/dnsmasq.d/</code></li> <li>Configured in a config file in <code>/etc/dnsmasq.d/</code></li>
<li>Read from <code>/etc/hosts</code></li> <li>Read from <code>/etc/hosts</code></li>
<li>Read from the "Local (custom) DNS" list (stored in <code>/etc/pihole/custom.list</code>)</li> <li>Read from the "Local (custom) DNS" list (stored in <code>/etc/pihole/custom.list</code>)</li>
</ol> </ol>
<p>Only the first record will trigger an address-to-name association.</p> <p>Only the first record will trigger an address-to-name association.</p>
<button type="button" id="btnAdd" class="btn btn-primary pull-right">Add</button> <button type="button" id="btnAdd" class="btn btn-primary pull-right">Add</button>
</div> </div>
</div> </div>
+7 -4
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
<div class="page-header"> <div class="page-header">
@@ -28,5 +31,5 @@
<script src="scripts/pi-hole/js/gravity.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/gravity.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+14 -12
View File
@@ -4,8 +4,10 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
@@ -60,16 +62,16 @@
<div class="box-body"> <div class="box-body">
<table id="adlistsTable" class="table table-striped table-bordered" width="100%"> <table id="adlistsTable" class="table table-striped table-bordered" width="100%">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th></th> <th></th>
<th class="no-padding"></th> <th class="no-padding"></th>
<th>Address</th> <th>Address</th>
<th>Status</th> <th>Status</th>
<th>Comment</th> <th>Comment</th>
<th>Group assignment</th> <th>Group assignment</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
</table> </table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button> <button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
+21 -16
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2019 Pi-hole, LLC (https://pi-hole.net) * (c) 2019 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
@@ -41,12 +44,14 @@
<div class="col-md-12"> <div class="col-md-12">
<p>You can select an existing client or add a custom one by typing into the field above and confirming your entry with <kbd>&#x23CE;</kbd>.</p> <p>You can select an existing client or add a custom one by typing into the field above and confirming your entry with <kbd>&#x23CE;</kbd>.</p>
<p>Clients may be described either by their IP addresses (IPv4 and IPv6 are supported), <p>Clients may be described either by their IP addresses (IPv4 and IPv6 are supported),
IP subnets (CIDR notation, like <code>192.168.2.0/24</code>), IP subnets (CIDR notation, like <code>192.168.2.0/24</code>),
their MAC addresses (like <code>12:34:56:78:9A:BC</code>), their MAC addresses (like <code>12:34:56:78:9A:BC</code>),
by their hostnames (like <code>localhost</code>), or by the interface they are connected to (prefaced with a colon, like <code>:eth0</code>).</p> by their hostnames (like <code>localhost</code>), or by the interface they are connected to (prefaced with a colon, like <code>:eth0</code>).
</p>
<p>Note that client recognition by IP addresses (incl. subnet ranges) are preferred over MAC address, host name or interface recognition as <p>Note that client recognition by IP addresses (incl. subnet ranges) are preferred over MAC address, host name or interface recognition as
the two latter will only be available after some time. the two latter will only be available after some time.
Furthermore, MAC address recognition only works for devices at most one networking hop away from your Pi-hole.</p> Furthermore, MAC address recognition only works for devices at most one networking hop away from your Pi-hole.
</p>
</div> </div>
</div> </div>
</div> </div>
@@ -68,14 +73,14 @@
<div class="box-body"> <div class="box-body">
<table id="clientsTable" class="table table-striped table-bordered" width="100%"> <table id="clientsTable" class="table table-striped table-bordered" width="100%">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th></th> <th></th>
<th title="Acceptable values are: IP address, subnet (CIDR notation), MAC address (AA:BB:CC:DD:EE:FF format) or host names.">Client</th> <th title="Acceptable values are: IP address, subnet (CIDR notation), MAC address (AA:BB:CC:DD:EE:FF format) or host names.">Client</th>
<th>Comment</th> <th>Comment</th>
<th>Group assignment</th> <th>Group assignment</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
</table> </table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button> <button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
+20 -17
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2019 Pi-hole, LLC (https://pi-hole.net) * (c) 2019 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
@@ -74,8 +77,8 @@
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="new_regex_comment">Comment:</label> <label for="new_regex_comment">Comment:</label>
<input id="new_regex_comment" type="text" class="form-control" placeholder="Description (optional)"> <input id="new_regex_comment" type="text" class="form-control" placeholder="Description (optional)">
</div> </div>
</div> </div>
</div> </div>
@@ -83,8 +86,8 @@
</div> </div>
<div> <div>
<p><strong>Note:</strong><br> <p><strong>Note:</strong><br>
The domain or regex filter will be automatically assigned to the Default Group.<br> The domain or regex filter will be automatically assigned to the Default Group.<br>
Other groups can optionally be assigned in the list below (using <b>Group assignment</b>). Other groups can optionally be assigned in the list below (using <b>Group assignment</b>).
</p> </p>
</div> </div>
<div class="btn-toolbar pull-right" role="toolbar" aria-label="Toolbar with buttons"> <div class="btn-toolbar pull-right" role="toolbar" aria-label="Toolbar with buttons">
@@ -115,16 +118,16 @@
<div class="box-body"> <div class="box-body">
<table id="domainsTable" class="table table-striped table-bordered" width="100%"> <table id="domainsTable" class="table table-striped table-bordered" width="100%">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th></th> <th></th>
<th>Domain/RegEx</th> <th>Domain/RegEx</th>
<th>Type</th> <th>Type</th>
<th>Status</th> <th>Status</th>
<th>Comment</th> <th>Comment</th>
<th>Group assignment</th> <th>Group assignment</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
</table> </table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button> <button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
+14 -11
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2019 Pi-hole, LLC (https://pi-hole.net) * (c) 2019 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
@@ -59,14 +62,14 @@
<div class="box-body"> <div class="box-body">
<table id="groupsTable" class="table table-striped table-bordered" width="100%"> <table id="groupsTable" class="table table-striped table-bordered" width="100%">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th></th> <th></th>
<th>Name</th> <th>Name</th>
<th>Status</th> <th>Status</th>
<th>Description</th> <th>Description</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
</table> </table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button> <button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
+171 -170
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
$indexpage = true; $indexpage = true;
require "scripts/pi-hole/php/header.php"; require "scripts/pi-hole/php/header.php";
@@ -73,217 +74,217 @@ require_once "scripts/pi-hole/php/gravity.php";
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="queries-over-time"> <div class="box" id="queries-over-time">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Total queries over last <span class="maxlogage-interval">24</span> hours</h3> <h3 class="box-title">Total queries over last <span class="maxlogage-interval">24</span> hours</h3>
</div>
<div class="box-body">
<div class="chart">
<canvas id="queryOverTimeChart" width="800" height="140"></canvas>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="box-body">
<div class="chart">
<canvas id="queryOverTimeChart" width="800" height="140"></canvas>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
</div> </div>
</div> </div>
<?php <?php
// If the user is logged in, then we show the more detailed index page. // If the user is logged in, then we show the more detailed index page.
// Even if we would include them here anyhow, there would be nothing to // Even if we would include them here anyhow, there would be nothing to
// show since the API will respect the privacy of the user if he defines // show since the API will respect the privacy of the user if he defines
// a password // a password
if($auth){ ?> if($auth){
?>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="clients"> <div class="box" id="clients">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Client activity over last <span class="maxlogage-interval">24</span> hours</h3> <h3 class="box-title">Client activity over last <span class="maxlogage-interval">24</span> hours</h3>
</div>
<div class="box-body">
<div class="chart">
<canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas no-user-select"></canvas>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="box-body">
<div class="chart">
<canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas no-user-select"></canvas>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="box" id="query-types-pie"> <div class="box" id="query-types-pie">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Query Types</h3> <h3 class="box-title">Query Types</h3>
</div>
<div class="box-body">
<div class="pull-left" style="width:50%">
<canvas id="queryTypePieChart" width="120" height="120"></canvas>
</div>
<div class="pull-left" style="width:50%">
<div id="query-types-legend" class="chart-legend"></div>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="box-body">
<div class="pull-left" style="width:50%">
<canvas id="queryTypePieChart" width="120" height="120"></canvas>
</div>
<div class="pull-left" style="width:50%">
<div id="query-types-legend" class="chart-legend"></div>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="box" id="forward-destinations-pie"> <div class="box" id="forward-destinations-pie">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Upstream servers</h3> <h3 class="box-title">Upstream servers</h3>
</div>
<div class="box-body">
<div class="pull-left" style="width:50%">
<canvas id="forwardDestinationPieChart" width="120" height="120" class="extratooltipcanvas no-user-select"></canvas>
</div>
<div class="pull-left" style="width:50%">
<div id="forward-destinations-legend" class="chart-legend extratooltipcanvas no-user-select"></div>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="box-body">
<div class="pull-left" style="width:50%">
<canvas id="forwardDestinationPieChart" width="120" height="120" class="extratooltipcanvas no-user-select"></canvas>
</div>
<div class="pull-left" style="width:50%">
<div id="forward-destinations-legend" class="chart-legend extratooltipcanvas no-user-select"></div>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
</div> </div>
</div> </div>
<?php <?php
if($boxedlayout) if($boxedlayout)
{ {
$tablelayout = "col-md-6"; $tablelayout = "col-md-6";
} }
else else
{ {
$tablelayout = "col-md-6 col-lg-6"; $tablelayout = "col-md-6 col-lg-6";
} }
?> ?>
<div class="row"> <div class="row">
<div class="<?php echo $tablelayout; ?>"> <div class="<?php echo $tablelayout; ?>">
<div class="box" id="domain-frequency"> <div class="box" id="domain-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Top Permitted Domains</h3> <h3 class="box-title">Top Permitted Domains</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay"> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
<div class="<?php echo $tablelayout; ?>"> <div class="<?php echo $tablelayout; ?>">
<div class="box" id="ad-frequency"> <div class="box" id="ad-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Top Blocked Domains</h3> <h3 class="box-title">Top Blocked Domains</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay"> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<!-- /.col --> <!-- /.col -->
<div class="<?php echo $tablelayout; ?>"> <div class="<?php echo $tablelayout; ?>">
<div class="box" id="client-frequency"> <div class="box" id="client-frequency">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Top Clients (total)</h3> <h3 class="box-title">Top Clients (total)</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Client</th>
<th>Requests</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Client</th>
<th>Requests</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay"> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
<!-- /.col -->
<div class="<?php echo $tablelayout; ?>"> <div class="<?php echo $tablelayout; ?>">
<div class="box" id="client-frequency-blocked"> <div class="box" id="client-frequency-blocked">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Top Clients (blocked only)</h3> <h3 class="box-title">Top Clients (blocked only)</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Client</th>
<th>Requests</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Client</th>
<th>Requests</th>
<th>Frequency</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div> </div>
<div class="overlay"> <!-- /.box -->
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> <!-- /.col -->
</div> </div>
@@ -293,5 +294,5 @@ else
<script src="scripts/pi-hole/js/index.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/index.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+20 -17
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2020 Pi-hole, LLC (https://pi-hole.net) * (c) 2020 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
@@ -21,19 +24,19 @@
<div class="box-body"> <div class="box-body">
<table id="messagesTable" class="table table-striped table-bordered" width="100%"> <table id="messagesTable" class="table table-striped table-bordered" width="100%">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>&nbsp;</th> <th>&nbsp;</th>
<th>Time</th> <th>Time</th>
<th>Type</th> <th>Type</th>
<th>Message</th> <th>Message</th>
<th>Data1</th> <th>Data1</th>
<th>Data2</th> <th>Data2</th>
<th>Data3</th> <th>Data3</th>
<th>Data4</th> <th>Data4</th>
<th>Data5</th> <th>Data5</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
</table> </table>
<p>Note: If errors are shown, you can <a href="debug.php">generate a debug log</a>, which will do a thorough Pi-hole evaluation.</p> <p>Note: If errors are shown, you can <a href="debug.php">generate a debug log</a>, which will do a thorough Pi-hole evaluation.</p>
@@ -47,5 +50,5 @@
<script src="scripts/pi-hole/js/messages.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/messages.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+52 -50
View File
@@ -4,62 +4,64 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="network-details"> <div class="box" id="network-details">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Network overview</h3> <h3 class="box-title">Network overview</h3>
</div> </div>
<!-- /.box-header --> <!-- /.box-header -->
<div class="box-body"> <div class="box-body">
<table id="network-entries" class="table table-striped table-bordered" width="100%"> <table id="network-entries" class="table table-striped table-bordered" width="100%">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>IP address</th> <th>IP address</th>
<th>Hardware address</th> <th>Hardware address</th>
<th>Interface</th> <th>Interface</th>
<th>Hostname</th> <th>Hostname</th>
<th>First seen</th> <th>First seen</th>
<th>Last Query</th> <th>Last Query</th>
<th>Number of queries</th> <th>Number of queries</th>
<th>Uses Pi-hole</th> <th>Uses Pi-hole</th>
<th>Action</th> <th>Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>ID</th>
<th>IP address</th>
<th>Hardware address</th>
<th>Interface</th>
<th>Hostname</th>
<th>First seen</th>
<th>Last Query</th>
<th>Number of queries</th>
<th>Uses Pi-hole</th>
<th>Action</th>
</tr>
</tfoot>
</table>
<label>Background color: Last query from this device seen ...</label>
<table width="100%">
<tr class="text-center">
<td class="network-recent" width="15%">just now</td>
<td class="network-gradient" width="30%">... to ...</td>
<td class="network-old" width="15%">24 hours ago</td>
<td class="network-older" width="20%">&gt; 24 hours ago</td>
<td class="network-never" width="20%">Device does not use Pi-hole</td>
</tr> </tr>
</thead> </table>
<tfoot> </div>
<tr> <!-- /.box-body -->
<th>ID</th>
<th>IP address</th>
<th>Hardware address</th>
<th>Interface</th>
<th>Hostname</th>
<th>First seen</th>
<th>Last Query</th>
<th>Number of queries</th>
<th>Uses Pi-hole</th>
<th>Action</th>
</tr>
</tfoot>
</table>
<label>Background color: Last query from this device seen ...</label>
<table width="100%">
<tr class="text-center">
<td class="network-recent" width="15%">just now</td>
<td class="network-gradient" width="30%">... to ...</td>
<td class="network-old" width="15%">24 hours ago</td>
<td class="network-older" width="20%">&gt; 24 hours ago</td>
<td class="network-never" width="20%">Device does not use Pi-hole</td>
</tr>
</table>
</div> </div>
<!-- /.box-body --> <!-- /.box -->
</div>
<!-- /.box -->
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
@@ -68,5 +70,5 @@
<script src="scripts/pi-hole/js/network.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/network.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+47 -44
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
$showing = ""; $showing = "";
@@ -131,47 +134,47 @@ if(strlen($showing) > 0)
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="recent-queries"> <div class="box" id="recent-queries">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Recent Queries <?php echo $showing; ?></h3> <h3 class="box-title">Recent Queries <?php echo $showing; ?></h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="all-queries" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</tfoot>
</table>
<p>Note: Queries for <code>pi.hole</code> and the hostname are never logged.</p>
<p><strong>Filtering options:</strong></p>
<ul>
<li>Click a value in a column to add/remove that value to/from the filter</li>
<li>On a computer: Hold down <kbd>Ctrl</kbd>, <kbd>Alt</kbd>, or <kbd>&#8984;</kbd> to allow highlighting for copying to clipboard</li>
<li>On a mobile: Long press to highlight the text and enable copying to clipboard
</ul><br/><button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Clear filters</button>
</div>
<!-- /.box-body -->
</div> </div>
<!-- /.box-header --> <!-- /.box -->
<div class="box-body">
<table id="all-queries" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Time</th>
<th>Type</th>
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</tfoot>
</table>
<p>Note: Queries for <code>pi.hole</code> and the hostname are never logged.</p>
<p><strong>Filtering options:</strong></p>
<ul>
<li>Click a value in a column to add/remove that value to/from the filter</li>
<li>On a computer: Hold down <kbd>Ctrl</kbd>, <kbd>Alt</kbd>, or <kbd>&#8984;</kbd> to allow highlighting for copying to clipboard</li>
<li>On a mobile: Long press to highlight the text and enable copying to clipboard
</ul><br/><button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Clear filters</button>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
@@ -179,5 +182,5 @@ if(strlen($showing) > 0)
<script src="scripts/pi-hole/js/queries.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/queries.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+21 -18
View File
@@ -1,38 +1,41 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
<div class="page-header"> <div class="page-header">
<h1>Find Blocked Domain In Lists</h1> <h1>Find Blocked Domain In Lists</h1>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box"> <div class="box">
<div class="box-body"> <div class="box-body">
<!-- domain-search-block - Single search field mobile/desktop --> <!-- domain-search-block - Single search field mobile/desktop -->
<div id="domain-search-block" class="input-group"> <div id="domain-search-block" class="input-group">
<input id="domain" type="url" class="form-control" placeholder="Domain to look for (example.com or sub.example.com)" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"> <input id="domain" type="url" class="form-control" placeholder="Domain to look for (example.com or sub.example.com)" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off">
<input id="quiet" type="hidden" value="no"> <input id="quiet" type="hidden" value="no">
<span class="input-group-btn"> <span class="input-group-btn">
<button type="button" id="btnSearch" class="btn btn-default">Search partial match</button> <button type="button" id="btnSearch" class="btn btn-default">Search partial match</button>
<button type="button" id="btnSearchExact" class="btn btn-default">Search exact match</button> <button type="button" id="btnSearchExact" class="btn btn-default">Search exact match</button>
</span> </span>
</div>
<!-- /domain-search-block -->
</div>
</div> </div>
<!-- /domain-search-block -->
</div>
</div> </div>
</div>
</div> </div>
<pre id="output" style="width: 100%; height: 100%;" hidden></pre> <pre id="output" style="width: 100%; height: 100%;" hidden></pre>
<script src="scripts/pi-hole/js/queryads.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/queryads.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
const DEFAULT_FTLCONFFILE = "/etc/pihole/pihole-FTL.conf"; const DEFAULT_FTLCONFFILE = "/etc/pihole/pihole-FTL.conf";
const DEFAULT_FTL_IP = "127.0.0.1"; const DEFAULT_FTL_IP = "127.0.0.1";
+12 -12
View File
@@ -31,19 +31,19 @@ body {
<body> <body>
<?php <?php
if($auth) { if($auth) {
if(strlen($pwhash) > 0) { if(strlen($pwhash) > 0) {
echo '<div class="qrcode">'; echo '<div class="qrcode">';
require_once("../../vendor/qrcode.php"); require_once("../../vendor/qrcode.php");
$qr = QRCode::getMinimumQRCode($pwhash, QR_ERROR_CORRECT_LEVEL_Q); $qr = QRCode::getMinimumQRCode($pwhash, QR_ERROR_CORRECT_LEVEL_Q);
// The size of each block (in pixels) should be an integer // The size of each block (in pixels) should be an integer
$qr->printSVG(10); $qr->printSVG(10);
echo "</div>"; echo "</div>";
echo 'Raw API Token: <code class="token">' . $pwhash . "</code></div>"; echo 'Raw API Token: <code class="token">' . $pwhash . "</code></div>";
} else { } else {
echo "<p>No password set</p>"; echo "<p>No password set</p>";
} }
} else { } else {
echo "<p>Not authorized!</p>"; echo "<p>Not authorized!</p>";
} }
?> ?>
</body> </body>
+3 -1
View File
@@ -4,9 +4,11 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require_once('func.php'); require_once('func.php');
$ERRORLOG = getenv('PHP_ERROR_LOG'); $ERRORLOG = getenv('PHP_ERROR_LOG');
if (empty($ERRORLOG)) { if (empty($ERRORLOG)) {
$ERRORLOG = '/var/log/lighttpd/error-pihole.log'; $ERRORLOG = '/var/log/lighttpd/error-pihole.log';
+17 -21
View File
@@ -1,26 +1,22 @@
<?php <?php
require_once "func.php";
require_once('auth.php');
require_once "func.php"; // Authentication checks
if (!isset($api)) {
require_once('auth.php'); if (isset($_POST['token'])) {
check_cors();
// Authentication checks check_csrf($_POST['token']);
if (!isset($api)) { } else {
if (isset($_POST['token'])) { log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
check_cors();
check_csrf($_POST['token']);
} else {
log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
}
} }
}
switch ($_POST['action']) {
switch ($_POST['action']) case 'get': echo json_encode(echoCustomCNAMEEntries()); break;
{ case 'add': echo json_encode(addCustomCNAMEEntry()); break;
case 'get': echo json_encode(echoCustomCNAMEEntries()); break; case 'delete': echo json_encode(deleteCustomCNAMEEntry()); break;
case 'add': echo json_encode(addCustomCNAMEEntry()); break; default:
case 'delete': echo json_encode(deleteCustomCNAMEEntry()); break; die("Wrong action");
default: }
die("Wrong action");
}
?> ?>
+17 -21
View File
@@ -1,26 +1,22 @@
<?php <?php
require_once "func.php";
require_once('auth.php');
require_once "func.php"; // Authentication checks
if (!isset($api)) {
require_once('auth.php'); if (isset($_POST['token'])) {
check_cors();
// Authentication checks check_csrf($_POST['token']);
if (!isset($api)) { } else {
if (isset($_POST['token'])) { log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
check_cors();
check_csrf($_POST['token']);
} else {
log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
}
} }
}
switch ($_POST['action']) {
switch ($_POST['action']) case 'get': echo json_encode(echoCustomDNSEntries()); break;
{ case 'add': echo json_encode(addCustomDNSEntry()); break;
case 'get': echo json_encode(echoCustomDNSEntries()); break; case 'delete': echo json_encode(deleteCustomDNSEntry()); break;
case 'add': echo json_encode(addCustomDNSEntry()); break; default:
case 'delete': echo json_encode(deleteCustomDNSEntry()); break; die("Wrong action");
default: }
die("Wrong action");
}
?> ?>
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license */ * Please see LICENSE file for your rights under this license
*/
function getGravityDBFilename() function getGravityDBFilename()
{ {
+11 -9
View File
@@ -4,7 +4,9 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ ?> * Please see LICENSE file for your rights under this license.
*/
?>
</section> </section>
<!-- /.content --> <!-- /.content -->
@@ -20,14 +22,14 @@
<div class="modal-body"> <div class="modal-body">
<div class="input-group"> <div class="input-group">
<input id="customTimeout" class="form-control" type="number" value="60"> <input id="customTimeout" class="form-control" type="number" value="60">
<div class="input-group-btn" data-toggle="buttons"> <div class="input-group-btn" data-toggle="buttons">
<label class="btn btn-default"> <label class="btn btn-default">
<input id="selSec" type="radio"> Secs <input id="selSec" type="radio"> Secs
</label> </label>
<label id="btnMins" class="btn btn-default active"> <label id="btnMins" class="btn btn-default active">
<input id="selMin" type="radio"> Mins <input id="selMin" type="radio"> Mins
</label> </label>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
+11 -10
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
// Credit: http://stackoverflow.com/a/4694816/2087442 // Credit: http://stackoverflow.com/a/4694816/2087442
// Modified because of https://github.com/pi-hole/AdminLTE/pull/533 // Modified because of https://github.com/pi-hole/AdminLTE/pull/533
@@ -70,8 +71,8 @@ function validCIDRIP($address){
function validMAC($mac_addr) function validMAC($mac_addr)
{ {
// Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case) // Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case)
return !filter_var($mac_addr, FILTER_VALIDATE_MAC) === false; return !filter_var($mac_addr, FILTER_VALIDATE_MAC) === false;
} }
function validEmail($email) function validEmail($email)
@@ -87,8 +88,8 @@ function validEmail($email)
function get_ip_type($ip) function get_ip_type($ip)
{ {
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? 4 : return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? 4 :
(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? 6 : (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? 6 :
0); 0);
} }
function checkfile($filename) { function checkfile($filename) {
@@ -109,14 +110,14 @@ if(!function_exists('hash_equals')) {
$ret = 0; $ret = 0;
if (strlen($known_string) !== strlen($user_string)) { if (strlen($known_string) !== strlen($user_string)) {
$user_string = $known_string; $user_string = $known_string;
$ret = 1; $ret = 1;
} }
$res = $known_string ^ $user_string; $res = $known_string ^ $user_string;
for ($i = strlen($res) - 1; $i >= 0; --$i) { for ($i = strlen($res) - 1; $i >= 0; --$i) {
$ret |= ord($res[$i]); $ret |= ord($res[$i]);
} }
return !$ret; return !$ret;
@@ -548,9 +549,9 @@ function piholeStatus() {
function getGateway() { function getGateway() {
$gateway= callFTLAPI("gateway"); $gateway= callFTLAPI("gateway");
if (array_key_exists("FTLnotrunning", $gateway)) { if (array_key_exists("FTLnotrunning", $gateway)) {
$ret = array("ip" => -1); $ret = array("ip" => -1);
} else { } else {
$ret = array_combine(["ip", "iface"], explode(" ", $gateway[0])); $ret = array_combine(["ip", "iface"], explode(" ", $gateway[0]));
} }
return $ret; return $ret;
} }
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require_once("scripts/pi-hole/php/database.php"); require_once("scripts/pi-hole/php/database.php");
+3 -1
View File
@@ -4,9 +4,11 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require "password.php"; require "password.php";
if(!$auth) die("Not authorized"); if(!$auth) die("Not authorized");
ob_end_flush(); ob_end_flush();
+21 -20
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require_once('auth.php'); require_once('auth.php');
require_once('func.php'); require_once('func.php');
@@ -360,8 +361,8 @@ if ($_POST['action'] == 'get_groups') {
$comment = html_entity_decode($_POST['comment']); $comment = html_entity_decode($_POST['comment']);
if (strlen($comment) === 0) { if (strlen($comment) === 0) {
// Store NULL in database for empty comments // Store NULL in database for empty comments
$comment = null; $comment = null;
} }
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) { if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: <strong>' . $db->lastErrorMsg() . '</strong><br>'. throw new Exception('While binding comment: <strong>' . $db->lastErrorMsg() . '</strong><br>'.
@@ -392,8 +393,8 @@ if ($_POST['action'] == 'get_groups') {
$comment = html_entity_decode($_POST['comment']); $comment = html_entity_decode($_POST['comment']);
if (strlen($comment) === 0) { if (strlen($comment) === 0) {
// Store NULL in database for empty comments // Store NULL in database for empty comments
$comment = null; $comment = null;
} }
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) { if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg()); throw new Exception('While binding comment: ' . $db->lastErrorMsg());
@@ -694,15 +695,15 @@ if ($_POST['action'] == 'get_groups') {
$difference = $after - $before; $difference = $after - $before;
if($total === 1) { if($total === 1) {
if($difference !== 1) { if($difference !== 1) {
$msg = "Not adding ". htmlentities(utf8_encode($domain)) . " as it is already on the list"; $msg = "Not adding ". htmlentities(utf8_encode($domain)) . " as it is already on the list";
} else { } else {
$msg = "Added " . htmlentities(utf8_encode($domain)); $msg = "Added " . htmlentities(utf8_encode($domain));
} }
} else { } else {
if($difference !== $total) { if($difference !== $total) {
$msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)"; $msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)";
} else { } else {
$msg = "Added " . $total . " domains"; $msg = "Added " . $total . " domains";
} }
} }
$reload = true; $reload = true;
@@ -722,7 +723,7 @@ if ($_POST['action'] == 'get_groups') {
$status = intval($_POST['status']); $status = intval($_POST['status']);
if ($status !== 0) { if ($status !== 0) {
$status = 1; $status = 1;
} }
if (!$stmt->bindValue(':enabled', $status, SQLITE3_INTEGER)) { if (!$stmt->bindValue(':enabled', $status, SQLITE3_INTEGER)) {
@@ -731,8 +732,8 @@ if ($_POST['action'] == 'get_groups') {
$comment = html_entity_decode($_POST['comment']); $comment = html_entity_decode($_POST['comment']);
if (strlen($comment) === 0) { if (strlen($comment) === 0) {
// Store NULL in database for empty comments // Store NULL in database for empty comments
$comment = null; $comment = null;
} }
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) { if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg()); throw new Exception('While binding comment: ' . $db->lastErrorMsg());
@@ -985,7 +986,7 @@ if ($_POST['action'] == 'get_groups') {
// Send added and ignored lists // Send added and ignored lists
$msg = "<b>Ignored duplicated adlists: " . $ignored . "</b><br>" . $ignored_list; $msg = "<b>Ignored duplicated adlists: " . $ignored . "</b><br>" . $ignored_list;
if ($added_list != "") { if ($added_list != "") {
$msg .= "<br><b>Added adlists: " . $added . "</b><br>" . $added_list; $msg .= "<br><b>Added adlists: " . $added . "</b><br>" . $added_list;
} }
$msg .= "<br><b>Total: " . $total . " adlist(s) processed.</b>"; $msg .= "<br><b>Total: " . $total . " adlist(s) processed.</b>";
JSON_warning($msg); JSON_warning($msg);
@@ -1010,7 +1011,7 @@ if ($_POST['action'] == 'get_groups') {
$status = intval($_POST['status']); $status = intval($_POST['status']);
if ($status !== 0) { if ($status !== 0) {
$status = 1; $status = 1;
} }
if (!$stmt->bindValue(':enabled', $status, SQLITE3_INTEGER)) { if (!$stmt->bindValue(':enabled', $status, SQLITE3_INTEGER)) {
@@ -1019,8 +1020,8 @@ if ($_POST['action'] == 'get_groups') {
$comment = html_entity_decode($_POST['comment']); $comment = html_entity_decode($_POST['comment']);
if (strlen($comment) === 0) { if (strlen($comment) === 0) {
// Store NULL in database for empty comments // Store NULL in database for empty comments
$comment = null; $comment = null;
} }
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) { if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg()); throw new Exception('While binding comment: ' . $db->lastErrorMsg());
@@ -1160,15 +1161,15 @@ if ($_POST['action'] == 'get_groups') {
$difference = $after - $before; $difference = $after - $before;
if($total === 1) { if($total === 1) {
if($difference !== 1) { if($difference !== 1) {
$msg = "Not adding ". htmlentities(utf8_encode($domain)) . " as it is already on the list"; $msg = "Not adding ". htmlentities(utf8_encode($domain)) . " as it is already on the list";
} else { } else {
$msg = "Added " . htmlentities(utf8_encode($domain)); $msg = "Added " . htmlentities(utf8_encode($domain));
} }
} else { } else {
if($difference !== $total) { if($difference !== $total) {
$msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)"; $msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)";
} else { } else {
$msg = "Added " . $total . " domains"; $msg = "Added " . $total . " domains";
} }
} }
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/auth.php"; require "scripts/pi-hole/php/auth.php";
require "scripts/pi-hole/php/password.php"; require "scripts/pi-hole/php/password.php";
+61 -59
View File
@@ -4,71 +4,73 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
?> ?>
<div class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2" style="float:none"> <div class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2" style="float:none">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<div class="text-center"> <div class="text-center">
<img src="img/logo.svg" alt="Pi-hole logo" class="loginpage-logo"> <img src="img/logo.svg" alt="Pi-hole logo" class="loginpage-logo">
</div>
<br>
<div class="panel-title text-center"><span class="logo-lg" style="font-size: 25px;">Pi-<b>hole</b></span></div>
<p class="login-box-msg">Sign in to start your session</p>
<div id="cookieInfo" class="panel-title text-center text-red" style="font-size: 150%" hidden>Verify that cookies are allowed for <code><?php echo $_SERVER['HTTP_HOST']; ?></code></div>
<?php if ($wrongpassword) { ?>
<div class="form-group has-error login-box-msg">
<label class="control-label"><i class="fa fa-times-circle"></i> Wrong password!</label>
</div>
<?php } ?>
</div>
<div class="panel-body">
<form action="" id="loginform" method="post">
<div class="form-group login-options has-feedback<?php if ($wrongpassword) { ?> has-error<?php } ?>">
<div class="pwd-field">
<input type="password" id="loginpw" name="pw" class="form-control" placeholder="Password" autocomplete="current-password" autofocus>
<span class="fa fa-key form-control-feedback"></span>
</div>
<div>
<input type="checkbox" id="logincookie" name="persistentlogin">
<label for="logincookie">Remember me for 7 days</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary form-control"><i class="fas fa-sign-in-alt"></i>&nbsp;&nbsp;&nbsp;Log in</button>
</div>
<div class="box login-help hidden-xs">
<p><kbd>Return</kbd> &#10140; Log in and go to requested page (<?php echo $scriptname; ?>)</p>
<p><kbd>Ctrl</kbd> + <kbd>Return</kbd> &#10140; Log in and go to Settings page</p>
</div>
<div class="row">
<div class="col-xs-12">
<div class="box box-<?php if (!$wrongpassword) { ?>info collapsed-box<?php } else { ?>danger<?php }?>">
<div class="box-header with-border pointer no-user-select" data-widget="collapse">
<h3 class="box-title">Forgot password?</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool"><i class="fa <?php if ($wrongpassword) { ?>fa-minus<?php } else { ?>fa-plus<?php } ?>"></i>
</button>
</div>
</div>
<div class="box-body">
<p>
After installing Pi-hole for the first time, a password is generated and displayed to the user. The
password cannot be retrieved later on, but it is possible to set a new password (or explicitly disable
the password by setting an empty password) using the command
</p>
<pre>sudo pihole -a -p</pre>
</div>
</div> </div>
</div> <br>
<div class="panel-title text-center"><span class="logo-lg" style="font-size: 25px;">Pi-<b>hole</b></span></div>
<p class="login-box-msg">Sign in to start your session</p>
<div id="cookieInfo" class="panel-title text-center text-red" style="font-size: 150%" hidden>Verify that cookies are allowed for <code><?php echo $_SERVER['HTTP_HOST']; ?></code></div>
<?php if ($wrongpassword) { ?>
<div class="form-group has-error login-box-msg">
<label class="control-label"><i class="fa fa-times-circle"></i> Wrong password!</label>
</div>
<?php } ?>
</div>
<div class="panel-body">
<form action="" id="loginform" method="post">
<div class="form-group login-options has-feedback<?php if ($wrongpassword) { ?> has-error<?php } ?>">
<div class="pwd-field">
<input type="password" id="loginpw" name="pw" class="form-control" placeholder="Password" autocomplete="current-password" autofocus>
<span class="fa fa-key form-control-feedback"></span>
</div>
<div>
<input type="checkbox" id="logincookie" name="persistentlogin">
<label for="logincookie">Remember me for 7 days</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary form-control"><i class="fas fa-sign-in-alt"></i>&nbsp;&nbsp;&nbsp;Log in</button>
</div>
<div class="box login-help hidden-xs">
<p><kbd>Return</kbd> &#10140; Log in and go to requested page (<?php echo $scriptname; ?>)</p>
<p><kbd>Ctrl</kbd> + <kbd>Return</kbd> &#10140; Log in and go to Settings page</p>
</div>
<div class="row">
<div class="col-xs-12">
<div class="box box-<?php if (!$wrongpassword) { ?>info collapsed-box<?php } else { ?>danger<?php }?>">
<div class="box-header with-border pointer no-user-select" data-widget="collapse">
<h3 class="box-title">Forgot password?</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool"><i class="fa <?php if ($wrongpassword) { ?>fa-minus<?php } else { ?>fa-plus<?php } ?>"></i>
</button>
</div>
</div>
<div class="box-body">
<p>
After installing Pi-hole for the first time, a password is generated and displayed to the user. The
password cannot be retrieved later on, but it is possible to set a new password (or explicitly disable
the password by setting an empty password) using the command
</p>
<pre>sudo pihole -a -p</pre>
</div>
</div>
</div>
</div>
</form>
</div> </div>
</form>
</div> </div>
</div>
</div> </div>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require_once('auth.php'); require_once('auth.php');
require_once('func.php'); require_once('func.php');
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require_once('auth.php'); require_once('auth.php');
require_once('func.php'); require_once('func.php');
+101 -100
View File
@@ -4,118 +4,119 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require_once('func.php'); require_once('func.php');
// Start a new PHP session (or continue an existing one) // Start a new PHP session (or continue an existing one)
// Prevents javascript XSS attacks aimed to steal the session ID // Prevents javascript XSS attacks aimed to steal the session ID
ini_set('session.cookie_httponly', 1); ini_set('session.cookie_httponly', 1);
// Prevent Session ID from being passed through URLs // Prevent Session ID from being passed through URLs
ini_set('session.use_only_cookies', 1); ini_set('session.use_only_cookies', 1);
session_start(); session_start();
// Read setupVars.conf file // Read setupVars.conf file
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf"); $setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
// Try to read password hash from setupVars.conf // Try to read password hash from setupVars.conf
if(isset($setupVars['WEBPASSWORD'])) if(isset($setupVars['WEBPASSWORD']))
{
$pwhash = $setupVars['WEBPASSWORD'];
}
else
{
$pwhash = "";
}
// If the user wants to log out, we free all session variables currently registered
// and delete any persistent cookie.
if(isset($_GET["logout"]))
{
session_unset();
setcookie('persistentlogin', '', 1);
header('Location: index.php');
exit();
}
$wrongpassword = false;
$auth = false;
// Test if password is set
if(strlen($pwhash) > 0)
{
// Check for and authorize from persistent cookie
if (isset($_COOKIE["persistentlogin"]))
{ {
$pwhash = $setupVars['WEBPASSWORD']; if (hash_equals($pwhash, $_COOKIE["persistentlogin"]))
}
else
{
$pwhash = "";
}
// If the user wants to log out, we free all session variables currently registered
// and delete any persistent cookie.
if(isset($_GET["logout"]))
{
session_unset();
setcookie('persistentlogin', '', 1);
header('Location: index.php');
exit();
}
$wrongpassword = false;
$auth = false;
// Test if password is set
if(strlen($pwhash) > 0)
{
// Check for and authorize from persistent cookie
if (isset($_COOKIE["persistentlogin"]))
{ {
if (hash_equals($pwhash, $_COOKIE["persistentlogin"])) $auth = true;
{ // Refresh cookie with new expiry
$auth = true; // setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly )
// Refresh cookie with new expiry setcookie('persistentlogin', $pwhash, time()+60*60*24*7, null, null, null, true );
// setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly )
setcookie('persistentlogin', $pwhash, time()+60*60*24*7, null, null, null, true );
}
else
{
// Invalid cookie
$auth = false;
setcookie('persistentlogin', '', 1);
}
}
// Compare doubly hashes password input with saved hash
else if(isset($_POST["pw"]))
{
$postinput = hash('sha256',hash('sha256',$_POST["pw"]));
if(hash_equals($pwhash, $postinput))
{
// Regenerate session ID to prevent session fixation
session_regenerate_id();
// Clear the old session
$_SESSION = array();
// Set hash in new session
$_SESSION["hash"] = $pwhash;
// Set persistent cookie if selected
if (isset($_POST['persistentlogin']))
{
// setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly )
setcookie('persistentlogin', $pwhash, time()+60*60*24*7, null, null, null, true );
}
// Login successful, redirect the user to the homepage to discard the POST request
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['QUERY_STRING'] === 'login') {
header('Location: index.php');
exit();
}
$auth = true;
}
else
{
$wrongpassword = true;
}
}
// Compare auth hash with saved hash
else if (isset($_SESSION["hash"]))
{
if(hash_equals($pwhash, $_SESSION["hash"]))
$auth = true;
}
// API can use the hash to get data without logging in via plain-text password
else if (isset($api) && isset($_GET["auth"]))
{
if(hash_equals($pwhash, $_GET["auth"]))
$auth = true;
} }
else else
{ {
// Password or hash wrong // Invalid cookie
$auth = false; $auth = false;
setcookie('persistentlogin', '', 1);
} }
} }
// Compare doubly hashes password input with saved hash
else if(isset($_POST["pw"]))
{
$postinput = hash('sha256',hash('sha256',$_POST["pw"]));
if(hash_equals($pwhash, $postinput))
{
// Regenerate session ID to prevent session fixation
session_regenerate_id();
// Clear the old session
$_SESSION = array();
// Set hash in new session
$_SESSION["hash"] = $pwhash;
// Set persistent cookie if selected
if (isset($_POST['persistentlogin']))
{
// setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly )
setcookie('persistentlogin', $pwhash, time()+60*60*24*7, null, null, null, true );
}
// Login successful, redirect the user to the homepage to discard the POST request
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['QUERY_STRING'] === 'login') {
header('Location: index.php');
exit();
}
$auth = true;
}
else
{
$wrongpassword = true;
}
}
// Compare auth hash with saved hash
else if (isset($_SESSION["hash"]))
{
if(hash_equals($pwhash, $_SESSION["hash"]))
$auth = true;
}
// API can use the hash to get data without logging in via plain-text password
else if (isset($api) && isset($_GET["auth"]))
{
if(hash_equals($pwhash, $_GET["auth"]))
$auth = true;
}
else else
{ {
// No password set // Password or hash wrong
$auth = true; $auth = false;
} }
}
else
{
// No password set
$auth = true;
}
?> ?>
+5 -3
View File
@@ -4,11 +4,13 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
while (ob_get_level() > 0) { while (ob_get_level() > 0) {
ob_end_flush(); ob_end_flush();
} }
require_once("func.php"); require_once("func.php");
ini_set("output_buffering", "0"); ini_set("output_buffering", "0");
ob_implicit_flush(true); ob_implicit_flush(true);
@@ -17,9 +19,9 @@ header('Cache-Control: no-cache');
function echoEvent($datatext) { function echoEvent($datatext) {
if(!isset($_GET["IE"])) if(!isset($_GET["IE"]))
echo "data:".implode("\ndata:", explode("\n", $datatext))."\n\n"; echo "data:".implode("\ndata:", explode("\n", $datatext))."\n\n";
else else
echo $datatext; echo $datatext;
} }
// Test if domain is set // Test if domain is set
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require_once("func.php"); require_once("func.php");
+165 -163
View File
@@ -49,16 +49,16 @@
?> ?>
<br/> <br/>
<?php <?php
if ($celsius >= -273.15) { if ($celsius >= -273.15) {
// Only show temp info if any data is available --> // Only show temp info if any data is available -->
$tempcolor = "text-vivid-blue"; $tempcolor = "text-vivid-blue";
if (isset($temperaturelimit) && $celsius > $temperaturelimit) { if (isset($temperaturelimit) && $celsius > $temperaturelimit) {
$tempcolor = "text-red"; $tempcolor = "text-red";
} }
echo '<span id="temperature"><i class="fa fa-w fa-fire '.$tempcolor.'" style="width: 1em !important"></i> '; echo '<span id="temperature"><i class="fa fa-w fa-fire '.$tempcolor.'" style="width: 1em !important"></i> ';
echo 'Temp:&nbsp;<span id="rawtemp" hidden>' .$celsius. '</span>'; echo 'Temp:&nbsp;<span id="rawtemp" hidden>' .$celsius. '</span>';
echo '<span id="tempdisplay"></span></span>'; echo '<span id="tempdisplay"></span></span>';
} }
?> ?>
</div> </div>
</div> </div>
@@ -80,7 +80,8 @@
<!-- Logout --> <!-- Logout -->
<?php <?php
// Show Logout button if $auth is set and authorization is required // Show Logout button if $auth is set and authorization is required
if(strlen($pwhash) > 0 && $auth) { ?> if(strlen($pwhash) > 0 && $auth) {
?>
<li> <li>
<a href="?logout"> <a href="?logout">
<i class="fa fa-fw menu-icon fa-sign-out-alt"></i> <span>Logout</span> <i class="fa fa-fw menu-icon fa-sign-out-alt"></i> <span>Logout</span>
@@ -90,7 +91,8 @@
<!-- Login --> <!-- Login -->
<?php <?php
// Show Login button if $auth is *not* set and authorization is required // Show Login button if $auth is *not* set and authorization is required
if(strlen($pwhash) > 0 && !$auth) { ?> if(strlen($pwhash) > 0 && !$auth) {
?>
<li<?php if($scriptname === "login"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "login"){ ?> class="active"<?php } ?>>
<a href="index.php?login"> <a href="index.php?login">
<i class="fa fa-fw menu-icon fa-user"></i> <span>Login</span> <i class="fa fa-fw menu-icon fa-user"></i> <span>Login</span>
@@ -108,29 +110,29 @@
</li> </li>
<!-- Long-term database --> <!-- Long-term database -->
<li class="treeview<?php if($scriptname === "db_queries.php" || $scriptname === "db_lists.php" || $scriptname === "db_graph.php"){ ?> active<?php } ?>"> <li class="treeview<?php if($scriptname === "db_queries.php" || $scriptname === "db_lists.php" || $scriptname === "db_graph.php"){ ?> active<?php } ?>">
<a href="#"> <a href="#">
<i class="fa fa-fw menu-icon fa-history"></i> <span>Long-term Data</span> <i class="fa fa-fw menu-icon fa-history"></i> <span>Long-term Data</span>
<span class="pull-right-container"> <span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i> <i class="fa fa-angle-left pull-right"></i>
</span> </span>
</a> </a>
<ul class="treeview-menu"> <ul class="treeview-menu">
<li<?php if($scriptname === "db_graph.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "db_graph.php"){ ?> class="active"<?php } ?>>
<a href="db_graph.php"> <a href="db_graph.php">
<i class="fa fa-fw menu-icon fa-chart-bar"></i> Graphics <i class="fa fa-fw menu-icon fa-chart-bar"></i> Graphics
</a> </a>
</li> </li>
<li<?php if($scriptname === "db_queries.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "db_queries.php"){ ?> class="active"<?php } ?>>
<a href="db_queries.php"> <a href="db_queries.php">
<i class="fa fa-fw menu-icon fa-file-alt"></i> Query Log <i class="fa fa-fw menu-icon fa-file-alt"></i> Query Log
</a> </a>
</li> </li>
<li<?php if($scriptname === "db_lists.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "db_lists.php"){ ?> class="active"<?php } ?>>
<a href="db_lists.php"> <a href="db_lists.php">
<i class="fa fa-fw menu-icon fa-list"></i> Top Lists <i class="fa fa-fw menu-icon fa-list"></i> Top Lists
</a> </a>
</li> </li>
</ul> </ul>
</li> </li>
<li class="header text-uppercase">Group Management</li> <li class="header text-uppercase">Group Management</li>
@@ -159,152 +161,152 @@
<li class="header text-uppercase">DNS Control</li> <li class="header text-uppercase">DNS Control</li>
<!-- Enable/Disable Blocking --> <!-- Enable/Disable Blocking -->
<li id="pihole-disable" class="treeview"<?php if ($pistatus == "0") { ?> hidden<?php } ?>> <li id="pihole-disable" class="treeview"<?php if ($pistatus == "0") { ?> hidden<?php } ?>>
<a href="#"> <a href="#">
<i class="fa fa-fw menu-icon fa-stop"></i> <span>Disable Blocking&nbsp;&nbsp;&nbsp;<span id="flip-status-disable"></span></span> <i class="fa fa-fw menu-icon fa-stop"></i> <span>Disable Blocking&nbsp;&nbsp;&nbsp;<span id="flip-status-disable"></span></span>
<span class="pull-right-container"> <span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i> <i class="fa fa-angle-left pull-right"></i>
</span> </span>
</a> </a>
<ul class="treeview-menu"> <ul class="treeview-menu">
<li> <li>
<a href="#" id="pihole-disable-indefinitely"> <a href="#" id="pihole-disable-indefinitely">
<i class="fa fa-fw menu-icon fa-infinity"></i> Indefinitely <i class="fa fa-fw menu-icon fa-infinity"></i> Indefinitely
</a> </a>
</li> </li>
<li> <li>
<a href="#" id="pihole-disable-10s"> <a href="#" id="pihole-disable-10s">
<i class="fa fa-fw menu-icon fa-clock"></i> For 10 seconds <i class="fa fa-fw menu-icon fa-clock"></i> For 10 seconds
</a> </a>
</li> </li>
<li> <li>
<a href="#" id="pihole-disable-30s"> <a href="#" id="pihole-disable-30s">
<i class="fa fa-fw menu-icon fa-clock"></i> For 30 seconds <i class="fa fa-fw menu-icon fa-clock"></i> For 30 seconds
</a> </a>
</li> </li>
<li> <li>
<a href="#" id="pihole-disable-5m"> <a href="#" id="pihole-disable-5m">
<i class="fa fa-fw menu-icon fas fa-clock"></i> For 5 minutes <i class="fa fa-fw menu-icon fas fa-clock"></i> For 5 minutes
</a> </a>
</li> </li>
<li> <li>
<a href="#" id="pihole-disable-cst" data-toggle="modal" data-target="#customDisableModal"> <a href="#" id="pihole-disable-cst" data-toggle="modal" data-target="#customDisableModal">
<i class="fa fa-fw menu-icon fa-user-clock"></i> Custom time <i class="fa fa-fw menu-icon fa-user-clock"></i> Custom time
</a> </a>
</li> </li>
</ul> </ul>
<!-- <a href="#" id="flip-status"><i class="fa fa-stop"></i> <span>Disable</span></a> --> <!-- <a href="#" id="flip-status"><i class="fa fa-stop"></i> <span>Disable</span></a> -->
</li> </li>
<li id="pihole-enable" class="treeview"<?php if (!in_array($pistatus,["0","-1","-2"])) { ?> hidden<?php } ?>> <li id="pihole-enable" class="treeview"<?php if (!in_array($pistatus,["0","-1","-2"])) { ?> hidden<?php } ?>>
<a href="#"> <a href="#">
<i class="fa fa-fw menu-icon fa-play"></i> <i class="fa fa-fw menu-icon fa-play"></i>
<span id="enableLabel">Enable Blocking&nbsp;&nbsp;&nbsp; <span id="enableLabel">Enable Blocking&nbsp;&nbsp;&nbsp;
<span id="flip-status-enable"></span> <span id="flip-status-enable"></span>
</span> </span>
</a> </a>
</li> </li>
<!-- Local DNS Records --> <!-- Local DNS Records -->
<li class="treeview <?php if(in_array($scriptname, array("dns_records.php", "cname_records.php"))){ ?>active<?php } ?>"> <li class="treeview <?php if(in_array($scriptname, array("dns_records.php", "cname_records.php"))){ ?>active<?php } ?>">
<a href="#"> <a href="#">
<i class="fa fa-fw menu-icon fa-address-book"></i> <span>Local DNS</span> <i class="fa fa-fw menu-icon fa-address-book"></i> <span>Local DNS</span>
<span class="pull-right-container"> <span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i> <i class="fa fa-angle-left pull-right"></i>
</span> </span>
</a> </a>
<ul class="treeview-menu"> <ul class="treeview-menu">
<li<?php if($scriptname === "dns_records.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "dns_records.php"){ ?> class="active"<?php } ?>>
<a href="dns_records.php"> <a href="dns_records.php">
<i class="fa fa-fw menu-icon fa-address-book"></i> DNS Records <i class="fa fa-fw menu-icon fa-address-book"></i> DNS Records
</a> </a>
</li> </li>
<li<?php if($scriptname === "cname_records.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "cname_records.php"){ ?> class="active"<?php } ?>>
<a href="cname_records.php"> <a href="cname_records.php">
<i class="fa fa-fw menu-icon fa-address-book"></i> CNAME Records <i class="fa fa-fw menu-icon fa-address-book"></i> CNAME Records
</a> </a>
</li> </li>
</ul> </ul>
</li> </li>
<li class="header text-uppercase">System</li> <li class="header text-uppercase">System</li>
<!-- Tools --> <!-- Tools -->
<li class="treeview<?php if (in_array($scriptname, array("messages.php", "gravity.php", "queryads.php", "auditlog.php", "taillog.php", "taillog-FTL.php", "debug.php", "network.php"))){ ?> active<?php } ?>"> <li class="treeview<?php if (in_array($scriptname, array("messages.php", "gravity.php", "queryads.php", "auditlog.php", "taillog.php", "taillog-FTL.php", "debug.php", "network.php"))){ ?> active<?php } ?>">
<a href="#"> <a href="#">
<i class="fa fa-fw menu-icon fa-tools"></i> <span>Tools</span> <i class="fa fa-fw menu-icon fa-tools"></i> <span>Tools</span>
<span class="warning-count hidden"></span> <span class="warning-count hidden"></span>
<span class="pull-right-container"> <span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i> <i class="fa fa-angle-left pull-right"></i>
</span> </span>
</a> </a>
<ul class="treeview-menu"> <ul class="treeview-menu">
<!-- Pi-hole diagnosis --> <!-- Pi-hole diagnosis -->
<li<?php if($scriptname === "messages.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "messages.php"){ ?> class="active"<?php } ?>>
<a href="messages.php"> <a href="messages.php">
<i class="fa fa-fw menu-icon fa-file-medical-alt"></i> Pi-hole diagnosis <i class="fa fa-fw menu-icon fa-file-medical-alt"></i> Pi-hole diagnosis
<span class="pull-right-container warning-count hidden"></span> <span class="pull-right-container warning-count hidden"></span>
</a> </a>
</li> </li>
<!-- Run gravity.sh --> <!-- Run gravity.sh -->
<li<?php if($scriptname === "gravity.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "gravity.php"){ ?> class="active"<?php } ?>>
<a href="gravity.php"> <a href="gravity.php">
<i class="fa fa-fw menu-icon fa-arrow-circle-down"></i> Update Gravity <i class="fa fa-fw menu-icon fa-arrow-circle-down"></i> Update Gravity
</a> </a>
</li> </li>
<!-- Query Lists --> <!-- Query Lists -->
<li<?php if($scriptname === "queryads.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "queryads.php"){ ?> class="active"<?php } ?>>
<a href="queryads.php"> <a href="queryads.php">
<i class="fa fa-fw menu-icon fa-search"></i> Search Adlists <i class="fa fa-fw menu-icon fa-search"></i> Search Adlists
</a> </a>
</li> </li>
<!-- Audit log --> <!-- Audit log -->
<li<?php if($scriptname === "auditlog.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "auditlog.php"){ ?> class="active"<?php } ?>>
<a href="auditlog.php"> <a href="auditlog.php">
<i class="fa fa-fw menu-icon fa-balance-scale"></i> Audit log <i class="fa fa-fw menu-icon fa-balance-scale"></i> Audit log
</a> </a>
</li> </li>
<!-- Tail pihole.log --> <!-- Tail pihole.log -->
<li<?php if($scriptname === "taillog.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "taillog.php"){ ?> class="active"<?php } ?>>
<a href="taillog.php"> <a href="taillog.php">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" preserveAspectRatio="xMidYMid meet" height="14" viewBox="0 0 200 200" class="svg-inline--fa custom-menu-icon fa-w-20 fa-fw menu-icon"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" preserveAspectRatio="xMidYMid meet" height="14" viewBox="0 0 200 200" class="svg-inline--fa custom-menu-icon fa-w-20 fa-fw menu-icon">
<g> <g>
<linearGradient id="svg_1_1_" gradientUnits="userSpaceOnUse" x1="-317.0903" y1="393.5137" x2="-316.0898" y2="393.5137" gradientTransform="matrix(94.8803 0 0 -56.7359 30129.9492 22362.8691)"> <linearGradient id="svg_1_1_" gradientUnits="userSpaceOnUse" x1="-317.0903" y1="393.5137" x2="-316.0898" y2="393.5137" gradientTransform="matrix(94.8803 0 0 -56.7359 30129.9492 22362.8691)">
<stop offset="0.051" style="stop-color:currentColor;stop-opacity:0.6"/> <stop offset="0.051" style="stop-color:currentColor;stop-opacity:0.6"/>
<stop offset="0.95" style="stop-color:currentColor"/> <stop offset="0.95" style="stop-color:currentColor"/>
</linearGradient> </linearGradient>
<path id="svg_1" fill="url(#svg_1_1_)" d="M89.247,64.579C66.298,62.131,43.179,44.785,41.354,8.083 c35.612,0,54.656,21.082,56.496,54.486c6.734-40.069,38.301-35.372,38.301-35.372c1.499,22.708-17.148,36.475-38.301,37.621 c-5.942-12.521-41.541-43.238-41.541-43.238c-0.042-0.036-0.104-0.03-0.14,0.011c-0.024,0.028-0.03,0.067-0.016,0.102 C56.153,21.694,90.506,51.619,89.247,64.579"/> <path id="svg_1" fill="url(#svg_1_1_)" d="M89.247,64.579C66.298,62.131,43.179,44.785,41.354,8.083 c35.612,0,54.656,21.082,56.496,54.486c6.734-40.069,38.301-35.372,38.301-35.372c1.499,22.708-17.148,36.475-38.301,37.621 c-5.942-12.521-41.541-43.238-41.541-43.238c-0.042-0.036-0.104-0.03-0.14,0.011c-0.024,0.028-0.03,0.067-0.016,0.102 C56.153,21.694,90.506,51.619,89.247,64.579"/>
<path id="svg_2" opacity="0.6" fill="currentColor" d="M100,191.916c-2.221-0.127-22.949-0.92-24.208-24.208 c-1.019-14.148,10.159-24.576,10.159-38.314c-2.533-34.253-48.431-30.009-48.431,0c-0.019,7.5,2.949,14.699,8.249,20.007 l34.197,34.211c5.307,5.299,12.506,8.268,20.006,8.248"/> <path id="svg_2" opacity="0.6" fill="currentColor" d="M100,191.916c-2.221-0.127-22.949-0.92-24.208-24.208 c-1.019-14.148,10.159-24.576,10.159-38.314c-2.533-34.253-48.431-30.009-48.431,0c-0.019,7.5,2.949,14.699,8.249,20.007 l34.197,34.211c5.307,5.299,12.506,8.268,20.006,8.248"/>
<path id="svg_3" fill="currentColor" d="M162.48,129.408c-0.127,2.221-0.92,22.949-24.209,24.208 c-14.148,1.019-24.59-10.159-38.314-10.159c-34.254,2.533-30.009,48.417,0,48.417c7.5,0.019,14.699-2.949,20.006-8.249 l34.226-34.197c5.299-5.307,8.268-12.506,8.248-20.006"/> <path id="svg_3" fill="currentColor" d="M162.48,129.408c-0.127,2.221-0.92,22.949-24.209,24.208 c-14.148,1.019-24.59-10.159-38.314-10.159c-34.254,2.533-30.009,48.417,0,48.417c7.5,0.019,14.699-2.949,20.006-8.249 l34.226-34.197c5.299-5.307,8.268-12.506,8.248-20.006"/>
<path id="svg_4" opacity="0.6" fill="currentColor" d="M100,66.928c2.221,0.127,22.949,0.919,24.209,24.208 c1.018,14.149-10.159,24.576-10.159,38.314c2.532,34.254,48.417,30.009,48.417,0c0.019-7.5-2.949-14.698-8.25-20.006 l-34.211-34.226c-5.307-5.3-12.506-8.268-20.006-8.249"/> <path id="svg_4" opacity="0.6" fill="currentColor" d="M100,66.928c2.221,0.127,22.949,0.919,24.209,24.208 c1.018,14.149-10.159,24.576-10.159,38.314c2.532,34.254,48.417,30.009,48.417,0c0.019-7.5-2.949-14.698-8.25-20.006 l-34.211-34.226c-5.307-5.3-12.506-8.268-20.006-8.249"/>
<path id="svg_5" fill="currentColor" d="M37.633,129.408c0.127-2.222,0.92-22.949,24.208-24.209 c14.148-1.019,24.59,10.159,38.314,10.159c34.254-2.575,30.009-48.417,0-48.417c-7.5-0.019-14.699,2.949-20.006,8.249 l-34.226,34.212c-5.299,5.307-8.268,12.506-8.249,20.006"/> <path id="svg_5" fill="currentColor" d="M37.633,129.408c0.127-2.222,0.92-22.949,24.208-24.209 c14.148-1.019,24.59,10.159,38.314,10.159c34.254-2.575,30.009-48.417,0-48.417c-7.5-0.019-14.699,2.949-20.006,8.249 l-34.226,34.212c-5.299,5.307-8.268,12.506-8.249,20.006"/>
</g> </g>
</svg> </svg>
Tail pihole.log Tail pihole.log
</a> </a>
</li> </li>
<!-- Tail FTL.log --> <!-- Tail FTL.log -->
<li<?php if($scriptname === "taillog-FTL.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "taillog-FTL.php"){ ?> class="active"<?php } ?>>
<a href="taillog-FTL.php"> <a href="taillog-FTL.php">
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" preserveAspectRatio="xMidYMid meet" height="14" viewBox="0 0 400 340" class="svg-inline--fa custom-menu-icon fa-w-20 fa-fw menu-icon"> <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" preserveAspectRatio="xMidYMid meet" height="14" viewBox="0 0 400 340" class="svg-inline--fa custom-menu-icon fa-w-20 fa-fw menu-icon">
<g fill="currentColor"> <g fill="currentColor">
<path opacity=".6" d="M42.315 11h111.078l-7.381 31.378H34.898L42.315 11z"/> <path opacity=".6" d="M42.315 11h111.078l-7.381 31.378H34.898L42.315 11z"/>
<path d="M237.368 42.207q-13.098 62.242-26.23 124.486h-37.354q13.135-62.244 26.23-124.486h-39.652l7.381-31.174h132.055l-7.639 31.174h-54.791zm87.03 94.016L351.124 11h-37.18q-16.584 77.846-33.199 155.693h103.356v-30.47h-59.703zM32.428 67.509l-22.316 99.184h31.807l16.068-67.908h59.41l7.381-31.326-92.35.05z"/> <path d="M237.368 42.207q-13.098 62.242-26.23 124.486h-37.354q13.135-62.244 26.23-124.486h-39.652l7.381-31.174h132.055l-7.639 31.174h-54.791zm87.03 94.016L351.124 11h-37.18q-16.584 77.846-33.199 155.693h103.356v-30.47h-59.703zM32.428 67.509l-22.316 99.184h31.807l16.068-67.908h59.41l7.381-31.326-92.35.05z"/>
<path opacity=".6" d="M10 186.2a283.868 283.868 0 0 1 42.976-2.992c26.697 0 44.014 4.806 57.58 15.023 14.604 10.853 23.782 28.17 23.782 52.991 0 26.914-9.798 45.487-23.364 56.96-14.806 12.31-37.348 18.154-64.882 18.154A276.442 276.442 0 0 1 10 324.29V186.2zm31.922 114.726a57.564 57.564 0 0 0 11.054.636c28.79.201 47.564-15.659 47.564-49.24.217-29.208-16.899-44.65-44.231-44.65a66.665 66.665 0 0 0-14.387 1.241v92.013zm113.283 24.015V184.325h37.209l29.146 51.595a408.098 408.098 0 0 1 22.945 48.06h.62a523.847 523.847 0 0 1-2.697-58.618v-41.037h29.208V324.94h-33.394l-30.046-54.262a523.459 523.459 0 0 1-24.402-49.611l-.62.201c.821 18.605 1.24 38.402 1.24 61.348v42.355l-29.209-.03zm145.004-32.759a81.099 81.099 0 0 0 35.27 8.76c14.605 0 22.326-6.047 22.326-15.225 0-8.76-6.682-13.767-23.581-19.829-23.364-8.123-38.604-21.069-38.604-41.518 0-23.984 20.03-42.355 53.208-42.355a86.246 86.246 0 0 1 35.89 7.1l-7.1 25.658a66.804 66.804 0 0 0-29.456-6.666c-13.783 0-20.45 6.201-20.45 13.55 0 8.976 7.923 12.945 26.077 19.829 24.806 9.178 36.511 22.108 36.511 41.937 0 23.58-18.155 43.611-56.743 43.611-16.077 0-31.921-4.186-39.86-8.558l6.512-26.294z"/> <path opacity=".6" d="M10 186.2a283.868 283.868 0 0 1 42.976-2.992c26.697 0 44.014 4.806 57.58 15.023 14.604 10.853 23.782 28.17 23.782 52.991 0 26.914-9.798 45.487-23.364 56.96-14.806 12.31-37.348 18.154-64.882 18.154A276.442 276.442 0 0 1 10 324.29V186.2zm31.922 114.726a57.564 57.564 0 0 0 11.054.636c28.79.201 47.564-15.659 47.564-49.24.217-29.208-16.899-44.65-44.231-44.65a66.665 66.665 0 0 0-14.387 1.241v92.013zm113.283 24.015V184.325h37.209l29.146 51.595a408.098 408.098 0 0 1 22.945 48.06h.62a523.847 523.847 0 0 1-2.697-58.618v-41.037h29.208V324.94h-33.394l-30.046-54.262a523.459 523.459 0 0 1-24.402-49.611l-.62.201c.821 18.605 1.24 38.402 1.24 61.348v42.355l-29.209-.03zm145.004-32.759a81.099 81.099 0 0 0 35.27 8.76c14.605 0 22.326-6.047 22.326-15.225 0-8.76-6.682-13.767-23.581-19.829-23.364-8.123-38.604-21.069-38.604-41.518 0-23.984 20.03-42.355 53.208-42.355a86.246 86.246 0 0 1 35.89 7.1l-7.1 25.658a66.804 66.804 0 0 0-29.456-6.666c-13.783 0-20.45 6.201-20.45 13.55 0 8.976 7.923 12.945 26.077 19.829 24.806 9.178 36.511 22.108 36.511 41.937 0 23.58-18.155 43.611-56.743 43.611-16.077 0-31.921-4.186-39.86-8.558l6.512-26.294z"/>
</g> </g>
</svg> </svg>
Tail FTL.log Tail FTL.log
</a> </a>
</li> </li>
<!-- Generate debug log --> <!-- Generate debug log -->
<li<?php if($scriptname === "debug.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "debug.php"){ ?> class="active"<?php } ?>>
<a href="debug.php"> <a href="debug.php">
<i class="fa fa-fw menu-icon fa-ambulance"></i> Generate debug log <i class="fa fa-fw menu-icon fa-ambulance"></i> Generate debug log
</a> </a>
</li> </li>
<!-- Network --> <!-- Network -->
<li<?php if($scriptname === "network.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "network.php"){ ?> class="active"<?php } ?>>
<a href="network.php"> <a href="network.php">
<i class="fa fa-fw menu-icon fa-network-wired"></i> Network <i class="fa fa-fw menu-icon fa-network-wired"></i> Network
</a> </a>
</li> </li>
</ul> </ul>
</li> </li>
<!-- Settings --> <!-- Settings -->
<li<?php if($scriptname === "settings.php"){ ?> class="active"<?php } ?>> <li<?php if($scriptname === "settings.php"){ ?> class="active"<?php } ?>>
@@ -315,8 +317,8 @@
<?php } ?> <?php } ?>
<li class="header text-uppercase">Support</li> <li class="header text-uppercase">Support</li>
<!-- Docs --> <!-- Docs -->
<li> <li>
<a href="https://docs.pi-hole.net/" rel="noopener" target="_blank" class="menu-support"> <a href="https://docs.pi-hole.net/" rel="noopener" target="_blank" class="menu-support">
<i class="fa fa-fw menu-icon fa-question-circle"></i> <span>Documentation</span> <i class="fa fa-fw menu-icon fa-question-circle"></i> <span>Documentation</span>
</a> </a>
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require "password.php"; require "password.php";
if(!$auth) die("Not authorized"); if(!$auth) die("Not authorized");
+2 -1
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require "password.php"; require "password.php";
require "auth.php"; // Also imports func.php require "auth.php"; // Also imports func.php
+10 -8
View File
@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
// Array of available themes and their description // Array of available themes and their description
$available_themes = array(); $available_themes = array();
@@ -28,15 +29,15 @@ if(isset($setupVars['WEBTHEME']))
// May be overwritten by settings tab // May be overwritten by settings tab
if(isset($_POST["field"]) && if(isset($_POST["field"]) &&
$_POST["field"] === "webUI" && $_POST["field"] === "webUI" &&
isset($_POST["webtheme"])) { isset($_POST["webtheme"])) {
$webtheme = $_POST["webtheme"]; $webtheme = $_POST["webtheme"];
} }
if(!array_key_exists($webtheme,$available_themes)) { if(!array_key_exists($webtheme,$available_themes)) {
// Fallback to default (light) theme is property is not set // Fallback to default (light) theme is property is not set
// or requested theme is not among the available // or requested theme is not among the available
$webtheme = "default-auto"; $webtheme = "default-auto";
} }
$darkmode = $available_themes[$webtheme][1]; $darkmode = $available_themes[$webtheme][1];
@@ -45,8 +46,9 @@ $theme = $available_themes[$webtheme][2];
function theme_selection() { function theme_selection() {
global $available_themes, $webtheme; global $available_themes, $webtheme;
foreach ($available_themes as $key => $value) { foreach ($available_themes as $key => $value) {
?><div><input type="radio" name="webtheme" value="<?php echo $key; ?>" id="webtheme_<?php echo $key; ?>" <?php if ($key === $webtheme){ ?>checked<?php } ?>> ?><div><input type="radio" name="webtheme" value="<?php echo $key; ?>" id="webtheme_<?php echo $key; ?>" <?php if ($key === $webtheme){ ?>checked<?php } ?>>
<label for="webtheme_<?php echo $key; ?>"><strong><?php echo $value[0]; ?></strong></label></div><?php <label for="webtheme_<?php echo $key; ?>"><strong><?php echo $value[0]; ?></strong></label></div>
<?php
} }
} }
?> ?>
+76 -76
View File
@@ -6,92 +6,92 @@ $GitHubVersions = "/etc/pihole/GitHubVersions";
if(!is_readable($localversions) || !is_readable($localbranches) || !is_readable($GitHubVersions)) if(!is_readable($localversions) || !is_readable($localbranches) || !is_readable($GitHubVersions))
{ {
$core_branch = "master"; $core_branch = "master";
$core_current = "N/A"; $core_current = "N/A";
$core_update = false; $core_update = false;
$web_branch = "master"; $web_branch = "master";
$web_current = "N/A"; $web_current = "N/A";
$web_update = false; $web_update = false;
$FTL_current = "N/A"; $FTL_current = "N/A";
$FTL_update = false; $FTL_update = false;
} }
else else
{ {
$versions = explode(" ", file_get_contents($localversions)); $versions = explode(" ", file_get_contents($localversions));
$branches = explode(" ", file_get_contents($localbranches)); $branches = explode(" ", file_get_contents($localbranches));
$GitHubversions = explode(" ", file_get_contents($GitHubVersions)); $GitHubversions = explode(" ", file_get_contents($GitHubVersions));
/********** Get Pi-hole core branch / version / commit **********/ /********** Get Pi-hole core branch / version / commit **********/
// Check if on a dev branch // Check if on a dev branch
$core_branch = $branches[0]; $core_branch = $branches[0];
if($core_branch !== "master") { if($core_branch !== "master") {
$core_current = "vDev"; $core_current = "vDev";
$core_commit = $versions[0]; $core_commit = $versions[0];
} }
else { else {
$core_current = explode("-",$versions[0])[0]; $core_current = explode("-",$versions[0])[0];
} }
/********** Get Pi-hole web branch / version / commit **********/ /********** Get Pi-hole web branch / version / commit **********/
$web_branch = $branches[1]; $web_branch = $branches[1];
if($web_branch !== "master") { if($web_branch !== "master") {
$web_current = "vDev"; $web_current = "vDev";
$web_commit = $versions[1]; $web_commit = $versions[1];
} }
else { else {
$web_current = explode("-",$versions[1])[0]; $web_current = explode("-",$versions[1])[0];
} }
/********** Get Pi-hole FTL (not a git repository) **********/ /********** Get Pi-hole FTL (not a git repository) **********/
$FTL_branch = $branches[2]; $FTL_branch = $branches[2];
if(substr($versions[2], 0, 4) === "vDev") { if(substr($versions[2], 0, 4) === "vDev") {
$FTL_current = "vDev"; $FTL_current = "vDev";
$FTL_commit = $versions[2]; $FTL_commit = $versions[2];
} }
else { else {
$FTL_current = $versions[2]; $FTL_current = $versions[2];
} }
// Get data from GitHub // Get data from GitHub
$core_latest = $GitHubversions[0]; $core_latest = $GitHubversions[0];
$web_latest = $GitHubversions[1]; $web_latest = $GitHubversions[1];
$FTL_latest = $GitHubversions[2]; $FTL_latest = $GitHubversions[2];
// Core version comparison // Core version comparison
if($core_current !== "vDev") if($core_current !== "vDev")
{ {
// This logic allows the local core version to be newer than the upstream version // This logic allows the local core version to be newer than the upstream version
// The update indicator is only shown if the upstream version is NEWER // The update indicator is only shown if the upstream version is NEWER
$core_update = (version_compare($core_current, $core_latest) < 0); $core_update = (version_compare($core_current, $core_latest) < 0);
} }
else else
{ {
$core_update = false; $core_update = false;
} }
// Web version comparison // Web version comparison
if($web_current !== "vDev") if($web_current !== "vDev")
{ {
// This logic allows the local core version to be newer than the upstream version // This logic allows the local core version to be newer than the upstream version
// The update indicator is only shown if the upstream version is NEWER // The update indicator is only shown if the upstream version is NEWER
$web_update = (version_compare($web_current, $web_latest) < 0); $web_update = (version_compare($web_current, $web_latest) < 0);
} }
else else
{ {
$web_update = false; $web_update = false;
} }
// FTL version comparison // FTL version comparison
// This logic allows the local core version to be newer than the upstream version // This logic allows the local core version to be newer than the upstream version
// The update indicator is only shown if the upstream version is NEWER // The update indicator is only shown if the upstream version is NEWER
if($FTL_current !== "vDev") if($FTL_current !== "vDev")
{ {
$FTL_update = (version_compare($FTL_current, $FTL_latest) < 0); $FTL_update = (version_compare($FTL_current, $FTL_latest) < 0);
} }
else else
{ {
$FTL_update = false; $FTL_update = false;
} }
} }
?> ?>
+167 -154
View File
@@ -1,13 +1,17 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php"; require "scripts/pi-hole/php/header.php";
require "scripts/pi-hole/php/savesettings.php"; require "scripts/pi-hole/php/savesettings.php";
require_once "scripts/pi-hole/php/FTL.php"; require_once "scripts/pi-hole/php/FTL.php";
// Reread ini file as things might have been changed // Reread ini file as things might have been changed
// DEFAULT_FTLCONFFILE is set in "scripts/pi-hole/php/FTL.php"; // DEFAULT_FTLCONFFILE is set in "scripts/pi-hole/php/FTL.php";
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf"); $setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
@@ -38,10 +42,12 @@ if (empty($timezone)) {
if (isset($_POST["submit"])) { if (isset($_POST["submit"])) {
if ($_POST["submit"] == "saveupdate") { if ($_POST["submit"] == "saveupdate") {
// If that is the case -> refresh to the gravity page and start updating immediately // If that is the case -> refresh to the gravity page and start updating immediately
?> ?>
<meta http-equiv="refresh" content="1;url=gravity.php?go"> <meta http-equiv="refresh" content="1;url=gravity.php?go">
<?php } <?php
} ?> }
}
?>
<?php if (strlen($success) > 0) { ?> <?php if (strlen($success) > 0) { ?>
<div id="alInfo" class="alert alert-info alert-dismissible fade in" role="alert"> <div id="alInfo" class="alert alert-info alert-dismissible fade in" role="alert">
@@ -318,7 +324,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div> </div>
<p class="hidden-md hidden-lg"></p> <p class="hidden-md hidden-lg"></p>
<div class="col-md-4"> <div class="col-md-4">
<button type="button" class="btn btn-warning confirm-flusharp btn-block">Flush network table</button> <button type="button" class="btn btn-warning confirm-flusharp btn-block">Flush network table</button>
</div> </div>
<p class="hidden-md hidden-lg"></p> <p class="hidden-md hidden-lg"></p>
<div class="col-md-4"> <div class="col-md-4">
@@ -464,9 +470,10 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">From</div> <div class="input-group-addon">From</div>
<input type="text" class="form-control DHCPgroup" name="from" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <input type="text" class="form-control DHCPgroup" name="from"
value="<?php echo $DHCPstart; ?>" autocomplete="off" spellcheck="false" autocapitalize="none"
<?php if (!$DHCP){ ?>disabled<?php } ?>> autocorrect="off" value="<?php echo $DHCPstart; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -474,9 +481,10 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">To</div> <div class="input-group-addon">To</div>
<input type="text" class="form-control DHCPgroup" name="to" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <input type="text" class="form-control DHCPgroup" name="to"
value="<?php echo $DHCPend; ?>" autocomplete="off" spellcheck="false" autocapitalize="none"
<?php if (!$DHCP){ ?>disabled<?php } ?>> autocorrect="off" value="<?php echo $DHCPend; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -487,9 +495,10 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">Router</div> <div class="input-group-addon">Router</div>
<input type="text" class="form-control DHCPgroup" name="router" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <input type="text" class="form-control DHCPgroup" name="router"
value="<?php echo $DHCProuter; ?>" autocomplete="off" spellcheck="false" autocapitalize="none"
<?php if (!$DHCP){ ?>disabled<?php } ?>> autocorrect="off" value="<?php echo $DHCProuter; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -511,8 +520,8 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">Domain</div> <div class="input-group-addon">Domain</div>
<input type="text" class="form-control DHCPgroup" name="domain" <input type="text" class="form-control DHCPgroup" name="domain"
value="<?php echo $piHoleDomain; ?>" value="<?php echo $piHoleDomain; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>> <?php if (!$DHCP){ ?>disabled<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -524,9 +533,9 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">Lease time in hours</div> <div class="input-group-addon">Lease time in hours</div>
<input type="number" class="form-control DHCPgroup" <input type="number" class="form-control DHCPgroup"
name="leasetime" name="leasetime"
id="leasetime" value="<?php echo $DHCPleasetime; ?>" id="leasetime" value="<?php echo $DHCPleasetime; ?>"
data-mask <?php if (!$DHCP){ ?>disabled<?php } ?>> data-mask <?php if (!$DHCP){ ?>disabled<?php } ?>>
</div> </div>
</div> </div>
<p>Hint: 0 = infinite, 24 = one day, 168 = one week, 744 = one month, 8760 = one year</p> <p>Hint: 0 = infinite, 24 = one day, 168 = one week, 744 = one month, 8760 = one year</p>
@@ -534,8 +543,8 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div><input type="checkbox" name="DHCP_rapid_commit" id="DHCP_rapid_commit" class="DHCPgroup" <?php if ($DHCP_rapid_commit){ ?>checked<?php }; if (!$DHCP){ ?> disabled<?php } ?>>&nbsp;<label for="DHCP_rapid_commit"><strong>Enable DHCPv4 rapid commit (fast address assignment)</strong></label></div> <div><input type="checkbox" name="DHCP_rapid_commit" id="DHCP_rapid_commit" class="DHCPgroup" <?php if ($DHCP_rapid_commit){ ?>checked<?php }; if (!$DHCP){ ?> disabled<?php } ?>>&nbsp;<label for="DHCP_rapid_commit"><strong>Enable DHCPv4 rapid commit (fast address assignment)</strong></label></div>
<div><input type="checkbox" name="useIPv6" id="useIPv6" class="DHCPgroup" <?php if ($DHCPIPv6){ ?>checked<?php }; if (!$DHCP){ ?> disabled<?php } ?>>&nbsp;<label for="useIPv6"><strong>Enable IPv6 support (SLAAC + RA)</strong></label></div> <div><input type="checkbox" name="useIPv6" id="useIPv6" class="DHCPgroup" <?php if ($DHCPIPv6){ ?>checked<?php }; if (!$DHCP){ ?> disabled<?php } ?>>&nbsp;<label for="useIPv6"><strong>Enable IPv6 support (SLAAC + RA)</strong></label></div>
</div> </div>
</div> </div>
</div> </div>
@@ -678,10 +687,10 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</tfoot> </tfoot>
</table> </table>
<p>Specifying the MAC address is mandatory and only one entry per MAC <p>Specifying the MAC address is mandatory and only one entry per MAC
address is allowed. If the IP address is omitted and a host name is address is allowed. If the IP address is omitted and a host name is
given, the IP address will still be generated dynamically and the given, the IP address will still be generated dynamically and the
specified host name will be used. If the host name is omitted, only specified host name will be used. If the host name is omitted, only
a static lease will be added.</p> a static lease will be added.</p>
</div> </div>
</div> </div>
</div> </div>
@@ -719,46 +728,48 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<table class="table table-bordered"> <table class="table table-bordered">
<thead> <thead>
<tr> <tr>
<th colspan="2">IPv4</th> <th colspan="2">IPv4</th>
<th colspan="2">IPv6</th> <th colspan="2">IPv6</th>
<th>Name</th> <th>Name</th>
</tr> </tr>
</thead> </thead>
<?php foreach ($DNSserverslist as $key => $value) { ?> <tbody>
<tr> <?php foreach ($DNSserverslist as $key => $value) { ?>
<?php if (isset($value["v4_1"])) { ?> <tr>
<td title="<?php echo $value["v4_1"]; ?>"> <?php if (isset($value["v4_1"])) { ?>
<div><input type="checkbox" name="DNSserver<?php echo $value["v4_1"]; ?>" id="DNS4server<?php echo $value["v4_1"]; ?>" value="true" <?php if (in_array($value["v4_1"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS4server<?php echo $value["v4_1"]; ?>"></label></div> <td title="<?php echo $value["v4_1"]; ?>">
</td> <div><input type="checkbox" name="DNSserver<?php echo $value["v4_1"]; ?>" id="DNS4server<?php echo $value["v4_1"]; ?>" value="true" <?php if (in_array($value["v4_1"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS4server<?php echo $value["v4_1"]; ?>"></label></div>
<?php } else { ?> </td>
<td></td> <?php } else { ?>
<?php } ?> <td></td>
<?php if (isset($value["v4_2"])) { ?> <?php } ?>
<td title="<?php echo $value["v4_2"]; ?>"> <?php if (isset($value["v4_2"])) { ?>
<div><input type="checkbox" name="DNSserver<?php echo $value["v4_2"]; ?>" id="DNS4server<?php echo $value["v4_2"]; ?>" value="true" <?php if (in_array($value["v4_2"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS4server<?php echo $value["v4_2"]; ?>"></label></div> <td title="<?php echo $value["v4_2"]; ?>">
</td> <div><input type="checkbox" name="DNSserver<?php echo $value["v4_2"]; ?>" id="DNS4server<?php echo $value["v4_2"]; ?>" value="true" <?php if (in_array($value["v4_2"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS4server<?php echo $value["v4_2"]; ?>"></label></div>
<?php } else { ?> </td>
<td></td> <?php } else { ?>
<?php } ?> <td></td>
<?php if (isset($value["v6_1"])) { ?> <?php } ?>
<td title="<?php echo $value["v6_1"]; ?>"> <?php if (isset($value["v6_1"])) { ?>
<div><input type="checkbox" name="DNSserver<?php echo $value["v6_1"]; ?>" id="DNS6server<?php echo $value["v6_1"]; ?>" value="true" <?php if (in_array($value["v6_1"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS6server<?php echo $value["v6_1"]; ?>"></label></div> <td title="<?php echo $value["v6_1"]; ?>">
</td> <div><input type="checkbox" name="DNSserver<?php echo $value["v6_1"]; ?>" id="DNS6server<?php echo $value["v6_1"]; ?>" value="true" <?php if (in_array($value["v6_1"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS6server<?php echo $value["v6_1"]; ?>"></label></div>
<?php } else { ?> </td>
<td></td> <?php } else { ?>
<?php } ?> <td></td>
<?php if (isset($value["v6_2"])) { ?> <?php } ?>
<td title="<?php echo $value["v6_2"]; ?>"> <?php if (isset($value["v6_2"])) { ?>
<div><input type="checkbox" name="DNSserver<?php echo $value["v6_2"]; ?>" id="DNS6server<?php echo $value["v6_2"]; ?>" value="true" <?php if (in_array($value["v6_2"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS6server<?php echo $value["v6_2"]; ?>"></label></div> <td title="<?php echo $value["v6_2"]; ?>">
</td> <div><input type="checkbox" name="DNSserver<?php echo $value["v6_2"]; ?>" id="DNS6server<?php echo $value["v6_2"]; ?>" value="true" <?php if (in_array($value["v6_2"], $DNSactive)){ ?>checked<?php } ?>><label for="DNS6server<?php echo $value["v6_2"]; ?>"></label></div>
<?php } else { ?> </td>
<td></td> <?php } else { ?>
<?php } ?> <td></td>
<td><?php echo $key; ?></td> <?php } ?>
</tr> <td><?php echo $key; ?></td>
<?php } ?> </tr>
<?php } ?>
</tbody>
</table> </table>
<p>ECS (Extended Client Subnet) defines a mechanism for recursive resolvers to send partial client IP address information to authoritative DNS name servers. Content Delivery Networks (CDNs) and latency-sensitive services use this to give geo-located responses when responding to name lookups coming through public DNS resolvers. <em>Note that ECS may result in reduced privacy.</em></p> <p>ECS (Extended Client Subnet) defines a mechanism for recursive resolvers to send partial client IP address information to authoritative DNS name servers. Content Delivery Networks (CDNs) and latency-sensitive services use this to give geo-located responses when responding to name lookups coming through public DNS resolvers. <em>Note that ECS may result in reduced privacy.</em></p>
</div> </div>
@@ -782,7 +793,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div> </div>
<div class="col-md-11"> <div class="col-md-11">
<input type="text" name="custom1val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <input type="text" name="custom1val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if (isset($custom1)){ ?>value="<?php echo $custom1; ?>"<?php } ?>> <?php if (isset($custom1)){ ?>value="<?php echo $custom1; ?>"<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -795,7 +806,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div> </div>
<div class="col-md-11"> <div class="col-md-11">
<input type="text" name="custom2val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <input type="text" name="custom2val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if (isset($custom2)){ ?>value="<?php echo $custom2; ?>"<?php } ?>> <?php if (isset($custom2)){ ?>value="<?php echo $custom2; ?>"<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -810,7 +821,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div> </div>
<div class="col-md-11"> <div class="col-md-11">
<input type="text" name="custom3val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <input type="text" name="custom3val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if (isset($custom3)){ ?>value="<?php echo $custom3; ?>"<?php } ?>> <?php if (isset($custom3)){ ?>value="<?php echo $custom3; ?>"<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -823,7 +834,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div> </div>
<div class="col-md-11"> <div class="col-md-11">
<input type="text" name="custom4val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <input type="text" name="custom4val" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if (isset($custom4)){ ?>value="<?php echo $custom4; ?>"<?php } ?>> <?php if (isset($custom4)){ ?>value="<?php echo $custom4; ?>"<?php } ?>>
</div> </div>
</div> </div>
</div> </div>
@@ -844,7 +855,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<h4>Recommended setting</h4> <h4>Recommended setting</h4>
<div> <div>
<input type="radio" name="DNSinterface" id="DNSinterface1" value="local" <input type="radio" name="DNSinterface" id="DNSinterface1" value="local"
<?php if ($DNSinterface == "local"){ ?>checked<?php } ?>> <?php if ($DNSinterface == "local"){ ?>checked<?php } ?>>
<label for="DNSinterface1"><strong>Allow only local requests</strong><br>Allows only queries from devices that are at most one hop away (local devices)</label> <label for="DNSinterface1"><strong>Allow only local requests</strong><br>Allows only queries from devices that are at most one hop away (local devices)</label>
</div> </div>
</div> </div>
@@ -852,17 +863,17 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<h4>Potentially dangerous options</h4>Make sure your Pi-hole is properly firewalled! <h4>Potentially dangerous options</h4>Make sure your Pi-hole is properly firewalled!
<div> <div>
<input type="radio" name="DNSinterface" id="DNSinterface2" value="single" <input type="radio" name="DNSinterface" id="DNSinterface2" value="single"
<?php if ($DNSinterface == "single"){ ?>checked<?php } ?>> <?php if ($DNSinterface == "single"){ ?>checked<?php } ?>>
<label for="DNSinterface2"><strong>Respond only on interface <?php echo htmlentities($piHoleInterface); ?></strong></label> <label for="DNSinterface2"><strong>Respond only on interface <?php echo htmlentities($piHoleInterface); ?></strong></label>
</div> </div>
<div> <div>
<input type="radio" name="DNSinterface" id="DNSinterface3" value="bind" <input type="radio" name="DNSinterface" id="DNSinterface3" value="bind"
<?php if ($DNSinterface == "bind"){ ?>checked<?php } ?>> <?php if ($DNSinterface == "bind"){ ?>checked<?php } ?>>
<label for="DNSinterface3"><strong>Bind only to interface <?php echo htmlentities($piHoleInterface); ?></strong></label> <label for="DNSinterface3"><strong>Bind only to interface <?php echo htmlentities($piHoleInterface); ?></strong></label>
</div> </div>
<div> <div>
<input type="radio" name="DNSinterface" id="DNSinterface4" value="all" <input type="radio" name="DNSinterface" id="DNSinterface4" value="all"
<?php if ($DNSinterface == "all"){ ?>checked<?php } ?>> <?php if ($DNSinterface == "all"){ ?>checked<?php } ?>>
<label for="DNSinterface4"><strong>Permit all origins</strong></label> <label for="DNSinterface4"><strong>Permit all origins</strong></label>
</div> </div>
<p>These options are dangerous on devices <p>These options are dangerous on devices
@@ -892,108 +903,110 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<input type="checkbox" name="DNSrequiresFQDN" id="DNSrequiresFQDN" title="domain-needed" <?php if ($DNSrequiresFQDN){ ?>checked<?php } ?>> <input type="checkbox" name="DNSrequiresFQDN" id="DNSrequiresFQDN" title="domain-needed" <?php if ($DNSrequiresFQDN){ ?>checked<?php } ?>>
<label for="DNSrequiresFQDN"><strong>Never forward non-FQDN <code>A</code> and <code>AAAA</code> queries</strong></label> <label for="DNSrequiresFQDN"><strong>Never forward non-FQDN <code>A</code> and <code>AAAA</code> queries</strong></label>
<p>When there is a Pi-hole domain set and this box is <p>When there is a Pi-hole domain set and this box is
ticked, this asks FTL that this domain is purely ticked, this asks FTL that this domain is purely
local and FTL may answer queries from <code>/etc/hosts</code> or DHCP leases local and FTL may answer queries from <code>/etc/hosts</code> or DHCP leases
but should never forward queries on that domain to any upstream servers. but should never forward queries on that domain to any upstream servers.
If Conditional Forwarding is enabled, unticking this box may cause a partial If Conditional Forwarding is enabled, unticking this box may cause a partial
DNS loop under certain circumstances (e.g. if a client would send TLD DNSSEC queries).</p> DNS loop under certain circumstances (e.g. if a client would send TLD DNSSEC queries).</p>
</div> </div>
<div> <div>
<input type="checkbox" name="DNSbogusPriv" id="DNSbogusPriv" title="bogus-priv" <?php if ($DNSbogusPriv){ ?>checked<?php } ?>> <input type="checkbox" name="DNSbogusPriv" id="DNSbogusPriv" title="bogus-priv" <?php if ($DNSbogusPriv){ ?>checked<?php } ?>>
<label for="DNSbogusPriv"><strong>Never forward reverse lookups for private IP ranges</strong></label> <label for="DNSbogusPriv"><strong>Never forward reverse lookups for private IP ranges</strong></label>
<p>All reverse lookups for private IP ranges (i.e., <code>192.168.0.x/24</code>, etc.) <p>All reverse lookups for private IP ranges (i.e., <code>192.168.0.x/24</code>, etc.)
which are not found in <code>/etc/hosts</code> or the DHCP leases are answered which are not found in <code>/etc/hosts</code> or the DHCP leases are answered
with "no such domain" rather than being forwarded upstream. The set with "no such domain" rather than being forwarded upstream. The set
of prefixes affected is the list given in <a href="https://tools.ietf.org/html/rfc6303">RFC6303</a>.</p> of prefixes affected is the list given in <a href="https://tools.ietf.org/html/rfc6303">RFC6303</a>.</p>
<p><strong>Important</strong>: Enabling these two options may increase your privacy, <p><strong>Important</strong>: Enabling these two options may increase your privacy,
but may also prevent you from being able to access but may also prevent you from being able to access
local hostnames if the Pi-hole is not used as DHCP server.</p> local hostnames if the Pi-hole is not used as DHCP server.</p>
</div> </div>
<br> <br>
<div> <div>
<input type="checkbox" name="DNSSEC" id="DNSSEC" <?php if ($DNSSEC){ ?>checked<?php } ?>> <input type="checkbox" name="DNSSEC" id="DNSSEC" <?php if ($DNSSEC){ ?>checked<?php } ?>>
<label for="DNSSEC"><strong>Use DNSSEC</strong></label> <label for="DNSSEC"><strong>Use DNSSEC</strong></label>
<p>Validate DNS replies and cache DNSSEC data. When forwarding DNS <p>Validate DNS replies and cache DNSSEC data. When forwarding DNS
queries, Pi-hole requests the DNSSEC records needed to validate queries, Pi-hole requests the DNSSEC records needed to validate
the replies. If a domain fails validation or the upstream does not the replies. If a domain fails validation or the upstream does not
support DNSSEC, this setting can cause issues resolving domains. support DNSSEC, this setting can cause issues resolving domains.
Use an upstream DNS server which supports DNSSEC when activating DNSSEC. Note that Use an upstream DNS server which supports DNSSEC when activating DNSSEC. Note that
the size of your log might increase significantly the size of your log might increase significantly
when enabling DNSSEC. A DNSSEC resolver test can be found when enabling DNSSEC. A DNSSEC resolver test can be found
<a href="https://dnssec.vs.uni-due.de/" rel="noopener" target="_blank">here</a>.</p> <a href="https://dnssec.vs.uni-due.de/" rel="noopener" target="_blank">here</a>.</p>
</div> </div>
<br> <br>
<h4><a id="ratelimit"></a>Rate-limiting</h4> <h4><a id="ratelimit"></a>Rate-limiting</h4>
<p>Block clients making more than <input type="number" name="rate_limit_count" value="<?=$rate_limit_count?>" min="0" step="10" style="width: 5em;"> queries within <p>Block clients making more than <input type="number" name="rate_limit_count" value="<?=$rate_limit_count?>" min="0" step="10" style="width: 5em;"> queries within
<input type="number" name="rate_limit_interval" value="<?=$rate_limit_interval?>" min="0" step="10" style="width: 4em;"> seconds.</p> <input type="number" name="rate_limit_interval" value="<?=$rate_limit_interval?>" min="0" step="10" style="width: 4em;"> seconds.</p>
<p>When a client makes too many queries in too short time, it <p>When a client makes too many queries in too short time, it
gets rate-limited. Rate-limited queries are answered with a gets rate-limited. Rate-limited queries are answered with a
<code>REFUSED</code> reply and not further processed by FTL <code>REFUSED</code> reply and not further processed by FTL
and prevent Pi-holes getting overwhelmed by rogue clients. and prevent Pi-holes getting overwhelmed by rogue clients.
It is important to note that rate-limiting is happening on a It is important to note that rate-limiting is happening on a
per-client basis. Other clients can continue to use FTL while per-client basis. Other clients can continue to use FTL while
rate-limited clients are short-circuited at the same time.</p> rate-limited clients are short-circuited at the same time.</p>
<p>Rate-limiting may be disabled altogether by setting both <p>Rate-limiting may be disabled altogether by setting both
values to zero. See values to zero. See
<a href="https://docs.pi-hole.net/ftldns/configfile/#rate_limit" target="_blank">our documentation</a> <a href="https://docs.pi-hole.net/ftldns/configfile/#rate_limit" target="_blank">our documentation</a>
for further details.</p> for further details.</p>
<br> <br>
<h4>Conditional forwarding</h4> <h4>Conditional forwarding</h4>
<p>If not configured as your DHCP server, Pi-hole typically won't be able to <p>If not configured as your DHCP server, Pi-hole typically won't be able to
determine the names of devices on your local network. As a determine the names of devices on your local network. As a
result, tables such as Top Clients will only show IP addresses.</p> result, tables such as Top Clients will only show IP addresses.</p>
<p>One solution for this is to configure Pi-hole to forward these <p>One solution for this is to configure Pi-hole to forward these
requests to your DHCP server (most likely your router), but only for devices on your requests to your DHCP server (most likely your router), but only for devices on your
home network. To configure this we will need to know the IP home network. To configure this we will need to know the IP
address of your DHCP server and which addresses belong to your local network. address of your DHCP server and which addresses belong to your local network.
Exemplary input is given below as placeholder in the text boxes (if empty).</p> Exemplary input is given below as placeholder in the text boxes (if empty).</p>
<p>If your local network spans 192.168.0.1 - 192.168.0.255, then you will have to input <p>If your local network spans 192.168.0.1 - 192.168.0.255, then you will have to input
<code>192.168.0.0/24</code>. If your local network is 192.168.47.1 - 192.168.47.255, it will <code>192.168.0.0/24</code>. If your local network is 192.168.47.1 - 192.168.47.255, it will
be <code>192.168.47.0/24</code> and similar. If your network is larger, the CIDR has to be be <code>192.168.47.0/24</code> and similar. If your network is larger, the CIDR has to be
different, for instance a range of 10.8.0.1 - 10.8.255.255 results in <code>10.8.0.0/16</code>, different, for instance a range of 10.8.0.1 - 10.8.255.255 results in <code>10.8.0.0/16</code>,
whereas an even wider network of 10.0.0.1 - 10.255.255.255 results in <code>10.0.0.0/8</code>. whereas an even wider network of 10.0.0.1 - 10.255.255.255 results in <code>10.0.0.0/8</code>.
Setting up IPv6 ranges is exactly similar to setting up IPv4 here and fully supported. Setting up IPv6 ranges is exactly similar to setting up IPv4 here and fully supported.
Feel free to reach out to us on our Feel free to reach out to us on our
<a href="https://discourse.pi-hole.net" rel="noopener" target="_blank">Discourse forum</a> <a href="https://discourse.pi-hole.net" rel="noopener" target="_blank">Discourse forum</a>
in case you need any assistance setting up local host name resolution for your particular system.</p> in case you need any assistance setting up local host name resolution for your particular system.</p>
<p>You can also specify a local domain name (like <code>fritz.box</code>) to ensure queries to <p>You can also specify a local domain name (like <code>fritz.box</code>) to ensure queries to
devices ending in your local domain name will not leave your network, however, this is optional. devices ending in your local domain name will not leave your network, however, this is optional.
The local domain name must match the domain name specified The local domain name must match the domain name specified
in your DHCP server for this to work. You can likely find it within the DHCP settings.</p> in your DHCP server for this to work. You can likely find it within the DHCP settings.</p>
<p>Enabling Conditional Forwarding will also forward all hostnames (i.e., non-FQDNs) to the router <p>Enabling Conditional Forwarding will also forward all hostnames (i.e., non-FQDNs) to the router
when "Never forward non-FQDNs" is <em>not</em> enabled.</p> when "Never forward non-FQDNs" is <em>not</em> enabled.</p>
<div class="form-group"> <div class="form-group">
<div> <div>
<input type="checkbox" name="rev_server" id="rev_server" value="rev_server" <?php if(isset($rev_server) && ($rev_server == true)){ ?>checked<?php } ?>> <input type="checkbox" name="rev_server" id="rev_server" value="rev_server" <?php if(isset($rev_server) && ($rev_server == true)){ ?>checked<?php } ?>>
<label for="rev_server"><strong>Use Conditional Forwarding</strong></label> <label for="rev_server"><strong>Use Conditional Forwarding</strong></label>
</div> </div>
<div class="input-group"> <div class="input-group">
<table class="table table-bordered"> <table class="table table-bordered">
<thead> <thead>
<tr> <tr>
<th>Local network in <a href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" target="_blank">CIDR notation</a></th> <th>Local network in <a href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" target="_blank">CIDR notation</a></th>
<th>IP address of your DHCP server (router)</th> <th>IP address of your DHCP server (router)</th>
<th>Local domain name (optional)</th> <th>Local domain name (optional)</th>
</tr> </tr>
</thead> </thead>
<tr> <tbody>
<td> <tr>
<input type="text" name="rev_server_cidr" placeholder="192.168.0.0/16" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <td>
<?php if(isset($rev_server_cidr)){ ?>value="<?php echo $rev_server_cidr; ?>"<?php } ?> <input type="text" name="rev_server_cidr" placeholder="192.168.0.0/16" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>> <?php if(isset($rev_server_cidr)){ ?>value="<?php echo $rev_server_cidr; ?>"<?php } ?>
</td> <?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
<td> </td>
<input type="text" name="rev_server_target" placeholder="192.168.0.1" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <td>
<?php if(isset($rev_server_target)){ ?>value="<?php echo $rev_server_target; ?>"<?php } ?> <input type="text" name="rev_server_target" placeholder="192.168.0.1" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>> <?php if(isset($rev_server_target)){ ?>value="<?php echo $rev_server_target; ?>"<?php } ?>
</td> <?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
<td> </td>
<input type="text" name="rev_server_domain" placeholder="local" class="form-control" data-mask autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <td>
<?php if(isset($rev_server_domain)){ ?>value="<?php echo $rev_server_domain; ?>"<?php } ?> <input type="text" name="rev_server_domain" placeholder="local" class="form-control" data-mask autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>> <?php if(isset($rev_server_domain)){ ?>value="<?php echo $rev_server_domain; ?>"<?php } ?>
</td> <?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
</tr> </td>
</table> </tr>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
@@ -1036,9 +1049,9 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="form-group"> <div class="form-group">
<label>Top Domains / Top Advertisers</label> <label>Top Domains / Top Advertisers</label>
<textarea name="domains" class="form-control" placeholder="Enter one domain per line" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" <textarea name="domains" class="form-control" placeholder="Enter one domain per line" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
rows="4"><?php foreach ($excludedDomains as $domain) { rows="4"><?php foreach ($excludedDomains as $domain) {
echo $domain . "\n"; } echo $domain . "\n"; }
?></textarea> ?></textarea>
</div> </div>
</div> </div>
<div class="col-xs-12 col-sm-6 col-md-12 col-lg-6"> <div class="col-xs-12 col-sm-6 col-md-12 col-lg-6">
@@ -1387,7 +1400,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</span> </span>
</span> </span>
<input type="text" id="zip_filename" class="form-control" <input type="text" id="zip_filename" class="form-control"
placeholder="no file selected" readonly="readonly" tabindex="-1"> placeholder="no file selected" readonly="readonly" tabindex="-1">
</div> </div>
<p class="help-block">Upload only Pi-hole backup files.</p> <p class="help-block">Upload only Pi-hole backup files.</p>
</div> </div>
@@ -1403,7 +1416,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div> </div>
<div class="box-footer clearfix"> <div class="box-footer clearfix">
<button type="submit" class="btn btn-default" name="action" <button type="submit" class="btn btn-default" name="action"
value="in" data-toggle="modal" data-target="#teleporterModal">Restore value="in" data-toggle="modal" data-target="#teleporterModal">Restore
</button> </button>
</div> </div>
</div> </div>
@@ -1420,8 +1433,8 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<label class="control-label">Output:</label> <label class="control-label">Output:</label>
<div class="box no-margin no-border no-shadow"> <div class="box no-margin no-border no-shadow">
<pre class="no-margin no-padding"><iframe class="col-xs-12 no-border no-padding" <pre class="no-margin no-padding"><iframe class="col-xs-12 no-border no-padding"
name="teleporter_iframe" height="100" name="teleporter_iframe" height="100"
tabindex="-1"></iframe></pre> tabindex="-1"></iframe></pre>
<div class="overlay"> <div class="overlay">
<i class="fa fa-spinner fa-pulse"></i> <i class="fa fa-spinner fa-pulse"></i>
</div> </div>
+7 -4
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
<div class="page-header"> <div class="page-header">
@@ -27,5 +30,5 @@
<script src="scripts/pi-hole/js/taillog-FTL.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/taillog-FTL.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>
+7 -4
View File
@@ -1,11 +1,14 @@
<?php /* <?php
/*
* Pi-hole: A black hole for Internet advertisements * Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net) * (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware. * Network-wide ad blocking via your own hardware.
* *
* This file is copyright under the latest version of the EUPL. * This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */ * Please see LICENSE file for your rights under this license.
require "scripts/pi-hole/php/header.php"; */
require "scripts/pi-hole/php/header.php";
?> ?>
<!-- Title --> <!-- Title -->
<div class="page-header"> <div class="page-header">
@@ -27,5 +30,5 @@
<script src="scripts/pi-hole/js/taillog.js?v=<?=$cacheVer?>"></script> <script src="scripts/pi-hole/js/taillog.js?v=<?=$cacheVer?>"></script>
<?php <?php
require "scripts/pi-hole/php/footer.php"; require "scripts/pi-hole/php/footer.php";
?> ?>