Move PHP scripts to scripts folder

This commit is contained in:
Mcat12
2016-12-19 19:44:51 -05:00
committed by DL6ER
parent d0553ef169
commit 2f65430a4d
29 changed files with 15 additions and 15 deletions

View File

@@ -0,0 +1,21 @@
<?php
require('auth.php');
if(!isset($_POST['domain'], $_POST['list'], $_POST['token'])) {
log_and_die("Missing POST variables");
}
check_cors();
check_csrf($_POST['token']);
check_domain();
switch($_POST['list']) {
case "white":
echo exec("sudo pihole -w -q ${_POST['domain']}");
break;
case "black":
echo exec("sudo pihole -b -q ${_POST['domain']}");
break;
}
?>

View File

@@ -0,0 +1,92 @@
<?php
require('func.php');
$ERRORLOG = getenv('PHP_ERROR_LOG');
if (empty($ERRORLOG)) {
$ERRORLOG = '/var/log/lighttpd/error.log';
}
function pi_log($message) {
error_log(date('Y-m-d H:i:s') . ': ' . $message . "\n", 3, $GLOBALS['ERRORLOG']);
}
function log_and_die($message) {
pi_log($message);
die($message);
}
function check_cors() {
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
$ipv4 = isset($setupVars["IPV4_ADDRESS"]) ? explode("/", $setupVars["IPV4_ADDRESS"])[0] : $_SERVER['SERVER_ADDR'];
// Check CORS
$AUTHORIZED_HOSTNAMES = array(
'http://' . $ipv4,
'http://' . $_SERVER['SERVER_NAME'],
'http://pi.hole',
'http://localhost'
);
# Allow user set virtual hostnames
$virtual_host = getenv('VIRTUAL_HOST');
if (! empty($virtual_host))
array_push($AUTHORIZED_HOSTNAMES, 'http://' . $virtual_host);
// Since the Host header is easily manipulated, we can only check if it's wrong and can't use it
// to validate that the client is authorized, only unauthorized.
if(isset($_SERVER['HTTP_HOST']) && !in_array("http://".$_SERVER['HTTP_HOST'], $AUTHORIZED_HOSTNAMES)) {
log_and_die("Failed Host Check: " . $_SERVER['HTTP_HOST'] .' vs '. join(', ', $AUTHORIZED_HOSTNAMES));
}
if(isset($_SERVER['HTTP_ORIGIN'])) {
if(!in_array($_SERVER['HTTP_ORIGIN'], $AUTHORIZED_HOSTNAMES)) {
log_and_die("Failed CORS: " . $_SERVER['HTTP_ORIGIN'] .' vs '. join(', ', $AUTHORIZED_HOSTNAMES));
}
header("Access-Control-Allow-Origin: ${_SERVER['HTTP_ORIGIN']}");
}
// If there's no HTTP_ORIGIN, CORS should not be used
}
function check_csrf($token) {
// Check CSRF token
$session_started = function_exists("session_status") ?
session_status() == PHP_SESSION_ACTIVE :
session_id() == "";
if(!$session_started) {
session_start();
}
// Credit: http://php.net/manual/en/function.hash-equals.php#119576
if(!function_exists('hash_equals')) {
function hash_equals($known_string, $user_string) {
$ret = 0;
if (strlen($known_string) !== strlen($user_string)) {
$user_string = $known_string;
$ret = 1;
}
$res = $known_string ^ $user_string;
for ($i = strlen($res) - 1; $i >= 0; --$i) {
$ret |= ord($res[$i]);
}
return !$ret;
}
}
if(!isset($_SESSION['token']) || empty($token) || !hash_equals($_SESSION['token'], $token)) {
log_and_die("Wrong token");
}
}
function check_domain() {
if(isset($_POST['domain'])){
$validDomain = is_valid_domain_name($_POST['domain']);
if(!$validDomain){
log_and_die($_POST['domain']. ' is not a valid domain');
}
}
}
?>

View File

@@ -0,0 +1,22 @@
<?php
function is_valid_domain_name($domain_name)
{
return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name) && //valid chars check
preg_match("/^.{1,253}$/", $domain_name) && //overall length check
preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name)); //length of each label
}
function checkfile($filename) {
if(is_readable($filename))
{
return $filename;
}
else
{
// substitute dummy file
return "/dev/null";
}
}
?>

View File

@@ -0,0 +1,35 @@
<?php
if(!isset($_GET['list']))
die();
$type = $_GET['list'];
if($type !== "white" && $type !== "black")
die("Invalid list parameter");
require "func.php";
$rawList = file_get_contents(checkfile("/etc/pihole/${type}list.txt"));
$list = explode("\n", $rawList);
// Get rid of empty lines
for($i = sizeof($list)-1; $i >= 0; $i--) {
if($list[$i] == "")
unset($list[$i]);
}
function filterArray(&$inArray) {
$outArray = array();
foreach ($inArray as $key=>$value) {
if (is_array($value)) {
$outArray[htmlspecialchars($key)] = filterArray($value);
} else {
$outArray[htmlspecialchars($key)] = htmlspecialchars($value);
}
}
return $outArray;
}
// Protect against XSS attacks
$list = filterArray($list);
echo json_encode(array_values($list));

View File

@@ -0,0 +1,23 @@
<?php
require "password.php";
if(!$auth) die("Not authorized");
ob_end_flush();
ini_set("output_buffering", "0");
ob_implicit_flush(true);
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
function echoEvent($datatext) {
echo "data: ".implode("\ndata: ", explode("\n", $datatext))."\n\n";
}
// echoEvent("***START***");
$proc = popen("sudo pihole -g", 'r');
while (!feof($proc)) {
echoEvent(fread($proc, 4096));
}
// echoEvent("***END***");
?>

View File

@@ -0,0 +1,54 @@
<div class="mainbox col-md-6 col-md-offset-3 col-sm-6 col-sm-offset-3">
<div class="panel panel-default">
<div class="panel-heading">
<div style="text-align: center;"><img src="img/logo.svg" width="<?php if ($boxedlayout) { ?>50%<?php } else { ?>30%<?php } ?>"></div><br>
<div class="panel-title text-center"><span class="logo-lg" style="font-size: 25px;"><b>Pi</b>-hole</span></div>
<p class="login-box-msg">Sign in to start your session</p>
<?php if ($wrongpassword) { ?>
<div class="form-group has-error login-box-msg">
<label class="control-label"><i class="fa fa-times-circle-o"></i> Wrong password!</label>
</div>
<?php } ?>
</div>
<div class="panel-body">
<form action="" method="post">
<div class="form-group has-feedback <?php if ($wrongpassword) { ?>has-error<?php } ?> ">
<input type="password" name="pw" class="form-control" placeholder="Password">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-4 col-xs-offset-8">
<button type="submit" href="#" class="btn btn-primary pull-right"><i class="glyphicon glyphicon-log-in"></i>&nbsp;&nbsp;&nbsp;Log in</button>
</div>
</div>
<br>
<div class="row">
<div class="col-xs-12">
<div class="box box-<?php if (!$wrongpassword) { ?>info<?php } else { ?>danger<?php }
if (!$wrongpassword) { ?> collapsed-box<?php } ?> box-solid">
<div class="box-header with-border">
<h3 class="box-title">Forgot password</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i
class="fa <?php if ($wrongpassword) { ?>fa-minus<?php } else { ?>fa-plus<?php } ?>"></i>
</button>
</div>
</div>
<div class="box-body">
After installing Pi-Hole for the first time, a password is generated and displayed to the user. The
password cannot be retrived later on, but it is possible to set a new password (or explicitly disable
the
password by setting an empty password) using the command
<pre>sudo pihole -a -p newpassword</pre>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,65 @@
<?php
// Start a new PHP session (or continue an existing one)
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']))
{
$pwhash = $setupVars['WEBPASSWORD'];
}
else
{
$pwhash = "";
}
// If the user wants to log out, we free all session variables currently registered
if(isset($_GET["logout"]))
{
session_unset();
}
$wrongpassword = false;
// Test if password is set
if(strlen($pwhash) > 0)
{
// Compare doubly hashes password input with saved hash
if(isset($_POST["pw"]))
{
$postinput = hash('sha256',hash('sha256',$_POST["pw"]));
if($postinput == $pwhash)
{
$_SESSION["hash"] = $pwhash;
$auth = true;
}
else
{
$wrongpassword = true;
}
}
// Compare auth hash with saved hash
else if (isset($_SESSION["hash"]))
{
if($_SESSION["hash"] == $pwhash)
$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($_GET["auth"] == $pwhash)
$auth = true;
}
else
{
// Password or hash wrong
$auth = false;
}
}
else
{
// No password set
$auth = true;
}
?>

View File

@@ -0,0 +1,50 @@
<?php
ob_end_flush();
ini_set("output_buffering", "0");
ob_implicit_flush(true);
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
function echoEvent($datatext) {
echo "data: ".implode("\ndata: ", explode("\n", $datatext))."\n\n";
}
// Credit: http://stackoverflow.com/a/4694816/2087442
function is_valid_domain_name($domain_name)
{
return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name) //valid chars check
&& preg_match("/^.{1,253}$/", $domain_name) //overall length check
&& preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name) ); //length of each label
}
// Test if domain is set
if(isset($_GET["domain"]))
{
// Is this a valid domain?
$url = $_GET["domain"];
if(!is_valid_domain_name($url))
{
echoEvent("Invalid domain!");
die();
}
}
else
{
echoEvent("No domain provided");
die();
}
if(isset($_GET["exact"]))
{
$exact = "-exact";
}
else
{
$exact = "";
}
$proc = popen("sudo pihole -q ".$url." ".$exact, 'r');
while (!feof($proc)) {
echoEvent(fread($proc, 4096));
}
?>

View File

@@ -0,0 +1,345 @@
<?php
if(basename($_SERVER['SCRIPT_FILENAME']) !== "settings.php")
{
die("Direct access to this script is forbidden!");
}
function validIP($address){
return !filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false;
}
// Credit: http://stackoverflow.com/a/4694816/2087442
function validDomain($domain_name)
{
$validChars = preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name);
$lengthCheck = preg_match("/^.{1,253}$/", $domain_name);
$labelLengthCheck = preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name);
return ( $validChars && $lengthCheck && $labelLengthCheck ); //length of each label
}
$primaryDNSservers = [
"8.8.8.8" => "Google",
"208.67.222.222" => "OpenDNS",
"4.2.2.1" => "Level3",
"199.85.126.10" => "Norton",
"8.26.56.26" => "Comodo"
];
$secondaryDNSservers = [
"8.8.4.4" => "Google",
"208.67.220.220" => "OpenDNS",
"4.2.2.2" => "Level3",
"199.85.127.10" => "Norton",
"8.20.247.20" => "Comodo"
];
$error = "";
$success = "";
if(isset($_POST["field"]))
{
// Process request
switch ($_POST["field"]) {
// Set DNS server
case "DNS":
$primaryDNS = $_POST["primaryDNS"];
$secondaryDNS = $_POST["secondaryDNS"];
// Get primary DNS server IP address
if($primaryDNS === "Custom")
{
$primaryIP = $_POST["DNS1IP"];
}
else
{
$primaryIP = array_flip($primaryDNSservers)[$primaryDNS];
}
// Validate primary IP
if (!validIP($primaryIP))
{
$error .= "Primary IP (".$primaryIP.") is invalid!<br>";
}
// Get secondary DNS server IP address
if($secondaryDNS === "Custom")
{
if(strlen($_POST["DNS2IP"]) > 0)
{
$secondaryIP = $_POST["DNS2IP"];
}
else
{
$secondaryIP = "none";
}
}
else
{
$secondaryIP = array_flip($secondaryDNSservers)[$secondaryDNS];
}
// Validate secondary IP
if (!validIP($secondaryIP) && $secondaryIP != "none" && strlen($secondaryIP) > 0)
{
$error .= "Secondary IP (".$secondaryIP.") is invalid!<br>";
}
// Check if domain-needed is requested
if(isset($_POST["DNSrequiresFQDN"]))
{
$extra = "domain-needed ";
}
else
{
$extra = "domain-not-needed ";
}
// Check if domain-needed is requested
if(isset($_POST["DNSbogusPriv"]))
{
$extra .= "bogus-priv";
}
else
{
$extra .= "no-bogus-priv";
}
// If there has been no error we can save the new DNS server IPs
if(!strlen($error))
{
exec("sudo pihole -a setdns ".$primaryIP." ".$secondaryIP." ".$extra);
$success .= "The DNS settings have been updated";
}
else
{
$error .= "The settings have been reset to their previous values";
}
break;
// Set query logging
case "Logging":
if($_POST["action"] === "Disable")
{
exec("sudo pihole -l off");
$success .= "Logging has been disabled";
}
else
{
exec("sudo pihole -l on");
$success .= "Logging has been enabled";
}
break;
// Set domains to be excluded from being shown in Top Domains (or Ads) and Top Clients
case "API":
// Explode the contents of the textareas into PHP arrays
// \n (Unix) and \r\n (Win) will be considered as newline
// array_filter( ... ) will remove any empty lines
$domains = array_filter(preg_split('/\r\n|[\r\n]/', $_POST["domains"]));
$clients = array_filter(preg_split('/\r\n|[\r\n]/', $_POST["clients"]));
$domainlist = "";
$first = true;
foreach($domains as $domain)
{
if(!validDomain($domain))
{
$error .= "Top Domains/Ads entry ".$domain." is invalid!<br>";
}
if(!$first)
{
$domainlist .= ",";
}
else
{
$first = false;
}
$domainlist .= $domain;
}
$clientlist = "";
$first = true;
foreach($clients as $client)
{
if(!validIP($client))
{
$error .= "Top Clients entry ".$client." is invalid (use only IP addresses)!<br>";
}
if(!$first)
{
$clientlist .= ",";
}
else
{
$first = false;
}
$clientlist .= $client;
}
// Set Top Lists options
if(!strlen($error))
{
// All entries are okay
exec("sudo pihole -a setexcludedomains ".$domainlist);
exec("sudo pihole -a setexcludeclients ".$clientlist);
$success .= "The API settings have been updated<br>";
}
else
{
$error .= "The settings have been reset to their previous values";
}
// Set query log options
if(isset($_POST["querylog-permitted"]) && isset($_POST["querylog-blocked"]))
{
exec("sudo pihole -a setquerylog all");
$success .= "All entries will be shown in Query Log";
}
elseif(isset($_POST["querylog-permitted"]))
{
exec("sudo pihole -a setquerylog permittedonly");
$success .= "Only permitted will be shown in Query Log";
}
elseif(isset($_POST["querylog-blocked"]))
{
exec("sudo pihole -a setquerylog blockedonly");
$success .= "Only blocked entries will be shown in Query Log";
}
else
{
exec("sudo pihole -a setquerylog nothing");
$success .= "No entries will be shown in Query Log";
}
break;
case "webUI":
if($_POST["tempunit"] == "F")
{
exec('sudo pihole -a -f');
}
elseif($_POST["tempunit"] == "K")
{
exec('sudo pihole -a -k');
}
else
{
exec('sudo pihole -a -c');
}
if(isset($_POST["boxedlayout"]))
{
exec('sudo pihole -a layout boxed');
}
else
{
exec('sudo pihole -a layout traditional');
}
$success .= "The webUI settings have been updated";
break;
case "reboot":
exec("sudo pihole -a reboot");
$success = "The system will reboot in 5 seconds...";
break;
case "restartdns":
exec("sudo pihole -a restartdns");
$success = "The DNS server has been restarted";
break;
case "flushlogs":
exec("sudo pihole -f");
$success = "The Pi-Hole log file has been flushed";
break;
case "DHCP":
if(isset($_POST["active"]))
{
// Validate from IP
$from = $_POST["from"];
if (!validIP($from))
{
$error .= "From IP (".$from.") is invalid!<br>";
}
// Validate to IP
$to = $_POST["to"];
if (!validIP($to))
{
$error .= "To IP (".$to.") is invalid!<br>";
}
// Validate router IP
$router = $_POST["router"];
if (!validIP($router))
{
$error .= "Router IP (".$router.") is invalid!<br>";
}
$domain = $_POST["domain"];
// Validate Domain name
if(!validDomain($domain))
{
$error .= "Domain name ".$domain." is invalid!<br>";
}
if(!strlen($error))
{
exec("sudo pihole -a enabledhcp ".$from." ".$to." ".$router);
exec("sudo pihole -a domainname ".$domain);
$success .= "The DHCP server has been activated";
}
}
else
{
exec("sudo pihole -a disabledhcp");
$success = "The DHCP server has been deactivated";
}
break;
default:
// Option not found
$debug = true;
break;
}
}
// Credit: http://stackoverflow.com/a/5501447/2087442
function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824)
{
$bytes = number_format($bytes / 1073741824, 2) . ' GB';
}
elseif ($bytes >= 1048576)
{
$bytes = number_format($bytes / 1048576, 2) . ' MB';
}
elseif ($bytes >= 1024)
{
$bytes = number_format($bytes / 1024, 2) . ' kB';
}
elseif ($bytes > 1)
{
$bytes = $bytes . ' bytes';
}
elseif ($bytes == 1)
{
$bytes = $bytes . ' byte';
}
else
{
$bytes = '0 bytes';
}
return $bytes;
}
?>

View File

@@ -0,0 +1,21 @@
<?php
require('auth.php');
if(!isset($_POST['domain'], $_POST['list'], $_POST['token'])) {
log_and_die("Missing POST variables");
}
check_cors();
check_csrf($_POST['token']);
check_domain();
switch($_POST['list']) {
case "white":
exec("sudo pihole -w -q -d ${_POST['domain']}");
break;
case "black":
exec("sudo pihole -b -q -d ${_POST['domain']}");
break;
}
?>