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

297
api.php
View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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;
require_once("scripts/pi-hole/php/FTL.php");
@@ -17,181 +18,181 @@ $data = array();
// Common API functions
if (isset($_GET['enable']) && $auth) {
if(isset($_GET["auth"]))
{
if($_GET["auth"] !== $pwhash)
die("Not authorized!");
}
else
{
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
pihole_execute('enable');
$data = array_merge($data, array("status" => "enabled"));
if (file_exists("../custom_disable_timer"))
{
unlink("../custom_disable_timer");
}
if(isset($_GET["auth"]))
{
if($_GET["auth"] !== $pwhash)
die("Not authorized!");
}
else
{
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
pihole_execute('enable');
$data = array_merge($data, array("status" => "enabled"));
if (file_exists("../custom_disable_timer"))
{
unlink("../custom_disable_timer");
}
}
elseif (isset($_GET['disable']) && $auth)
{
if(isset($_GET["auth"]))
{
if($_GET["auth"] !== $pwhash)
die("Not authorized!");
}
else
{
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
$disable = intval($_GET['disable']);
// intval returns the integer value on success, or 0 on failure
if($disable > 0)
{
$timestamp = time();
pihole_execute("disable ".$disable."s");
file_put_contents("../custom_disable_timer",($timestamp+$disable)*1000);
}
else
{
pihole_execute('disable');
if (file_exists("../custom_disable_timer"))
{
unlink("../custom_disable_timer");
}
}
$data = array_merge($data, array("status" => "disabled"));
if(isset($_GET["auth"]))
{
if($_GET["auth"] !== $pwhash)
die("Not authorized!");
}
else
{
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
$disable = intval($_GET['disable']);
// intval returns the integer value on success, or 0 on failure
if($disable > 0)
{
$timestamp = time();
pihole_execute("disable ".$disable."s");
file_put_contents("../custom_disable_timer",($timestamp+$disable)*1000);
}
else
{
pihole_execute('disable');
if (file_exists("../custom_disable_timer"))
{
unlink("../custom_disable_timer");
}
}
$data = array_merge($data, array("status" => "disabled"));
}
elseif (isset($_GET['versions']))
{
// Determine if updates are available for Pi-hole
// using the same script that we use for the footer
// on the dashboard (update notifications are
// suppressed if on development branches)
require "scripts/pi-hole/php/update_checker.php";
$updates = array("core_update" => $core_update,
"web_update" => $web_update,
"FTL_update" => $FTL_update);
$current = array("core_current" => $core_current,
"web_current" => $web_current,
"FTL_current" => $FTL_current);
$latest = array("core_latest" => $core_latest,
"web_latest" => $web_latest,
"FTL_latest" => $FTL_latest);
$branches = array("core_branch" => $core_branch,
"web_branch" => $web_branch,
"FTL_branch" => $FTL_branch);
$data = array_merge($data, $updates);
$data = array_merge($data, $current);
$data = array_merge($data, $latest);
$data = array_merge($data, $branches);
// Determine if updates are available for Pi-hole
// using the same script that we use for the footer
// on the dashboard (update notifications are
// suppressed if on development branches)
require "scripts/pi-hole/php/update_checker.php";
$updates = array("core_update" => $core_update,
"web_update" => $web_update,
"FTL_update" => $FTL_update);
$current = array("core_current" => $core_current,
"web_current" => $web_current,
"FTL_current" => $FTL_current);
$latest = array("core_latest" => $core_latest,
"web_latest" => $web_latest,
"FTL_latest" => $FTL_latest);
$branches = array("core_branch" => $core_branch,
"web_branch" => $web_branch,
"FTL_branch" => $FTL_branch);
$data = array_merge($data, $updates);
$data = array_merge($data, $current);
$data = array_merge($data, $latest);
$data = array_merge($data, $branches);
}
elseif (isset($_GET['list']))
{
if (!$auth)
die("Not authorized!");
if (!$auth)
die("Not authorized!");
if(!isset($_GET["list"]))
die("List has not been specified.");
if(!isset($_GET["list"]))
die("List has not been specified.");
switch ($_GET["list"]) {
case 'black':
$_POST['type'] = ListType::blacklist;
break;
case 'regex_black':
$_POST['type'] = ListType::regex_blacklist;
break;
case 'white':
$_POST['type'] = ListType::whitelist;
break;
case 'regex_white':
$_POST['type'] = ListType::regex_whitelist;
break;
switch ($_GET["list"]) {
case 'black':
$_POST['type'] = ListType::blacklist;
break;
case 'regex_black':
$_POST['type'] = ListType::regex_blacklist;
break;
case 'white':
$_POST['type'] = ListType::whitelist;
break;
case 'regex_white':
$_POST['type'] = ListType::regex_whitelist;
break;
default:
die("Invalid list [supported: black, regex_black, white, regex_white]");
}
default:
die("Invalid list [supported: black, regex_black, white, regex_white]");
}
if (isset($_GET['add']))
{
// Set POST parameters and invoke script to add domain to list
$_POST['domain'] = $_GET['add'];
$_POST['action'] = 'add_domain';
require("scripts/pi-hole/php/groups.php");
}
elseif (isset($_GET['sub']))
{
// Set POST parameters and invoke script to remove domain from list
$_POST['domain'] = $_GET['sub'];
$_POST['action'] = 'delete_domain_string';
require("scripts/pi-hole/php/groups.php");
}
else
{
// Set POST parameters and invoke script to get all domains
$_POST['action'] = 'get_domains';
require("scripts/pi-hole/php/groups.php");
}
if (isset($_GET['add']))
{
// Set POST parameters and invoke script to add domain to list
$_POST['domain'] = $_GET['add'];
$_POST['action'] = 'add_domain';
require("scripts/pi-hole/php/groups.php");
}
elseif (isset($_GET['sub']))
{
// Set POST parameters and invoke script to remove domain from list
$_POST['domain'] = $_GET['sub'];
$_POST['action'] = 'delete_domain_string';
require("scripts/pi-hole/php/groups.php");
}
else
{
// Set POST parameters and invoke script to get all domains
$_POST['action'] = 'get_domains';
require("scripts/pi-hole/php/groups.php");
}
return;
return;
}
elseif(isset($_GET['customdns']) && $auth)
{
if (isset($_GET["auth"])) {
if ($_GET["auth"] !== $pwhash) {
die("Not authorized!");
}
} else {
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
if (isset($_GET["auth"])) {
if ($_GET["auth"] !== $pwhash) {
die("Not authorized!");
}
} else {
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
switch ($_GET["action"]) {
case 'get':
$data = echoCustomDNSEntries();
break;
switch ($_GET["action"]) {
case 'get':
$data = echoCustomDNSEntries();
break;
case 'add':
$data = addCustomDNSEntry();
break;
case 'add':
$data = addCustomDNSEntry();
break;
case 'delete':
$data = deleteCustomDNSEntry();
break;
case 'delete':
$data = deleteCustomDNSEntry();
break;
default:
die("Wrong action");
}
default:
die("Wrong action");
}
}
elseif(isset($_GET['customcname']) && $auth)
{
if (isset($_GET["auth"])) {
if ($_GET["auth"] !== $pwhash) {
die("Not authorized!");
}
} else {
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
if (isset($_GET["auth"])) {
if ($_GET["auth"] !== $pwhash) {
die("Not authorized!");
}
} else {
// Skip token validation if explicit auth string is given
check_csrf($_GET['token']);
}
switch ($_GET["action"]) {
case 'get':
$data = echoCustomCNAMEEntries();
break;
switch ($_GET["action"]) {
case 'get':
$data = echoCustomCNAMEEntries();
break;
case 'add':
$data = addCustomCNAMEEntry();
break;
case 'add':
$data = addCustomCNAMEEntry();
break;
case 'delete':
$data = deleteCustomCNAMEEntry();
break;
case 'delete':
$data = deleteCustomCNAMEEntry();
break;
default:
die("Wrong action");
}
default:
die("Wrong action");
}
}
// Other API functions

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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)) {
die("Direct call to api_FTL.php is not allowed!");
@@ -21,14 +22,14 @@ if (isset($_GET['version'])) {
if (isset($_GET['status'])) {
$return = callFTLAPI("stats");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
if (in_array("status enabled", $return)) {
$data = array_merge($data, array("status" => "enabled"));
} else {
$data = array_merge($data, array("status" => "disabled"));
}
}
if (in_array("status enabled", $return)) {
$data = array_merge($data, array("status" => "enabled"));
} else {
$data = array_merge($data, array("status" => "disabled"));
}
}
}
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");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$stats = [];
foreach ($return as $line) {
$tmp = explode(" ",$line);
$stats = [];
foreach ($return as $line) {
$tmp = explode(" ",$line);
if ($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1]) || $tmp[0] === "status") {
// Expect string response
$stats[$tmp[0]] = $tmp[1];
} elseif (isset($_GET['summary'])) {
// "summary" expects a formmated string response
if ($tmp[0] !== "ads_percentage_today") {
$stats[$tmp[0]] = number_format($tmp[1]);
} else {
$stats[$tmp[0]] = number_format($tmp[1], 1, '.', '');
}
} else {
// Expect float response
$stats[$tmp[0]] = floatval($tmp[1]);
}
if ($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1]) || $tmp[0] === "status") {
// Expect string response
$stats[$tmp[0]] = $tmp[1];
} elseif (isset($_GET['summary'])) {
// "summary" expects a formmated string response
if ($tmp[0] !== "ads_percentage_today") {
$stats[$tmp[0]] = number_format($tmp[1]);
} else {
$stats[$tmp[0]] = number_format($tmp[1], 1, '.', '');
}
} else {
// Expect float response
$stats[$tmp[0]] = floatval($tmp[1]);
}
}
$stats['gravity_last_updated'] = gravity_last_update(true);
$data = array_merge($data,$stats);
}
$stats['gravity_last_updated'] = gravity_last_update(true);
$data = array_merge($data,$stats);
}
}
if (isset($_GET["getMaxlogage"]) && $auth) {
$return = callFTLAPI("maxlogage");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
// Convert seconds to hours and rounds to one decimal place.
$ret = round(intval($return[0]) / 3600, 1);
// Return 24h if value is 0, empty, null or non numeric.
$ret = $ret ?: 24;
// Convert seconds to hours and rounds to one decimal place.
$ret = round(intval($return[0]) / 3600, 1);
// Return 24h if value is 0, empty, null or non numeric.
$ret = $ret ?: 24;
$data = array_merge($data, array("maxlogage" => $ret));
}
$data = array_merge($data, array("maxlogage" => $ret));
}
}
if (isset($_GET['overTimeData10mins'])) {
$return = callFTLAPI("overTime");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$domains_over_time = array();
$ads_over_time = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$domains_over_time[intval($tmp[0])] = intval($tmp[1]);
$ads_over_time[intval($tmp[0])] = intval($tmp[2]);
}
$domains_over_time = array();
$ads_over_time = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$domains_over_time[intval($tmp[0])] = intval($tmp[1]);
$ads_over_time[intval($tmp[0])] = intval($tmp[2]);
}
$result = array(
'domains_over_time' => $domains_over_time,
'ads_over_time' => $ads_over_time
);
$result = array(
'domains_over_time' => $domains_over_time,
'ads_over_time' => $ads_over_time
);
$data = array_merge($data, $result);
}
$data = array_merge($data, $result);
}
}
if (isset($_GET['topItems']) && $auth) {
@@ -109,18 +110,18 @@ if (isset($_GET['topItems']) && $auth) {
}
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$top_queries = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
if (count($tmp) == 2) {
$tmp[2]="";
}
$domain = utf8_encode($tmp[2]);
$top_queries[$domain] = intval($tmp[1]);
$top_queries = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
if (count($tmp) == 2) {
$tmp[2]="";
}
$domain = utf8_encode($tmp[2]);
$top_queries[$domain] = intval($tmp[1]);
}
}
}
if ($_GET['topItems'] === "audit") {
$return = callFTLAPI("top-ads for audit");
@@ -131,26 +132,26 @@ if (isset($_GET['topItems']) && $auth) {
}
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$top_ads = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$domain = utf8_encode($tmp[2]);
if (count($tmp) > 3) {
$top_ads[$domain." (".$tmp[3].")"] = intval($tmp[1]);
} else {
$top_ads[$domain] = intval($tmp[1]);
}
}
$top_ads = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$domain = utf8_encode($tmp[2]);
if (count($tmp) > 3) {
$top_ads[$domain." (".$tmp[3].")"] = intval($tmp[1]);
} else {
$top_ads[$domain] = intval($tmp[1]);
}
}
$result = array(
'top_queries' => $top_queries,
'top_ads' => $top_ads
);
$result = array(
'top_queries' => $top_queries,
'top_ads' => $top_ads
);
$data = array_merge($data, $result);
}
$data = array_merge($data, $result);
}
}
if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth) {
@@ -167,23 +168,23 @@ if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth) {
$return = callFTLAPI("top-clients");
}
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$top_clients = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$clientip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$clientname = utf8_encode($tmp[3]);
$top_clients[$clientname."|".$clientip] = intval($tmp[1]);
} else {
$top_clients[$clientip] = intval($tmp[1]);
}
}
$top_clients = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$clientip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$clientname = utf8_encode($tmp[3]);
$top_clients[$clientname."|".$clientip] = intval($tmp[1]);
} else {
$top_clients[$clientip] = intval($tmp[1]);
}
}
$result = array('top_sources' => $top_clients);
$data = array_merge($data, $result);
}
$result = array('top_sources' => $top_clients);
$data = array_merge($data, $result);
}
}
if (isset($_GET['topClientsBlocked']) && $auth) {
@@ -198,23 +199,23 @@ if (isset($_GET['topClientsBlocked']) && $auth) {
$return = callFTLAPI("top-clients blocked");
}
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$top_clients = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$clientip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$clientname = utf8_encode($tmp[3]);
$top_clients[$clientname."|".$clientip] = intval($tmp[1]);
} else {
$top_clients[$clientip] = intval($tmp[1]);
}
}
$top_clients = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$clientip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$clientname = utf8_encode($tmp[3]);
$top_clients[$clientname."|".$clientip] = intval($tmp[1]);
} else {
$top_clients[$clientip] = intval($tmp[1]);
}
}
$result = array('top_sources_blocked' => $top_clients);
$data = array_merge($data, $result);
}
$result = array('top_sources_blocked' => $top_clients);
$data = array_merge($data, $result);
}
}
if (isset($_GET['getForwardDestinations']) && $auth) {
@@ -224,57 +225,57 @@ if (isset($_GET['getForwardDestinations']) && $auth) {
$return = callFTLAPI("forward-dest");
}
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$forward_dest = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$forwardip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$forwardname = utf8_encode($tmp[3]);
$forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
} else {
$forward_dest[$forwardip] = floatval($tmp[1]);
}
}
$forward_dest = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$forwardip = utf8_encode($tmp[2]);
if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
$forwardname = utf8_encode($tmp[3]);
$forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
} else {
$forward_dest[$forwardip] = floatval($tmp[1]);
}
}
$result = array('forward_destinations' => $forward_dest);
$data = array_merge($data, $result);
}
$result = array('forward_destinations' => $forward_dest);
$data = array_merge($data, $result);
}
}
if (isset($_GET['getQueryTypes']) && $auth) {
$return = callFTLAPI("querytypes");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$querytypes = array();
foreach ($return as $ret) {
$tmp = explode(": ",$ret);
// Reply cannot contain non-ASCII characters
$querytypes[$tmp[0]] = floatval($tmp[1]);
}
$querytypes = array();
foreach ($return as $ret) {
$tmp = explode(": ",$ret);
// Reply cannot contain non-ASCII characters
$querytypes[$tmp[0]] = floatval($tmp[1]);
}
$result = array('querytypes' => $querytypes);
$data = array_merge($data, $result);
}
$result = array('querytypes' => $querytypes);
$data = array_merge($data, $result);
}
}
if (isset($_GET['getCacheInfo']) && $auth) {
$return = callFTLAPI("cacheinfo");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$cacheinfo = array();
foreach ($return as $ret) {
$tmp = explode(": ",$ret);
// Reply cannot contain non-ASCII characters
$cacheinfo[$tmp[0]] = floatval($tmp[1]);
}
$cacheinfo = array();
foreach ($return as $ret) {
$tmp = explode(": ",$ret);
// Reply cannot contain non-ASCII characters
$cacheinfo[$tmp[0]] = floatval($tmp[1]);
}
$result = array('cacheinfo' => $cacheinfo);
$data = array_merge($data, $result);
}
$result = array('cacheinfo' => $cacheinfo);
$data = array_merge($data, $result);
}
}
if (isset($_GET['getAllQueries']) && $auth) {
@@ -304,38 +305,37 @@ if (isset($_GET['getAllQueries']) && $auth) {
}
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
// Set the header
header('Content-type: application/json');
// Set the header
header('Content-type: application/json');
// Start the JSON string
echo '{"data":[';
$first = true;
// Start the JSON string
echo '{"data":[';
$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)
if (!$first) {
echo ",";
} else {
$first = false;
}
$row = str_getcsv($line," ");
// UTF-8 encode domain
$domain = utf8_encode(str_replace("~"," ",$row[2]));
// UTF-8 encode client host name
$client = utf8_encode($row[3]);
$row = str_getcsv($line," ");
// UTF-8 encode domain
$domain = utf8_encode(str_replace("~"," ",$row[2]));
// UTF-8 encode client host name
$client = utf8_encode($row[3]);
// Insert into array and output it in JSON format
// array: time type domain client status dnssecStatus reply response_time CNAMEDomain regexID upstream destination EDE
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();
// Insert into array and output it in JSON format
// array: time type domain client status dnssecStatus reply response_time CNAMEDomain regexID upstream destination EDE
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");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$forward_dest = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$forwardip = utf8_encode($tmp[2]);
if (count($tmp) > 3) {
$forwardname = utf8_encode($tmp[3]);
$forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
} else {
$forward_dest[$forwardip] = floatval($tmp[1]);
}
}
$forward_dest = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
$forwardip = utf8_encode($tmp[2]);
if (count($tmp) > 3) {
$forwardname = utf8_encode($tmp[3]);
$forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
} else {
$forward_dest[$forwardip] = floatval($tmp[1]);
}
}
$result = array('forward_destinations' => $forward_dest);
$data = array_merge($data, $result);
}
$result = array('forward_destinations' => $forward_dest);
$data = array_merge($data, $result);
}
}
if (isset($_GET['overTimeDataQueryTypes']) && $auth) {
$return = callFTLAPI("QueryTypesoverTime");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$over_time = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
for ($i=0; $i < count($tmp)-1; $i++) {
$over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
}
}
$result = array('over_time' => $over_time);
$data = array_merge($data, $result);
}
$over_time = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
for ($i=0; $i < count($tmp)-1; $i++) {
$over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
}
}
$result = array('over_time' => $over_time);
$data = array_merge($data, $result);
}
}
if (isset($_GET['getClientNames']) && $auth) {
$return = callFTLAPI("client-names");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$client_names = array();
foreach ($return as $line) {
$tmp = explode(" ", $line);
$client_names[] = array(
"name" => utf8_encode($tmp[0]),
"ip" => utf8_encode($tmp[1])
);
}
$client_names = array();
foreach ($return as $line) {
$tmp = explode(" ", $line);
$client_names[] = array(
"name" => utf8_encode($tmp[0]),
"ip" => utf8_encode($tmp[1])
);
}
$result = array('clients' => $client_names);
$data = array_merge($data, $result);
}
$result = array('clients' => $client_names);
$data = array_merge($data, $result);
}
}
if (isset($_GET['overTimeDataClients']) && $auth) {
$return = callFTLAPI("ClientsoverTime");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$over_time = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
for ($i=0; $i < count($tmp)-1; $i++) {
$over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
}
}
$result = array('over_time' => $over_time);
$data = array_merge($data, $result);
}
$over_time = array();
foreach ($return as $line) {
$tmp = explode(" ",$line);
for ($i=0; $i < count($tmp)-1; $i++) {
$over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
}
}
$result = array('over_time' => $over_time);
$data = array_merge($data, $result);
}
}
if (isset($_GET['delete_lease']) && $auth) {
$return = callFTLAPI("delete-lease ".$_GET['delete_lease']);
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$data["delete_lease"] = $return[0];
}
$data["delete_lease"] = $return[0];
}
}
if (isset($_GET['dns-port']) && $auth) {
$return = callFTLAPI("dns-port");
if (array_key_exists("FTLnotrunning", $return)) {
$data = array("FTLnotrunning" => true);
$data = array("FTLnotrunning" => true);
} else {
$data["dns-port"] = $return[0];
$data["dns-port"] = $return[0];
}
}
?>

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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;
header('Content-type: application/json');
@@ -27,428 +28,428 @@ $db = SQLite3_connect($QUERYDB);
if(isset($_GET["network"]) && $auth)
{
$network = array();
$results = $db->query('SELECT * FROM network');
$network = array();
$results = $db->query('SELECT * FROM network');
while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{
$id = intval($res["id"]);
while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{
$id = intval($res["id"]);
// Get IP addresses and host names for this device
$res["ip"] = array();
$res["name"] = array();
$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))
{
array_push($res["ip"],$network_address["ip"]);
if($network_address["name"] !== null)
array_push($res["name"],utf8_encode($network_address["name"]));
else
array_push($res["name"],"");
}
$network_addresses->finalize();
// Get IP addresses and host names for this device
$res["ip"] = array();
$res["name"] = array();
$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))
{
array_push($res["ip"],$network_address["ip"]);
if($network_address["name"] !== null)
array_push($res["name"],utf8_encode($network_address["name"]));
else
array_push($res["name"],"");
}
$network_addresses->finalize();
// UTF-8 encode vendor
$res["macVendor"] = utf8_encode($res["macVendor"]);
array_push($network, $res);
}
$results->finalize();
// UTF-8 encode vendor
$res["macVendor"] = utf8_encode($res["macVendor"]);
array_push($network, $res);
}
$results->finalize();
$data = array_merge($data, array('network' => $network));
$data = array_merge($data, array('network' => $network));
}
if (isset($_GET['getAllQueries']) && $auth)
{
$allQueries = array();
if($_GET['getAllQueries'] !== "empty")
{
$from = intval($_GET["from"]);
$until = intval($_GET["until"]);
$allQueries = array();
if($_GET['getAllQueries'] !== "empty")
{
$from = intval($_GET["from"]);
$until = intval($_GET["until"]);
// Use table "query_storage"
// - replace domain ID with domain
// - replace client ID with client name
// - replace forward ID with forward destination
$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(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 .= " ) 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 .= " status, reply_type, reply_time, dnssec";
$dbquery .= " FROM query_storage q";
$dbquery .= " WHERE timestamp >= :from AND timestamp <= :until ";
if(isset($_GET["types"]))
{
$types = $_GET["types"];
if(preg_match("/^[0-9]+(?:,[0-9]+)*$/", $types) === 1)
{
// Append selector to DB query. The used regex ensures
// that only numbers, separated by commas are accepted
// to avoid code injection and other malicious things
// We accept only valid lists like "1,2,3"
// We reject ",2,3", "1,2," and similar arguments
$dbquery .= "AND status IN (".$types.") ";
}
else
{
die("Error. Selector types specified using an invalid format.");
}
}
$dbquery .= "ORDER BY timestamp ASC";
$stmt = $db->prepare($dbquery);
$stmt->bindValue(":from", intval($from), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($until), SQLITE3_INTEGER);
$results = $stmt->execute();
// Use table "query_storage"
// - replace domain ID with domain
// - replace client ID with client name
// - replace forward ID with forward destination
$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(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 .= " ) 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 .= " status, reply_type, reply_time, dnssec";
$dbquery .= " FROM query_storage q";
$dbquery .= " WHERE timestamp >= :from AND timestamp <= :until ";
if(isset($_GET["types"]))
{
$types = $_GET["types"];
if(preg_match("/^[0-9]+(?:,[0-9]+)*$/", $types) === 1)
{
// Append selector to DB query. The used regex ensures
// that only numbers, separated by commas are accepted
// to avoid code injection and other malicious things
// We accept only valid lists like "1,2,3"
// We reject ",2,3", "1,2," and similar arguments
$dbquery .= "AND status IN (".$types.") ";
}
else
{
die("Error. Selector types specified using an invalid format.");
}
}
$dbquery .= "ORDER BY timestamp ASC";
$stmt = $db->prepare($dbquery);
$stmt->bindValue(":from", intval($from), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($until), SQLITE3_INTEGER);
$results = $stmt->execute();
// Start the JSON string
echo '{"data":[';
// Start the JSON string
echo '{"data":[';
if (!is_bool($results)) {
$first = true;
while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
// Insert a comma before the next record (except on the first one)
if (!$first) {
echo ",";
} else {
$first = false;
}
if (!is_bool($results)) {
$first = true;
while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
// Insert a comma before the next record (except on the first one)
if (!$first) {
echo ",";
} else {
$first = false;
}
// Format, encode, transform each field (if necessary).
$time = $row["timestamp"];
$query_type = getQueryTypeStr($row["type"]); // Convert query type ID to name
$domain = utf8_encode(str_replace("~"," ",$row["domain"]));
$client = $row["client"];
$status = $row["status"];
$destination = utf8_encode($row["forward"]);
$reply_type = $row["reply_type"];
$reply_time = $row["reply_time"];
$dnssec = $row["dnssec"];
// Format, encode, transform each field (if necessary).
$time = $row["timestamp"];
$query_type = getQueryTypeStr($row["type"]); // Convert query type ID to name
$domain = utf8_encode(str_replace("~"," ",$row["domain"]));
$client = $row["client"];
$status = $row["status"];
$destination = utf8_encode($row["forward"]);
$reply_type = $row["reply_type"];
$reply_time = $row["reply_time"];
$dnssec = $row["dnssec"];
// Insert into array and output it in JSON format
echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]);
}
}
// Insert into array and output it in JSON format
echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]);
}
}
// Finish the JSON string
echo ']}';
// Finish the JSON string
echo ']}';
// exit at the end
exit();
}
// only used if getAllQueries==empty
$result = array('data' => $allQueries);
$data = array_merge($data, $result);
// exit at the end
exit();
}
// only used if getAllQueries==empty
$result = array('data' => $allQueries);
$data = array_merge($data, $result);
}
if (isset($_GET['topClients']) && $auth)
{
// $from = intval($_GET["from"]);
$limit = "";
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = "WHERE timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = "WHERE timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = "WHERE timestamp <= :until";
}
// $from = intval($_GET["from"]);
$limit = "";
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = "WHERE timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = "WHERE timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = "WHERE timestamp <= :until";
}
$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 .= " 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->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute();
$stmt = $db->prepare($dbquery);
$stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute();
$clientnums = array();
$clientnums = array();
if(!is_bool($results))
while ($row = $results->fetchArray())
{
// $row[0] is the client IP
if(!is_bool($results))
while ($row = $results->fetchArray())
{
// $row[0] is the client IP
if(array_key_exists($row[0], $clientnums))
{
// Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database)
$clientnums[$row[0]] += intval($row[1]);
}
else
{
// Entry does not yet exist
$clientnums[$row[0]] = intval($row[1]);
}
}
if(array_key_exists($row[0], $clientnums))
{
// Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database)
$clientnums[$row[0]] += intval($row[1]);
}
else
{
// Entry does not yet exist
$clientnums[$row[0]] = intval($row[1]);
}
}
// Sort by number of hits
arsort($clientnums);
// Sort by number of hits
arsort($clientnums);
// Extract only the first ten entries
$clientnums = array_slice($clientnums, 0, 10);
// Extract only the first ten entries
$clientnums = array_slice($clientnums, 0, 10);
$result = array('top_sources' => $clientnums);
$data = array_merge($data, $result);
$result = array('top_sources' => $clientnums);
$data = array_merge($data, $result);
}
if (isset($_GET['topDomains']) && $auth)
{
$limit = "";
$limit = "";
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = " AND timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp <= :until";
}
// 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->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute();
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = " AND timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp <= :until";
}
// 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->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute();
$domains = array();
$domains = array();
if(!is_bool($results))
while ($row = $results->fetchArray())
{
// Convert domain to lower case UTF-8
$c = utf8_encode(strtolower($row[0]));
if(array_key_exists($c, $domains))
{
// Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database)
$domains[$c] += intval($row[1]);
}
else
{
// Entry does not yet exist
$domains[$c] = intval($row[1]);
}
}
if(!is_bool($results))
while ($row = $results->fetchArray())
{
// Convert domain to lower case UTF-8
$c = utf8_encode(strtolower($row[0]));
if(array_key_exists($c, $domains))
{
// Entry already exists, add to it (might appear multiple times due to mixed capitalization in the database)
$domains[$c] += intval($row[1]);
}
else
{
// Entry does not yet exist
$domains[$c] = intval($row[1]);
}
}
// Sort by number of hits
arsort($domains);
// Sort by number of hits
arsort($domains);
// Extract only the first ten entries
$domains = array_slice($domains, 0, 10);
// Extract only the first ten entries
$domains = array_slice($domains, 0, 10);
$result = array('top_domains' => $domains);
$data = array_merge($data, $result);
$result = array('top_domains' => $domains);
$data = array_merge($data, $result);
}
if (isset($_GET['topAds']) && $auth)
{
$limit = "";
$limit = "";
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = " AND timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["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->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute();
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = " AND timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["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->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute();
$addomains = array();
$addomains = array();
if(!is_bool($results))
while ($row = $results->fetchArray())
{
$addomains[utf8_encode($row[0])] = intval($row[1]);
}
$result = array('top_ads' => $addomains);
$data = array_merge($data, $result);
if(!is_bool($results))
while ($row = $results->fetchArray())
{
$addomains[utf8_encode($row[0])] = intval($row[1]);
}
$result = array('top_ads' => $addomains);
$data = array_merge($data, $result);
}
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))
$result = array('mintimestamp' => $results->fetchArray()[0]);
else
$result = array();
if(!is_bool($results))
$result = array('mintimestamp' => $results->fetchArray()[0]);
else
$result = array();
$data = array_merge($data, $result);
$data = array_merge($data, $result);
}
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))
$result = array('maxtimestamp' => $results->fetchArray()[0]);
else
$result = array();
if(!is_bool($results))
$result = array('maxtimestamp' => $results->fetchArray()[0]);
else
$result = array();
$data = array_merge($data, $result);
$data = array_merge($data, $result);
}
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))
$result = array('count' => $results->fetchArray()[0]);
else
$result = array();
if(!is_bool($results))
$result = array('count' => $results->fetchArray()[0]);
else
$result = array();
$data = array_merge($data, $result);
$data = array_merge($data, $result);
}
if (isset($_GET['getDBfilesize']) && $auth)
{
$filesize = filesize("/etc/pihole/pihole-FTL.db");
$result = array('filesize' => $filesize);
$data = array_merge($data, $result);
$filesize = filesize("/etc/pihole/pihole-FTL.db");
$result = array('filesize' => $filesize);
$data = array_merge($data, $result);
}
if (isset($_GET['getGraphData']) && $auth)
{
$limit = "";
$limit = "";
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = " AND timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp <= :until";
}
if(isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp >= :from AND timestamp <= :until";
}
elseif(isset($_GET["from"]) && !isset($_GET["until"]))
{
$limit = " AND timestamp >= :from";
}
elseif(!isset($_GET["from"]) && isset($_GET["until"]))
{
$limit = " AND timestamp <= :until";
}
$interval = 600;
$interval = 600;
if(isset($_GET["interval"]))
{
$q = intval($_GET["interval"]);
if($q >= 10)
$interval = $q;
}
if(isset($_GET["interval"]))
{
$q = intval($_GET["interval"]);
if($q >= 10)
$interval = $q;
}
// Round $from and $until to match the requested $interval
$from = intval((intval($_GET['from'])/$interval)*$interval);
$until = intval((intval($_GET['until'])/$interval)*$interval);
// Round $from and $until to match the requested $interval
$from = intval((intval($_GET['from'])/$interval)*$interval);
$until = intval((intval($_GET['until'])/$interval)*$interval);
// 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->bindValue(":from", $from, SQLITE3_INTEGER);
$stmt->bindValue(":until", $until, SQLITE3_INTEGER);
$stmt->bindValue(":interval", $interval, SQLITE3_INTEGER);
$results = $stmt->execute();
// 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->bindValue(":from", $from, SQLITE3_INTEGER);
$stmt->bindValue(":until", $until, SQLITE3_INTEGER);
$stmt->bindValue(":interval", $interval, SQLITE3_INTEGER);
$results = $stmt->execute();
// Parse the DB result into graph data, filling in missing interval sections with zero
function parseDBData($results, $interval, $from, $until) {
$data = array();
$first_db_timestamp = -1;
// Parse the DB result into graph data, filling in missing interval sections with zero
function parseDBData($results, $interval, $from, $until) {
$data = array();
$first_db_timestamp = -1;
if(!is_bool($results)) {
// Read in the data
while($row = $results->fetchArray()) {
// $data[timestamp] = value_in_this_interval
$data[$row[0]] = intval($row[1]);
if($first_db_timestamp === -1)
$first_db_timestamp = intval($row[0]);
}
}
if(!is_bool($results)) {
// Read in the data
while($row = $results->fetchArray()) {
// $data[timestamp] = value_in_this_interval
$data[$row[0]] = intval($row[1]);
if($first_db_timestamp === -1)
$first_db_timestamp = intval($row[0]);
}
}
// It is unpredictable what the first timestamp returned by the database
// will be. This depends on live data. Hence, we re-align the FROM
// timestamp to avoid unaligned holes appearing as additional
// (incorrect) data points
$aligned_from = $from + (($first_db_timestamp - $from) % $interval);
// It is unpredictable what the first timestamp returned by the database
// will be. This depends on live data. Hence, we re-align the FROM
// timestamp to avoid unaligned holes appearing as additional
// (incorrect) data points
$aligned_from = $from + (($first_db_timestamp - $from) % $interval);
// Fill gaps in returned data
for($i = $aligned_from; $i < $until; $i += $interval) {
if(!array_key_exists($i, $data))
$data[$i] = 0;
}
// Fill gaps in returned data
for($i = $aligned_from; $i < $until; $i += $interval) {
if(!array_key_exists($i, $data))
$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);
$data = array_merge($data, $result);
$result = array('domains_over_time' => $domains);
$data = array_merge($data, $result);
// 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->bindValue(":from", $from, SQLITE3_INTEGER);
$stmt->bindValue(":until", $until, SQLITE3_INTEGER);
$stmt->bindValue(":interval", $interval, SQLITE3_INTEGER);
$results = $stmt->execute();
// 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->bindValue(":from", $from, SQLITE3_INTEGER);
$stmt->bindValue(":until", $until, SQLITE3_INTEGER);
$stmt->bindValue(":interval", $interval, SQLITE3_INTEGER);
$results = $stmt->execute();
$addomains = parseDBData($results, $interval, $from, $until);
$addomains = parseDBData($results, $interval, $from, $until);
$result = array('ads_over_time' => $addomains);
$data = array_merge($data, $result);
$result = array('ads_over_time' => $addomains);
$data = array_merge($data, $result);
}
if (isset($_GET['status']) && $auth)
{
$extra = ";";
if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN')
$extra = "WHERE type != 'DNSMASQ_WARN';";
$results = $db->query('SELECT COUNT(*) FROM message '.$extra);
$extra = ";";
if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN')
$extra = "WHERE type != 'DNSMASQ_WARN';";
$results = $db->query('SELECT COUNT(*) FROM message '.$extra);
if(!is_bool($results))
$result = array('message_count' => $results->fetchArray()[0]);
else
$result = array();
if(!is_bool($results))
$result = array('message_count' => $results->fetchArray()[0]);
else
$result = array();
$data = array_merge($data, $result);
$data = array_merge($data, $result);
}
if(isset($_GET["messages"]) && $auth)
{
$extra = ";";
if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN')
$extra = "WHERE type != 'DNSMASQ_WARN';";
$extra = ";";
if(isset($_GET["ignore"]) && $_GET["ignore"] === 'DNSMASQ_WARN')
$extra = "WHERE type != 'DNSMASQ_WARN';";
$messages = array();
$results = $db->query('SELECT * FROM message '.$extra);
$messages = array();
$results = $db->query('SELECT * FROM message '.$extra);
while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{
// 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.
foreach ($res as $key => $value) {
if (is_string($value))
$res[$key] = htmlspecialchars(utf8_encode($value));
}
array_push($messages, $res);
}
while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{
// 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.
foreach ($res as $key => $value) {
if (is_string($value))
$res[$key] = htmlspecialchars(utf8_encode($value));
}
array_push($messages, $res);
}
$data = array_merge($data, array('messages' => $messages));
$data = array_merge($data, array('messages' => $messages));
}
if(isset($_GET["jsonForceObject"]))
{
echo json_encode($data, JSON_FORCE_OBJECT);
echo json_encode($data, JSON_FORCE_OBJECT);
}
else
{
echo json_encode($data);
echo json_encode($data);
}

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
@@ -15,62 +18,62 @@
<div class="row">
<div class="col-xs-12 col-lg-6">
<div class="box" id="domain-frequency">
<div class="box-header with-border">
<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 class="box" id="domain-frequency">
<div class="box-header with-border">
<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>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
<div class="col-xs-12 col-lg-6">
<div class="box" id="ad-frequency">
<div class="box-header with-border">
<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 class="box" id="ad-frequency">
<div class="box-header with-border">
<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>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
</div>
@@ -79,5 +82,5 @@
<script src="scripts/pi-hole/js/auditlog.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -5,7 +5,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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";
?>
@@ -40,9 +41,9 @@ require "scripts/pi-hole/php/header.php";
</div>
</div>
<div class="box-footer clearfix">
<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 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,
<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 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>
<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>
@@ -63,11 +64,11 @@ require "scripts/pi-hole/php/header.php";
<div class="box-body">
<table id="customCNAMETable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Domain</th>
<th>Target</th>
<th>Action</th>
</tr>
<tr>
<th>Domain</th>
<th>Target</th>
<th>Action</th>
</tr>
</thead>
</table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Clear Filters</button>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Sourceing CSS colors from stylesheet to be used in JS code -->
<span class="queries-permitted"></span>
@@ -17,64 +20,63 @@
<h1>Compute graphical statistics from the Pi-hole query database</h1>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">
Select date and time range
</h3>
</div>
<div class="box-body">
<div class="row">
<div class="form-group col-md-12">
<div class="input-group">
<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 class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">
Select date and time range
</h3>
</div>
<div class="box-body">
<div class="row">
<div class="form-group col-md-12">
<div class="input-group">
<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>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<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>
<div class="col-md-12">
<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>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="box" id="queries-over-time">
<div class="box-header with-border">
<h3 class="box-title">
Queries over the selected time period
</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-12">
<div class="chart">
<canvas id="queryOverTimeChart" width="800" height="250"></canvas>
<div class="col-md-12">
<div class="box" id="queries-over-time">
<div class="box-header with-border">
<h3 class="box-title">
Queries over the selected time period
</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-12">
<div class="chart">
<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 class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
</div>
</div>
</div>
<script src="scripts/vendor/daterangepicker.min.js?v=<?=$cacheVer?>"></script>
<script src="scripts/pi-hole/js/db_graph.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Sourceing CSS colors from stylesheet to be used in JS code -->
@@ -18,27 +21,27 @@
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">
Select date and time range
</h3>
</div>
<div class="box-body">
<div class="row">
<div class="form-group col-md-12">
<div class="input-group">
<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 class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">
Select date and time range
</h3>
</div>
<div class="box-body">
<div class="row">
<div class="form-group col-md-12">
<div class="input-group">
<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>
</div>
</div>
</div>
</div>
</div>
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
@@ -57,90 +60,90 @@ else
?>
<div class="row">
<div class="<?php echo $tablelayout; ?>">
<div class="box" id="domain-frequency">
<div class="box-header with-border">
<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 class="box" id="domain-frequency">
<div class="box-header with-border">
<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>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
<div class="<?php echo $tablelayout; ?>">
<div class="box" id="ad-frequency">
<div class="box-header with-border">
<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 class="box" id="ad-frequency">
<div class="box-header with-border">
<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>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
<div class="<?php echo $tablelayout; ?>">
<div class="box" id="client-frequency">
<div class="box-header with-border">
<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 class="box" id="client-frequency">
<div class="box-header with-border">
<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>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
</div>
@@ -149,5 +152,5 @@ else
<script src="scripts/pi-hole/js/db_lists.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
@@ -14,60 +17,60 @@
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">
Select date and time range
</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 class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">
Select date and time range
</h3>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<div class="input-group">
<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 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 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 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 class="row">
<div class="form-group col-md-12">
<div class="input-group">
<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 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 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 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 id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
@@ -166,40 +169,40 @@
<div class="row">
<div class="col-md-12">
<div class="box" id="recent-queries">
<div class="box-header with-border">
<h3 class="box-title">Recent Queries</h3>
<div class="box" id="recent-queries">
<div class="box-header with-border">
<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>
<!-- /.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>
<!-- /.box -->
<!-- /.box -->
</div>
</div>
<!-- /.row -->
@@ -208,5 +211,5 @@
<script src="scripts/pi-hole/js/db_queries.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -39,5 +39,5 @@ require "scripts/pi-hole/php/header.php";
<script src="scripts/pi-hole/js/debug.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -5,7 +5,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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";
?>
@@ -40,15 +41,15 @@ require "scripts/pi-hole/php/header.php";
</div>
</div>
<div class="box-footer clearfix">
<strong>Note:</strong>
<p>The order of locally defined DNS records is: </p>
<ol>
<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>Read from <code>/etc/hosts</code></li>
<li>Read from the "Local (custom) DNS" list (stored in <code>/etc/pihole/custom.list</code>)</li>
</ol>
<p>Only the first record will trigger an address-to-name association.</p>
<strong>Note:</strong>
<p>The order of locally defined DNS records is: </p>
<ol>
<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>Read from <code>/etc/hosts</code></li>
<li>Read from the "Local (custom) DNS" list (stored in <code>/etc/pihole/custom.list</code>)</li>
</ol>
<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>
</div>
</div>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
<div class="page-header">
@@ -28,5 +31,5 @@
<script src="scripts/pi-hole/js/gravity.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -4,8 +4,10 @@
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
@@ -60,16 +62,16 @@
<div class="box-body">
<table id="adlistsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
<th></th>
<th class="no-padding"></th>
<th>Address</th>
<th>Status</th>
<th>Comment</th>
<th>Group assignment</th>
<th>&nbsp;</th>
</tr>
<tr>
<th>ID</th>
<th></th>
<th class="no-padding"></th>
<th>Address</th>
<th>Status</th>
<th>Comment</th>
<th>Group assignment</th>
<th>&nbsp;</th>
</tr>
</thead>
</table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2019 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
@@ -41,12 +44,14 @@
<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>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>),
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>
IP subnets (CIDR notation, like <code>192.168.2.0/24</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>
<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.
Furthermore, MAC address recognition only works for devices at most one networking hop away from your Pi-hole.</p>
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>
</div>
</div>
</div>
@@ -68,14 +73,14 @@
<div class="box-body">
<table id="clientsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</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>Comment</th>
<th>Group assignment</th>
<th>&nbsp;</th>
</tr>
<tr>
<th>ID</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>Comment</th>
<th>Group assignment</th>
<th>&nbsp;</th>
</tr>
</thead>
</table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2019 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
@@ -74,8 +77,8 @@
</div>
</div>
<div class="form-group col-md-6">
<label for="new_regex_comment">Comment:</label>
<input id="new_regex_comment" type="text" class="form-control" placeholder="Description (optional)">
<label for="new_regex_comment">Comment:</label>
<input id="new_regex_comment" type="text" class="form-control" placeholder="Description (optional)">
</div>
</div>
</div>
@@ -83,8 +86,8 @@
</div>
<div>
<p><strong>Note:</strong><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>).
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>).
</p>
</div>
<div class="btn-toolbar pull-right" role="toolbar" aria-label="Toolbar with buttons">
@@ -115,16 +118,16 @@
<div class="box-body">
<table id="domainsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
<th></th>
<th>Domain/RegEx</th>
<th>Type</th>
<th>Status</th>
<th>Comment</th>
<th>Group assignment</th>
<th>&nbsp;</th>
</tr>
<tr>
<th>ID</th>
<th></th>
<th>Domain/RegEx</th>
<th>Type</th>
<th>Status</th>
<th>Comment</th>
<th>Group assignment</th>
<th>&nbsp;</th>
</tr>
</thead>
</table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2019 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
@@ -59,14 +62,14 @@
<div class="box-body">
<table id="groupsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
<th></th>
<th>Name</th>
<th>Status</th>
<th>Description</th>
<th>&nbsp;</th>
</tr>
<tr>
<th>ID</th>
<th></th>
<th>Name</th>
<th>Status</th>
<th>Description</th>
<th>&nbsp;</th>
</tr>
</thead>
</table>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>

341
index.php
View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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;
require "scripts/pi-hole/php/header.php";
@@ -73,217 +74,217 @@ require_once "scripts/pi-hole/php/gravity.php";
<div class="row">
<div class="col-md-12">
<div class="box" id="queries-over-time">
<div class="box-header with-border">
<h3 class="box-title">Total queries over last <span class="maxlogage-interval">24</span> hours</h3>
<div class="box" id="queries-over-time">
<div class="box-header with-border">
<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 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>
<?php
// 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
// show since the API will respect the privacy of the user if he defines
// a password
if($auth){ ?>
// 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
// show since the API will respect the privacy of the user if he defines
// a password
if($auth){
?>
<div class="row">
<div class="col-md-12">
<div class="box" id="clients">
<div class="box-header with-border">
<h3 class="box-title">Client activity over last <span class="maxlogage-interval">24</span> hours</h3>
<div class="box" id="clients">
<div class="box-header with-border">
<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 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 class="row">
<div class="col-md-6">
<div class="box" id="query-types-pie">
<div class="box-header with-border">
<h3 class="box-title">Query Types</h3>
<div class="box" id="query-types-pie">
<div class="box-header with-border">
<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 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="col-md-6">
<div class="box" id="forward-destinations-pie">
<div class="box-header with-border">
<h3 class="box-title">Upstream servers</h3>
<div class="box" id="forward-destinations-pie">
<div class="box-header with-border">
<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 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>
<?php
if($boxedlayout)
{
$tablelayout = "col-md-6";
}
else
{
$tablelayout = "col-md-6 col-lg-6";
}
if($boxedlayout)
{
$tablelayout = "col-md-6";
}
else
{
$tablelayout = "col-md-6 col-lg-6";
}
?>
<div class="row">
<div class="<?php echo $tablelayout; ?>">
<div class="box" id="domain-frequency">
<div class="box-header with-border">
<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 class="box" id="domain-frequency">
<div class="box-header with-border">
<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>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
<div class="<?php echo $tablelayout; ?>">
<div class="box" id="ad-frequency">
<div class="box-header with-border">
<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 class="box" id="ad-frequency">
<div class="box-header with-border">
<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>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
</div>
<div class="row">
<!-- /.col -->
<div class="<?php echo $tablelayout; ?>">
<div class="box" id="client-frequency">
<div class="box-header with-border">
<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 class="box" id="client-frequency">
<div class="box-header with-border">
<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>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
<!-- /.col -->
<div class="<?php echo $tablelayout; ?>">
<div class="box" id="client-frequency-blocked">
<div class="box-header with-border">
<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 class="box" id="client-frequency-blocked">
<div class="box-header with-border">
<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>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<div class="overlay">
<i class="fa fa-sync fa-spin"></i>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
<!-- /.col -->
</div>
@@ -293,5 +294,5 @@ else
<script src="scripts/pi-hole/js/index.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2020 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
@@ -21,19 +24,19 @@
<div class="box-body">
<table id="messagesTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
<th>&nbsp;</th>
<th>Time</th>
<th>Type</th>
<th>Message</th>
<th>Data1</th>
<th>Data2</th>
<th>Data3</th>
<th>Data4</th>
<th>Data5</th>
<th>&nbsp;</th>
</tr>
<tr>
<th>ID</th>
<th>&nbsp;</th>
<th>Time</th>
<th>Type</th>
<th>Message</th>
<th>Data1</th>
<th>Data2</th>
<th>Data3</th>
<th>Data4</th>
<th>Data5</th>
<th>&nbsp;</th>
</tr>
</thead>
</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>
@@ -47,5 +50,5 @@
<script src="scripts/pi-hole/js/messages.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -4,62 +4,64 @@
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<div class="row">
<div class="col-md-12">
<div class="box" id="network-details">
<div class="box-header with-border">
<h3 class="box-title">Network overview</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="network-entries" class="table table-striped table-bordered" width="100%">
<thead>
<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>
<div class="box-header with-border">
<h3 class="box-title">Network overview</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="network-entries" class="table table-striped table-bordered" width="100%">
<thead>
<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>
</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>
</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>
</table>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
<!-- /.box -->
</div>
</div>
<!-- /.row -->
@@ -68,5 +70,5 @@
<script src="scripts/pi-hole/js/network.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
$showing = "";
@@ -131,47 +134,47 @@ if(strlen($showing) > 0)
<div class="row">
<div class="col-md-12">
<div class="box" id="recent-queries">
<div class="box-header with-border">
<h3 class="box-title">Recent Queries <?php echo $showing; ?></h3>
<div class="box" id="recent-queries">
<div class="box-header with-border">
<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>
<!-- /.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>
<!-- /.box -->
<!-- /.box -->
</div>
</div>
<!-- /.row -->
@@ -179,5 +182,5 @@ if(strlen($showing) > 0)
<script src="scripts/pi-hole/js/queries.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -1,38 +1,41 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
<div class="page-header">
<h1>Find Blocked Domain In Lists</h1>
</div>
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
<!-- domain-search-block - Single search field mobile/desktop -->
<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="quiet" type="hidden" value="no">
<span class="input-group-btn">
<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>
</span>
<div class="col-md-12">
<div class="box">
<div class="box-body">
<!-- domain-search-block - Single search field mobile/desktop -->
<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="quiet" type="hidden" value="no">
<span class="input-group-btn">
<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>
</span>
</div>
<!-- /domain-search-block -->
</div>
</div>
<!-- /domain-search-block -->
</div>
</div>
</div>
</div>
<pre id="output" style="width: 100%; height: 100%;" hidden></pre>
<script src="scripts/pi-hole/js/queryads.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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_FTL_IP = "127.0.0.1";

View File

@@ -31,19 +31,19 @@ body {
<body>
<?php
if($auth) {
if(strlen($pwhash) > 0) {
echo '<div class="qrcode">';
require_once("../../vendor/qrcode.php");
$qr = QRCode::getMinimumQRCode($pwhash, QR_ERROR_CORRECT_LEVEL_Q);
// The size of each block (in pixels) should be an integer
$qr->printSVG(10);
echo "</div>";
echo 'Raw API Token: <code class="token">' . $pwhash . "</code></div>";
} else {
echo "<p>No password set</p>";
}
if(strlen($pwhash) > 0) {
echo '<div class="qrcode">';
require_once("../../vendor/qrcode.php");
$qr = QRCode::getMinimumQRCode($pwhash, QR_ERROR_CORRECT_LEVEL_Q);
// The size of each block (in pixels) should be an integer
$qr->printSVG(10);
echo "</div>";
echo 'Raw API Token: <code class="token">' . $pwhash . "</code></div>";
} else {
echo "<p>No password set</p>";
}
} else {
echo "<p>Not authorized!</p>";
echo "<p>Not authorized!</p>";
}
?>
</body>

View File

@@ -4,9 +4,11 @@
* Network-wide ad blocking via your own hardware.
*
* 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');
$ERRORLOG = getenv('PHP_ERROR_LOG');
if (empty($ERRORLOG)) {
$ERRORLOG = '/var/log/lighttpd/error-pihole.log';

View File

@@ -1,26 +1,22 @@
<?php
require_once "func.php";
require_once('auth.php');
require_once "func.php";
require_once('auth.php');
// Authentication checks
if (!isset($api)) {
if (isset($_POST['token'])) {
check_cors();
check_csrf($_POST['token']);
} else {
log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
}
// Authentication checks
if (!isset($api)) {
if (isset($_POST['token'])) {
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'])
{
case 'get': echo json_encode(echoCustomCNAMEEntries()); break;
case 'add': echo json_encode(addCustomCNAMEEntry()); break;
case 'delete': echo json_encode(deleteCustomCNAMEEntry()); break;
default:
die("Wrong action");
}
switch ($_POST['action']) {
case 'get': echo json_encode(echoCustomCNAMEEntries()); break;
case 'add': echo json_encode(addCustomCNAMEEntry()); break;
case 'delete': echo json_encode(deleteCustomCNAMEEntry()); break;
default:
die("Wrong action");
}
?>

View File

@@ -1,26 +1,22 @@
<?php
require_once "func.php";
require_once('auth.php');
require_once "func.php";
require_once('auth.php');
// Authentication checks
if (!isset($api)) {
if (isset($_POST['token'])) {
check_cors();
check_csrf($_POST['token']);
} else {
log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
}
// Authentication checks
if (!isset($api)) {
if (isset($_POST['token'])) {
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'])
{
case 'get': echo json_encode(echoCustomDNSEntries()); break;
case 'add': echo json_encode(addCustomDNSEntry()); break;
case 'delete': echo json_encode(deleteCustomDNSEntry()); break;
default:
die("Wrong action");
}
switch ($_POST['action']) {
case 'get': echo json_encode(echoCustomDNSEntries()); break;
case 'add': echo json_encode(addCustomDNSEntry()); break;
case 'delete': echo json_encode(deleteCustomDNSEntry()); break;
default:
die("Wrong action");
}
?>

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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()
{

View File

@@ -4,7 +4,9 @@
* Network-wide ad blocking via your own hardware.
*
* 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>
<!-- /.content -->
@@ -20,14 +22,14 @@
<div class="modal-body">
<div class="input-group">
<input id="customTimeout" class="form-control" type="number" value="60">
<div class="input-group-btn" data-toggle="buttons">
<label class="btn btn-default">
<input id="selSec" type="radio"> Secs
</label>
<label id="btnMins" class="btn btn-default active">
<input id="selMin" type="radio"> Mins
</label>
</div>
<div class="input-group-btn" data-toggle="buttons">
<label class="btn btn-default">
<input id="selSec" type="radio"> Secs
</label>
<label id="btnMins" class="btn btn-default active">
<input id="selMin" type="radio"> Mins
</label>
</div>
</div>
</div>
<div class="modal-footer">

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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
// Modified because of https://github.com/pi-hole/AdminLTE/pull/533
@@ -70,8 +71,8 @@ function validCIDRIP($address){
function validMAC($mac_addr)
{
// Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case)
return !filter_var($mac_addr, FILTER_VALIDATE_MAC) === false;
// Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case)
return !filter_var($mac_addr, FILTER_VALIDATE_MAC) === false;
}
function validEmail($email)
@@ -87,8 +88,8 @@ function validEmail($email)
function get_ip_type($ip)
{
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? 4 :
(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? 6 :
0);
(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? 6 :
0);
}
function checkfile($filename) {
@@ -109,14 +110,14 @@ if(!function_exists('hash_equals')) {
$ret = 0;
if (strlen($known_string) !== strlen($user_string)) {
$user_string = $known_string;
$ret = 1;
$user_string = $known_string;
$ret = 1;
}
$res = $known_string ^ $user_string;
for ($i = strlen($res) - 1; $i >= 0; --$i) {
$ret |= ord($res[$i]);
$ret |= ord($res[$i]);
}
return !$ret;
@@ -548,9 +549,9 @@ function piholeStatus() {
function getGateway() {
$gateway= callFTLAPI("gateway");
if (array_key_exists("FTLnotrunning", $gateway)) {
$ret = array("ip" => -1);
$ret = array("ip" => -1);
} else {
$ret = array_combine(["ip", "iface"], explode(" ", $gateway[0]));
$ret = array_combine(["ip", "iface"], explode(" ", $gateway[0]));
}
return $ret;
}

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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");

View File

@@ -4,9 +4,11 @@
* Network-wide ad blocking via your own hardware.
*
* 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";
if(!$auth) die("Not authorized");
ob_end_flush();

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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('func.php');
@@ -360,8 +361,8 @@ if ($_POST['action'] == 'get_groups') {
$comment = html_entity_decode($_POST['comment']);
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
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']);
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
@@ -694,15 +695,15 @@ if ($_POST['action'] == 'get_groups') {
$difference = $after - $before;
if($total === 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 {
$msg = "Added " . htmlentities(utf8_encode($domain));
$msg = "Added " . htmlentities(utf8_encode($domain));
}
} else {
if($difference !== $total) {
$msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)";
$msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)";
} else {
$msg = "Added " . $total . " domains";
$msg = "Added " . $total . " domains";
}
}
$reload = true;
@@ -722,7 +723,7 @@ if ($_POST['action'] == 'get_groups') {
$status = intval($_POST['status']);
if ($status !== 0) {
$status = 1;
$status = 1;
}
if (!$stmt->bindValue(':enabled', $status, SQLITE3_INTEGER)) {
@@ -731,8 +732,8 @@ if ($_POST['action'] == 'get_groups') {
$comment = html_entity_decode($_POST['comment']);
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
@@ -985,7 +986,7 @@ if ($_POST['action'] == 'get_groups') {
// Send added and ignored lists
$msg = "<b>Ignored duplicated adlists: " . $ignored . "</b><br>" . $ignored_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>";
JSON_warning($msg);
@@ -1010,7 +1011,7 @@ if ($_POST['action'] == 'get_groups') {
$status = intval($_POST['status']);
if ($status !== 0) {
$status = 1;
$status = 1;
}
if (!$stmt->bindValue(':enabled', $status, SQLITE3_INTEGER)) {
@@ -1019,8 +1020,8 @@ if ($_POST['action'] == 'get_groups') {
$comment = html_entity_decode($_POST['comment']);
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
@@ -1160,15 +1161,15 @@ if ($_POST['action'] == 'get_groups') {
$difference = $after - $before;
if($total === 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 {
$msg = "Added " . htmlentities(utf8_encode($domain));
$msg = "Added " . htmlentities(utf8_encode($domain));
}
} else {
if($difference !== $total) {
$msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)";
$msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)";
} else {
$msg = "Added " . $total . " domains";
$msg = "Added " . $total . " domains";
}
}

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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/password.php";

View File

@@ -4,71 +4,73 @@
* Network-wide ad blocking via your own hardware.
*
* 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="panel panel-default">
<div class="panel-heading">
<div class="text-center">
<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 class="panel panel-default">
<div class="panel-heading">
<div class="text-center">
<img src="img/logo.svg" alt="Pi-hole logo" class="loginpage-logo">
</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>
</form>
</div>
</div>
</div>
<?php
require "scripts/pi-hole/php/footer.php";

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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('func.php');

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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('func.php');

View File

@@ -4,118 +4,119 @@
* Network-wide ad blocking via your own hardware.
*
* 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)
// Prevents javascript XSS attacks aimed to steal the session ID
ini_set('session.cookie_httponly', 1);
// Prevent Session ID from being passed through URLs
ini_set('session.use_only_cookies', 1);
session_start();
// Start a new PHP session (or continue an existing one)
// Prevents javascript XSS attacks aimed to steal the session ID
ini_set('session.cookie_httponly', 1);
// Prevent Session ID from being passed through URLs
ini_set('session.use_only_cookies', 1);
session_start();
// Read setupVars.conf file
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
// Try to read password hash from setupVars.conf
if(isset($setupVars['WEBPASSWORD']))
// Read setupVars.conf file
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
// Try to read password hash from setupVars.conf
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'];
}
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"]))
{
if (hash_equals($pwhash, $_COOKIE["persistentlogin"]))
{
$auth = true;
// Refresh cookie with new expiry
// 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;
$auth = true;
// Refresh cookie with new expiry
// setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly )
setcookie('persistentlogin', $pwhash, time()+60*60*24*7, null, null, null, true );
}
else
{
// Password or hash wrong
// 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
{
// No password set
$auth = true;
// Password or hash wrong
$auth = false;
}
}
else
{
// No password set
$auth = true;
}
?>

View File

@@ -4,11 +4,13 @@
* Network-wide ad blocking via your own hardware.
*
* 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) {
ob_end_flush();
}
require_once("func.php");
ini_set("output_buffering", "0");
ob_implicit_flush(true);
@@ -17,9 +19,9 @@ header('Cache-Control: no-cache');
function echoEvent($datatext) {
if(!isset($_GET["IE"]))
echo "data:".implode("\ndata:", explode("\n", $datatext))."\n\n";
echo "data:".implode("\ndata:", explode("\n", $datatext))."\n\n";
else
echo $datatext;
echo $datatext;
}
// Test if domain is set

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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");

View File

@@ -49,16 +49,16 @@
?>
<br/>
<?php
if ($celsius >= -273.15) {
if ($celsius >= -273.15) {
// Only show temp info if any data is available -->
$tempcolor = "text-vivid-blue";
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 'Temp:&nbsp;<span id="rawtemp" hidden>' .$celsius. '</span>';
echo '<span id="tempdisplay"></span></span>';
}
}
?>
</div>
</div>
@@ -80,7 +80,8 @@
<!-- Logout -->
<?php
// Show Logout button if $auth is set and authorization is required
if(strlen($pwhash) > 0 && $auth) { ?>
if(strlen($pwhash) > 0 && $auth) {
?>
<li>
<a href="?logout">
<i class="fa fa-fw menu-icon fa-sign-out-alt"></i> <span>Logout</span>
@@ -90,7 +91,8 @@
<!-- Login -->
<?php
// 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 } ?>>
<a href="index.php?login">
<i class="fa fa-fw menu-icon fa-user"></i> <span>Login</span>
@@ -108,29 +110,29 @@
</li>
<!-- Long-term database -->
<li class="treeview<?php if($scriptname === "db_queries.php" || $scriptname === "db_lists.php" || $scriptname === "db_graph.php"){ ?> active<?php } ?>">
<a href="#">
<i class="fa fa-fw menu-icon fa-history"></i> <span>Long-term Data</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li<?php if($scriptname === "db_graph.php"){ ?> class="active"<?php } ?>>
<a href="db_graph.php">
<i class="fa fa-fw menu-icon fa-chart-bar"></i> Graphics
</a>
</li>
<li<?php if($scriptname === "db_queries.php"){ ?> class="active"<?php } ?>>
<a href="db_queries.php">
<i class="fa fa-fw menu-icon fa-file-alt"></i> Query Log
</a>
</li>
<li<?php if($scriptname === "db_lists.php"){ ?> class="active"<?php } ?>>
<a href="db_lists.php">
<i class="fa fa-fw menu-icon fa-list"></i> Top Lists
</a>
</li>
</ul>
<a href="#">
<i class="fa fa-fw menu-icon fa-history"></i> <span>Long-term Data</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li<?php if($scriptname === "db_graph.php"){ ?> class="active"<?php } ?>>
<a href="db_graph.php">
<i class="fa fa-fw menu-icon fa-chart-bar"></i> Graphics
</a>
</li>
<li<?php if($scriptname === "db_queries.php"){ ?> class="active"<?php } ?>>
<a href="db_queries.php">
<i class="fa fa-fw menu-icon fa-file-alt"></i> Query Log
</a>
</li>
<li<?php if($scriptname === "db_lists.php"){ ?> class="active"<?php } ?>>
<a href="db_lists.php">
<i class="fa fa-fw menu-icon fa-list"></i> Top Lists
</a>
</li>
</ul>
</li>
<li class="header text-uppercase">Group Management</li>
@@ -159,152 +161,152 @@
<li class="header text-uppercase">DNS Control</li>
<!-- Enable/Disable Blocking -->
<li id="pihole-disable" class="treeview"<?php if ($pistatus == "0") { ?> hidden<?php } ?>>
<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>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li>
<a href="#" id="pihole-disable-indefinitely">
<i class="fa fa-fw menu-icon fa-infinity"></i> Indefinitely
</a>
</li>
<li>
<a href="#" id="pihole-disable-10s">
<i class="fa fa-fw menu-icon fa-clock"></i> For 10 seconds
</a>
</li>
<li>
<a href="#" id="pihole-disable-30s">
<i class="fa fa-fw menu-icon fa-clock"></i> For 30 seconds
</a>
</li>
<li>
<a href="#" id="pihole-disable-5m">
<i class="fa fa-fw menu-icon fas fa-clock"></i> For 5 minutes
</a>
</li>
<li>
<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
</a>
</li>
</ul>
<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>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li>
<a href="#" id="pihole-disable-indefinitely">
<i class="fa fa-fw menu-icon fa-infinity"></i> Indefinitely
</a>
</li>
<li>
<a href="#" id="pihole-disable-10s">
<i class="fa fa-fw menu-icon fa-clock"></i> For 10 seconds
</a>
</li>
<li>
<a href="#" id="pihole-disable-30s">
<i class="fa fa-fw menu-icon fa-clock"></i> For 30 seconds
</a>
</li>
<li>
<a href="#" id="pihole-disable-5m">
<i class="fa fa-fw menu-icon fas fa-clock"></i> For 5 minutes
</a>
</li>
<li>
<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
</a>
</li>
</ul>
<!-- <a href="#" id="flip-status"><i class="fa fa-stop"></i> <span>Disable</span></a> -->
</li>
<li id="pihole-enable" class="treeview"<?php if (!in_array($pistatus,["0","-1","-2"])) { ?> hidden<?php } ?>>
<a href="#">
<i class="fa fa-fw menu-icon fa-play"></i>
<span id="enableLabel">Enable Blocking&nbsp;&nbsp;&nbsp;
<span id="flip-status-enable"></span>
</span>
<i class="fa fa-fw menu-icon fa-play"></i>
<span id="enableLabel">Enable Blocking&nbsp;&nbsp;&nbsp;
<span id="flip-status-enable"></span>
</span>
</a>
</li>
<!-- Local DNS Records -->
<li class="treeview <?php if(in_array($scriptname, array("dns_records.php", "cname_records.php"))){ ?>active<?php } ?>">
<a href="#">
<i class="fa fa-fw menu-icon fa-address-book"></i> <span>Local DNS</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li<?php if($scriptname === "dns_records.php"){ ?> class="active"<?php } ?>>
<a href="dns_records.php">
<i class="fa fa-fw menu-icon fa-address-book"></i> DNS Records
</a>
</li>
<li<?php if($scriptname === "cname_records.php"){ ?> class="active"<?php } ?>>
<a href="cname_records.php">
<i class="fa fa-fw menu-icon fa-address-book"></i> CNAME Records
</a>
</li>
</ul>
<a href="#">
<i class="fa fa-fw menu-icon fa-address-book"></i> <span>Local DNS</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li<?php if($scriptname === "dns_records.php"){ ?> class="active"<?php } ?>>
<a href="dns_records.php">
<i class="fa fa-fw menu-icon fa-address-book"></i> DNS Records
</a>
</li>
<li<?php if($scriptname === "cname_records.php"){ ?> class="active"<?php } ?>>
<a href="cname_records.php">
<i class="fa fa-fw menu-icon fa-address-book"></i> CNAME Records
</a>
</li>
</ul>
</li>
<li class="header text-uppercase">System</li>
<!-- 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 } ?>">
<a href="#">
<i class="fa fa-fw menu-icon fa-tools"></i> <span>Tools</span>
<span class="warning-count hidden"></span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<!-- Pi-hole diagnosis -->
<li<?php if($scriptname === "messages.php"){ ?> class="active"<?php } ?>>
<a href="messages.php">
<i class="fa fa-fw menu-icon fa-file-medical-alt"></i> Pi-hole diagnosis
<span class="pull-right-container warning-count hidden"></span>
</a>
</li>
<!-- Run gravity.sh -->
<li<?php if($scriptname === "gravity.php"){ ?> class="active"<?php } ?>>
<a href="gravity.php">
<i class="fa fa-fw menu-icon fa-arrow-circle-down"></i> Update Gravity
</a>
</li>
<!-- Query Lists -->
<li<?php if($scriptname === "queryads.php"){ ?> class="active"<?php } ?>>
<a href="queryads.php">
<i class="fa fa-fw menu-icon fa-search"></i> Search Adlists
</a>
</li>
<!-- Audit log -->
<li<?php if($scriptname === "auditlog.php"){ ?> class="active"<?php } ?>>
<a href="auditlog.php">
<i class="fa fa-fw menu-icon fa-balance-scale"></i> Audit log
</a>
</li>
<!-- Tail pihole.log -->
<li<?php if($scriptname === "taillog.php"){ ?> class="active"<?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">
<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)">
<stop offset="0.051" style="stop-color:currentColor;stop-opacity:0.6"/>
<stop offset="0.95" style="stop-color:currentColor"/>
</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_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_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"/>
</g>
</svg>
Tail pihole.log
</a>
</li>
<!-- Tail FTL.log -->
<li<?php if($scriptname === "taillog-FTL.php"){ ?> class="active"<?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">
<g fill="currentColor">
<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 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>
</svg>
Tail FTL.log
</a>
</li>
<!-- Generate debug log -->
<li<?php if($scriptname === "debug.php"){ ?> class="active"<?php } ?>>
<a href="debug.php">
<i class="fa fa-fw menu-icon fa-ambulance"></i> Generate debug log
</a>
</li>
<!-- Network -->
<li<?php if($scriptname === "network.php"){ ?> class="active"<?php } ?>>
<a href="network.php">
<i class="fa fa-fw menu-icon fa-network-wired"></i> Network
</a>
</li>
</ul>
<a href="#">
<i class="fa fa-fw menu-icon fa-tools"></i> <span>Tools</span>
<span class="warning-count hidden"></span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<!-- Pi-hole diagnosis -->
<li<?php if($scriptname === "messages.php"){ ?> class="active"<?php } ?>>
<a href="messages.php">
<i class="fa fa-fw menu-icon fa-file-medical-alt"></i> Pi-hole diagnosis
<span class="pull-right-container warning-count hidden"></span>
</a>
</li>
<!-- Run gravity.sh -->
<li<?php if($scriptname === "gravity.php"){ ?> class="active"<?php } ?>>
<a href="gravity.php">
<i class="fa fa-fw menu-icon fa-arrow-circle-down"></i> Update Gravity
</a>
</li>
<!-- Query Lists -->
<li<?php if($scriptname === "queryads.php"){ ?> class="active"<?php } ?>>
<a href="queryads.php">
<i class="fa fa-fw menu-icon fa-search"></i> Search Adlists
</a>
</li>
<!-- Audit log -->
<li<?php if($scriptname === "auditlog.php"){ ?> class="active"<?php } ?>>
<a href="auditlog.php">
<i class="fa fa-fw menu-icon fa-balance-scale"></i> Audit log
</a>
</li>
<!-- Tail pihole.log -->
<li<?php if($scriptname === "taillog.php"){ ?> class="active"<?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">
<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)">
<stop offset="0.051" style="stop-color:currentColor;stop-opacity:0.6"/>
<stop offset="0.95" style="stop-color:currentColor"/>
</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_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_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"/>
</g>
</svg>
Tail pihole.log
</a>
</li>
<!-- Tail FTL.log -->
<li<?php if($scriptname === "taillog-FTL.php"){ ?> class="active"<?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">
<g fill="currentColor">
<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 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>
</svg>
Tail FTL.log
</a>
</li>
<!-- Generate debug log -->
<li<?php if($scriptname === "debug.php"){ ?> class="active"<?php } ?>>
<a href="debug.php">
<i class="fa fa-fw menu-icon fa-ambulance"></i> Generate debug log
</a>
</li>
<!-- Network -->
<li<?php if($scriptname === "network.php"){ ?> class="active"<?php } ?>>
<a href="network.php">
<i class="fa fa-fw menu-icon fa-network-wired"></i> Network
</a>
</li>
</ul>
</li>
<!-- Settings -->
<li<?php if($scriptname === "settings.php"){ ?> class="active"<?php } ?>>
@@ -315,8 +317,8 @@
<?php } ?>
<li class="header text-uppercase">Support</li>
<!-- Docs -->
<li>
<!-- Docs -->
<li>
<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>
</a>

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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";
if(!$auth) die("Not authorized");

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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 "auth.php"; // Also imports func.php

View File

@@ -4,7 +4,8 @@
* Network-wide ad blocking via your own hardware.
*
* 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
$available_themes = array();
@@ -28,15 +29,15 @@ if(isset($setupVars['WEBTHEME']))
// May be overwritten by settings tab
if(isset($_POST["field"]) &&
$_POST["field"] === "webUI" &&
isset($_POST["webtheme"])) {
$_POST["field"] === "webUI" &&
isset($_POST["webtheme"])) {
$webtheme = $_POST["webtheme"];
}
if(!array_key_exists($webtheme,$available_themes)) {
// Fallback to default (light) theme is property is not set
// or requested theme is not among the available
$webtheme = "default-auto";
// Fallback to default (light) theme is property is not set
// or requested theme is not among the available
$webtheme = "default-auto";
}
$darkmode = $available_themes[$webtheme][1];
@@ -45,8 +46,9 @@ $theme = $available_themes[$webtheme][2];
function theme_selection() {
global $available_themes, $webtheme;
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 } ?>>
<label for="webtheme_<?php echo $key; ?>"><strong><?php echo $value[0]; ?></strong></label></div><?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
}
}
?>

View File

@@ -6,92 +6,92 @@ $GitHubVersions = "/etc/pihole/GitHubVersions";
if(!is_readable($localversions) || !is_readable($localbranches) || !is_readable($GitHubVersions))
{
$core_branch = "master";
$core_current = "N/A";
$core_update = false;
$web_branch = "master";
$web_current = "N/A";
$web_update = false;
$FTL_current = "N/A";
$FTL_update = false;
$core_branch = "master";
$core_current = "N/A";
$core_update = false;
$web_branch = "master";
$web_current = "N/A";
$web_update = false;
$FTL_current = "N/A";
$FTL_update = false;
}
else
{
$versions = explode(" ", file_get_contents($localversions));
$branches = explode(" ", file_get_contents($localbranches));
$GitHubversions = explode(" ", file_get_contents($GitHubVersions));
$versions = explode(" ", file_get_contents($localversions));
$branches = explode(" ", file_get_contents($localbranches));
$GitHubversions = explode(" ", file_get_contents($GitHubVersions));
/********** Get Pi-hole core branch / version / commit **********/
// Check if on a dev branch
$core_branch = $branches[0];
if($core_branch !== "master") {
$core_current = "vDev";
$core_commit = $versions[0];
}
else {
$core_current = explode("-",$versions[0])[0];
}
/********** Get Pi-hole core branch / version / commit **********/
// Check if on a dev branch
$core_branch = $branches[0];
if($core_branch !== "master") {
$core_current = "vDev";
$core_commit = $versions[0];
}
else {
$core_current = explode("-",$versions[0])[0];
}
/********** Get Pi-hole web branch / version / commit **********/
$web_branch = $branches[1];
if($web_branch !== "master") {
$web_current = "vDev";
$web_commit = $versions[1];
}
else {
$web_current = explode("-",$versions[1])[0];
}
/********** Get Pi-hole web branch / version / commit **********/
$web_branch = $branches[1];
if($web_branch !== "master") {
$web_current = "vDev";
$web_commit = $versions[1];
}
else {
$web_current = explode("-",$versions[1])[0];
}
/********** Get Pi-hole FTL (not a git repository) **********/
$FTL_branch = $branches[2];
if(substr($versions[2], 0, 4) === "vDev") {
$FTL_current = "vDev";
$FTL_commit = $versions[2];
}
else {
$FTL_current = $versions[2];
}
/********** Get Pi-hole FTL (not a git repository) **********/
$FTL_branch = $branches[2];
if(substr($versions[2], 0, 4) === "vDev") {
$FTL_current = "vDev";
$FTL_commit = $versions[2];
}
else {
$FTL_current = $versions[2];
}
// Get data from GitHub
$core_latest = $GitHubversions[0];
$web_latest = $GitHubversions[1];
$FTL_latest = $GitHubversions[2];
// Get data from GitHub
$core_latest = $GitHubversions[0];
$web_latest = $GitHubversions[1];
$FTL_latest = $GitHubversions[2];
// Core version comparison
if($core_current !== "vDev")
{
// 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
$core_update = (version_compare($core_current, $core_latest) < 0);
}
else
{
$core_update = false;
}
// Core version comparison
if($core_current !== "vDev")
{
// 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
$core_update = (version_compare($core_current, $core_latest) < 0);
}
else
{
$core_update = false;
}
// Web version comparison
if($web_current !== "vDev")
{
// 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
$web_update = (version_compare($web_current, $web_latest) < 0);
}
else
{
$web_update = false;
}
// Web version comparison
if($web_current !== "vDev")
{
// 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
$web_update = (version_compare($web_current, $web_latest) < 0);
}
else
{
$web_update = false;
}
// FTL version comparison
// 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
if($FTL_current !== "vDev")
{
$FTL_update = (version_compare($FTL_current, $FTL_latest) < 0);
}
else
{
$FTL_update = false;
}
// FTL version comparison
// 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
if($FTL_current !== "vDev")
{
$FTL_update = (version_compare($FTL_current, $FTL_latest) < 0);
}
else
{
$FTL_update = false;
}
}
?>

View File

@@ -1,13 +1,17 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* 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/savesettings.php";
require_once "scripts/pi-hole/php/FTL.php";
// Reread ini file as things might have been changed
// DEFAULT_FTLCONFFILE is set in "scripts/pi-hole/php/FTL.php";
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
@@ -38,10 +42,12 @@ if (empty($timezone)) {
if (isset($_POST["submit"])) {
if ($_POST["submit"] == "saveupdate") {
// If that is the case -> refresh to the gravity page and start updating immediately
?>
?>
<meta http-equiv="refresh" content="1;url=gravity.php?go">
<?php }
} ?>
<?php
}
}
?>
<?php if (strlen($success) > 0) { ?>
<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>
<p class="hidden-md hidden-lg"></p>
<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>
<p class="hidden-md hidden-lg"></p>
<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="input-group">
<div class="input-group-addon">From</div>
<input type="text" class="form-control DHCPgroup" name="from" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
value="<?php echo $DHCPstart; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
<input type="text" class="form-control DHCPgroup" name="from"
autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" value="<?php echo $DHCPstart; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
</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="input-group">
<div class="input-group-addon">To</div>
<input type="text" class="form-control DHCPgroup" name="to" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
value="<?php echo $DHCPend; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
<input type="text" class="form-control DHCPgroup" name="to"
autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" value="<?php echo $DHCPend; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
</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="input-group">
<div class="input-group-addon">Router</div>
<input type="text" class="form-control DHCPgroup" name="router" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
value="<?php echo $DHCProuter; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
<input type="text" class="form-control DHCPgroup" name="router"
autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" value="<?php echo $DHCProuter; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
</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-addon">Domain</div>
<input type="text" class="form-control DHCPgroup" name="domain"
value="<?php echo $piHoleDomain; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
value="<?php echo $piHoleDomain; ?>"
<?php if (!$DHCP){ ?>disabled<?php } ?>>
</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-addon">Lease time in hours</div>
<input type="number" class="form-control DHCPgroup"
name="leasetime"
id="leasetime" value="<?php echo $DHCPleasetime; ?>"
data-mask <?php if (!$DHCP){ ?>disabled<?php } ?>>
name="leasetime"
id="leasetime" value="<?php echo $DHCPleasetime; ?>"
data-mask <?php if (!$DHCP){ ?>disabled<?php } ?>>
</div>
</div>
<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 class="row">
<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="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="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>
</div>
</div>
@@ -678,10 +687,10 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</tfoot>
</table>
<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
given, the IP address will still be generated dynamically and the
specified host name will be used. If the host name is omitted, only
a static lease will be added.</p>
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
specified host name will be used. If the host name is omitted, only
a static lease will be added.</p>
</div>
</div>
</div>
@@ -719,46 +728,48 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered">
<thead>
<tr>
<th colspan="2">IPv4</th>
<th colspan="2">IPv6</th>
<th>Name</th>
</tr>
</thead>
<?php foreach ($DNSserverslist as $key => $value) { ?>
<tr>
<?php if (isset($value["v4_1"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<?php if (isset($value["v4_2"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<?php if (isset($value["v6_1"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<?php if (isset($value["v6_2"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<td><?php echo $key; ?></td>
</tr>
<?php } ?>
<thead>
<tr>
<th colspan="2">IPv4</th>
<th colspan="2">IPv6</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php foreach ($DNSserverslist as $key => $value) { ?>
<tr>
<?php if (isset($value["v4_1"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<?php if (isset($value["v4_2"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<?php if (isset($value["v6_1"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<?php if (isset($value["v6_2"])) { ?>
<td title="<?php echo $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>
<?php } else { ?>
<td></td>
<?php } ?>
<td><?php echo $key; ?></td>
</tr>
<?php } ?>
</tbody>
</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>
</div>
@@ -782,7 +793,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div>
<div class="col-md-11">
<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>
@@ -795,7 +806,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div>
<div class="col-md-11">
<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>
@@ -810,7 +821,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div>
<div class="col-md-11">
<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>
@@ -823,7 +834,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div>
<div class="col-md-11">
<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>
@@ -844,7 +855,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<h4>Recommended setting</h4>
<div>
<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>
</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!
<div>
<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>
</div>
<div>
<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>
</div>
<div>
<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>
</div>
<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 } ?>>
<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
ticked, this asks FTL that this domain is purely
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.
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>
ticked, this asks FTL that this domain is purely
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.
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>
</div>
<div>
<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>
<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
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>
<p><strong>Important</strong>: Enabling these two options may increase your privacy,
but may also prevent you from being able to access
local hostnames if the Pi-hole is not used as DHCP server.</p>
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
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,
but may also prevent you from being able to access
local hostnames if the Pi-hole is not used as DHCP server.</p>
</div>
<br>
<div>
<input type="checkbox" name="DNSSEC" id="DNSSEC" <?php if ($DNSSEC){ ?>checked<?php } ?>>
<label for="DNSSEC"><strong>Use DNSSEC</strong></label>
<p>Validate DNS replies and cache DNSSEC data. When forwarding DNS
queries, Pi-hole requests the DNSSEC records needed to validate
the replies. If a domain fails validation or the upstream does not
support DNSSEC, this setting can cause issues resolving domains.
Use an upstream DNS server which supports DNSSEC when activating DNSSEC. Note that
the size of your log might increase significantly
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>
queries, Pi-hole requests the DNSSEC records needed to validate
the replies. If a domain fails validation or the upstream does not
support DNSSEC, this setting can cause issues resolving domains.
Use an upstream DNS server which supports DNSSEC when activating DNSSEC. Note that
the size of your log might increase significantly
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>
</div>
<br>
<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
<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
gets rate-limited. Rate-limited queries are answered with a
<code>REFUSED</code> reply and not further processed by FTL
and prevent Pi-holes getting overwhelmed by rogue clients.
It is important to note that rate-limiting is happening on a
per-client basis. Other clients can continue to use FTL while
rate-limited clients are short-circuited at the same time.</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
gets rate-limited. Rate-limited queries are answered with a
<code>REFUSED</code> reply and not further processed by FTL
and prevent Pi-holes getting overwhelmed by rogue clients.
It is important to note that rate-limiting is happening on a
per-client basis. Other clients can continue to use FTL while
rate-limited clients are short-circuited at the same time.</p>
<p>Rate-limiting may be disabled altogether by setting both
values to zero. See
<a href="https://docs.pi-hole.net/ftldns/configfile/#rate_limit" target="_blank">our documentation</a>
for further details.</p>
values to zero. See
<a href="https://docs.pi-hole.net/ftldns/configfile/#rate_limit" target="_blank">our documentation</a>
for further details.</p>
<br>
<h4>Conditional forwarding</h4>
<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
result, tables such as Top Clients will only show IP addresses.</p>
determine the names of devices on your local network. As a
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
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
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>
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
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>
<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
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>,
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.
Feel free to reach out to us on our
<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>
<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
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>.
Setting up IPv6 ranges is exactly similar to setting up IPv4 here and fully supported.
Feel free to reach out to us on our
<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>
<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.
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>
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
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
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>
<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>
</div>
<div class="input-group">
<table class="table table-bordered">
<thead>
<tr>
<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>Local domain name (optional)</th>
</tr>
</thead>
<tr>
<td>
<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_cidr)){ ?>value="<?php echo $rev_server_cidr; ?>"<?php } ?>
<?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"
<?php if(isset($rev_server_target)){ ?>value="<?php echo $rev_server_target; ?>"<?php } ?>
<?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"
<?php if(isset($rev_server_domain)){ ?>value="<?php echo $rev_server_domain; ?>"<?php } ?>
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
</td>
</tr>
</table>
<table class="table table-bordered">
<thead>
<tr>
<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>Local domain name (optional)</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<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_cidr)){ ?>value="<?php echo $rev_server_cidr; ?>"<?php } ?>
<?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"
<?php if(isset($rev_server_target)){ ?>value="<?php echo $rev_server_target; ?>"<?php } ?>
<?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"
<?php if(isset($rev_server_domain)){ ?>value="<?php echo $rev_server_domain; ?>"<?php } ?>
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
@@ -1036,9 +1049,9 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<div class="form-group">
<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"
rows="4"><?php foreach ($excludedDomains as $domain) {
echo $domain . "\n"; }
?></textarea>
rows="4"><?php foreach ($excludedDomains as $domain) {
echo $domain . "\n"; }
?></textarea>
</div>
</div>
<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>
<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>
<p class="help-block">Upload only Pi-hole backup files.</p>
</div>
@@ -1403,7 +1416,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
</div>
<div class="box-footer clearfix">
<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>
</div>
</div>
@@ -1420,8 +1433,8 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "dns", "piho
<label class="control-label">Output:</label>
<div class="box no-margin no-border no-shadow">
<pre class="no-margin no-padding"><iframe class="col-xs-12 no-border no-padding"
name="teleporter_iframe" height="100"
tabindex="-1"></iframe></pre>
name="teleporter_iframe" height="100"
tabindex="-1"></iframe></pre>
<div class="overlay">
<i class="fa fa-spinner fa-pulse"></i>
</div>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
<div class="page-header">
@@ -27,5 +30,5 @@
<script src="scripts/pi-hole/js/taillog-FTL.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>

View File

@@ -1,11 +1,14 @@
<?php /*
<?php
/*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
* Please see LICENSE file for your rights under this license.
*/
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
<div class="page-header">
@@ -27,5 +30,5 @@
<script src="scripts/pi-hole/js/taillog.js?v=<?=$cacheVer?>"></script>
<?php
require "scripts/pi-hole/php/footer.php";
require "scripts/pi-hole/php/footer.php";
?>