mirror of
https://github.com/pi-hole/web.git
synced 2024-12-06 19:36:21 +01:00
Merge branch 'release/v5.6' into devel
This commit is contained in:
@@ -75,29 +75,37 @@ $(function () {
|
||||
|
||||
tableApi = $("#all-queries").DataTable({
|
||||
rowCallback: function (row, data) {
|
||||
var replyid = parseInt(data[5], 10);
|
||||
// DNSSEC status
|
||||
var dnssecStatus;
|
||||
var ede = data[11];
|
||||
switch (data[6]) {
|
||||
case "1":
|
||||
dnssecStatus = '<br><span class="text-green">SECURE</span>';
|
||||
dnssecStatus = '<br><span class="text-green">SECURE';
|
||||
break;
|
||||
case "2":
|
||||
dnssecStatus = '<br><span class="text-orange">INSECURE</span>';
|
||||
dnssecStatus = '<br><span class="text-orange">INSECURE';
|
||||
break;
|
||||
case "3":
|
||||
dnssecStatus = '<br><span class="text-red">BOGUS</span>';
|
||||
dnssecStatus = '<br><span class="text-red">BOGUS';
|
||||
break;
|
||||
case "4":
|
||||
dnssecStatus = '<br><span class="text-red">ABANDONED</span>';
|
||||
dnssecStatus = '<br><span class="text-red">ABANDONED';
|
||||
break;
|
||||
case "5":
|
||||
dnssecStatus = '<br><span class="text-orange">UNKNOWN</span>';
|
||||
dnssecStatus = '<br><span class="text-orange">UNKNOWN';
|
||||
break;
|
||||
default:
|
||||
// No DNSSEC
|
||||
dnssecStatus = "";
|
||||
}
|
||||
|
||||
if (dnssecStatus.length > 0) {
|
||||
if (ede.length > 0) dnssecStatus += " (" + ede + ")";
|
||||
else if (replyid === 7) dnssecStatus += " (refused upstream)";
|
||||
dnssecStatus += "</span>";
|
||||
}
|
||||
|
||||
// Query status
|
||||
var fieldtext,
|
||||
buttontext,
|
||||
@@ -114,10 +122,10 @@ $(function () {
|
||||
break;
|
||||
case "2":
|
||||
colorClass = "text-green";
|
||||
fieldtext =
|
||||
"OK <br class='hidden-lg'>(forwarded to " +
|
||||
fieldtext = replyid === 0 ? "OK, sent to " : "OK, answered by ";
|
||||
fieldtext +=
|
||||
"<br class='hidden-lg'>" +
|
||||
(data.length > 10 && data[10] !== "N/A" ? data[10] : "") +
|
||||
")" +
|
||||
dnssecStatus;
|
||||
buttontext =
|
||||
'<button type="button" class="btn btn-default btn-sm text-red"><i class="fa fa-ban"></i> Blacklist</button>';
|
||||
@@ -208,6 +216,12 @@ $(function () {
|
||||
buttontext = "";
|
||||
}
|
||||
|
||||
// Add EDE here if available and not included in dnssecStatus
|
||||
if (ede.length > 0 && dnssecStatus.length === 0) fieldtext += " (" + ede + ")";
|
||||
|
||||
// Cannot block internal queries of this type
|
||||
if ((data[1] === "DNSKEY" || data[1] === "DS") && data[3] === "pi.hole") buttontext = "";
|
||||
|
||||
fieldtext += '<input type="hidden" name="id" value="' + parseInt(data[4], 10) + '">';
|
||||
|
||||
if (colorClass !== false) {
|
||||
@@ -252,7 +266,6 @@ $(function () {
|
||||
}
|
||||
|
||||
// Check for existence of sixth column and display only if not Pi-holed
|
||||
var replyid = data[5];
|
||||
var replytext =
|
||||
replyid >= 0 && replyid < replyTypes.length ? replyTypes[replyid] : "? (" + replyid + ")";
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ function check_csrf($token) {
|
||||
function check_domain(&$domains) {
|
||||
foreach($domains as &$domain)
|
||||
{
|
||||
$validDomain = is_valid_domain_name($domain);
|
||||
$validDomain = validDomain($domain);
|
||||
if(!$validDomain){
|
||||
log_and_die(htmlspecialchars($domain. ' is not a valid domain'));
|
||||
}
|
||||
|
||||
@@ -6,11 +6,86 @@
|
||||
* This file is copyright under the latest version of the EUPL.
|
||||
* Please see LICENSE file for your rights under this license. */
|
||||
|
||||
function is_valid_domain_name($domain_name)
|
||||
// Credit: http://stackoverflow.com/a/4694816/2087442
|
||||
// Modified because of https://github.com/pi-hole/AdminLTE/pull/533
|
||||
ini_set("pcre.recursion_limit", 1500);
|
||||
function validDomain($domain_name, &$message = NULL)
|
||||
{
|
||||
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
|
||||
if(!preg_match("/^((-|_)*[a-z\d]((-|_)*[a-z\d])*(-|_)*)(\.(-|_)*([a-z\d]((-|_)*[a-z\d])*))*$/i", $domain_name)) {
|
||||
if($message !== NULL)
|
||||
$message = "it contains invalid characters";
|
||||
return false;
|
||||
}
|
||||
if(!preg_match("/^.{1,253}$/", $domain_name)) {
|
||||
if($message !== NULL)
|
||||
$message = "its length is invalid";
|
||||
return false;
|
||||
}
|
||||
if(!preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name)) {
|
||||
if($message !== NULL)
|
||||
$message = "at least one label is of invalid length";
|
||||
return false;
|
||||
}
|
||||
|
||||
// everything is okay
|
||||
return true;
|
||||
}
|
||||
|
||||
function validDomainWildcard($domain_name)
|
||||
{
|
||||
// There has to be either no or at most one "*" at the beginning of a line
|
||||
$validChars = preg_match("/^((\*.)?[_a-z\d](-*[_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
|
||||
}
|
||||
|
||||
function validIP($address){
|
||||
if (preg_match('/[.:0]/', $address) && !preg_match('/[1-9a-f]/', $address)) {
|
||||
// Test if address contains either `:` or `0` but not 1-9 or a-f
|
||||
return false;
|
||||
}
|
||||
return !filter_var($address, FILTER_VALIDATE_IP) === false;
|
||||
}
|
||||
|
||||
function validCIDRIP($address){
|
||||
// This validation strategy has been taken from ../js/groups-common.js
|
||||
$isIPv6 = strpos($address, ":") !== false;
|
||||
if($isIPv6) {
|
||||
// One IPv6 element is 16bit: 0000 - FFFF
|
||||
$v6elem = "[0-9A-Fa-f]{1,4}";
|
||||
// CIDR for IPv6 is any multiple of 4 from 4 up to 128 bit
|
||||
$v6cidr = "(4";
|
||||
for ($i=8; $i <= 128; $i+=4) {
|
||||
$v6cidr .= "|$i";
|
||||
}
|
||||
$v6cidr .= ")";
|
||||
$validator = "/^(((?:$v6elem))((?::$v6elem))*::((?:$v6elem))((?::$v6elem))*|((?:$v6elem))((?::$v6elem)){7})\/$v6cidr$/";
|
||||
return preg_match($validator, $address);
|
||||
} else {
|
||||
// One IPv4 element is 8bit: 0 - 256
|
||||
$v4elem = "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)";
|
||||
// Note that rev-server accepts only /8, /16, /24, and /32
|
||||
$allowedv4cidr = "(8|16|24|32)";
|
||||
$validator = "/^$v4elem\.$v4elem\.$v4elem\.$v4elem\/$allowedv4cidr$/";
|
||||
return preg_match($validator, $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;
|
||||
}
|
||||
|
||||
function validEmail($email)
|
||||
{
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL)
|
||||
// Make sure that the email does not contain special characters which
|
||||
// may be used to execute shell commands, even though they may be valid
|
||||
// in an email address. If the escaped email does not equal the original
|
||||
// email, it is not safe to store in setupVars.
|
||||
&& escapeshellcmd($email) === $email;
|
||||
}
|
||||
|
||||
function get_ip_type($ip)
|
||||
@@ -145,7 +220,7 @@ function addCustomDNSEntry($ip="", $domain="", $json=true)
|
||||
if (empty($domain))
|
||||
return returnError("Domain must be set", $json);
|
||||
|
||||
if (!is_valid_domain_name($domain))
|
||||
if (!validDomain($domain))
|
||||
return returnError("Domain must be valid", $json);
|
||||
|
||||
// Only check for duplicates if adding new records from the web UI (not through Teleporter)
|
||||
@@ -302,13 +377,13 @@ function addCustomCNAMEEntry($domain="", $target="", $json=true)
|
||||
if (empty($target))
|
||||
return returnError("Target must be set", $json);
|
||||
|
||||
if (!is_valid_domain_name($target))
|
||||
if (!validDomain($target))
|
||||
return returnError("Target must be valid", $json);
|
||||
|
||||
// Check if each submitted domain is valid
|
||||
$domains = array_map('trim', explode(",", $domain));
|
||||
foreach ($domains as $d) {
|
||||
if (!is_valid_domain_name($d))
|
||||
if (!validDomain($d))
|
||||
return returnError("Domain '$d' is not valid", $json);
|
||||
}
|
||||
|
||||
|
||||
@@ -649,15 +649,16 @@ if ($_POST['action'] == 'get_groups') {
|
||||
{
|
||||
// If adding to the exact lists, we convert the domain lower case and check whether it is valid
|
||||
$domain = strtolower($domain);
|
||||
if(filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) === false)
|
||||
$msg = "";
|
||||
if(!validDomain($domain, $msg))
|
||||
{
|
||||
// This is the case when idn_to_ascii() modified the string
|
||||
if($input !== $domain && strlen($domain) > 0)
|
||||
$errormsg = 'Domain ' . htmlentities($input) . ' (converted to "' . htmlentities(utf8_encode($domain)) . '") is not a valid domain.';
|
||||
$errormsg = 'Domain ' . htmlentities($input) . ' (converted to "' . htmlentities(utf8_encode($domain)) . '") is not a valid domain because ' . $msg . '.';
|
||||
elseif($input !== $domain)
|
||||
$errormsg = 'Domain ' . htmlentities($input) . ' is not a valid domain.';
|
||||
$errormsg = 'Domain ' . htmlentities($input) . ' is not a valid domain because ' . $msg . '.';
|
||||
else
|
||||
$errormsg = 'Domain ' . htmlentities(utf8_encode($domain)) . ' is not a valid domain.';
|
||||
$errormsg = 'Domain ' . htmlentities(utf8_encode($domain)) . ' is not a valid domain because ' . $msg . '.';
|
||||
throw new Exception($errormsg . '<br>Added ' . $added . " out of ". $total . " domains");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
while (ob_get_level() > 0) {
|
||||
ob_end_flush();
|
||||
}
|
||||
require_once("func.php");
|
||||
ini_set("output_buffering", "0");
|
||||
ob_implicit_flush(true);
|
||||
header('Content-Type: text/event-stream');
|
||||
@@ -21,22 +22,12 @@ function echoEvent($datatext) {
|
||||
echo $datatext;
|
||||
}
|
||||
|
||||
// Credit: http://stackoverflow.com/a/4694816/2087442
|
||||
ini_set("pcre.recursion_limit", 1500);
|
||||
function is_valid_domain_name($domain_name)
|
||||
{
|
||||
return ($domain_name[0] !== '-' // Don't allow domains to appear as command line options
|
||||
&& 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))
|
||||
if(!validDomain($url))
|
||||
{
|
||||
echoEvent("Invalid domain!");
|
||||
die();
|
||||
|
||||
@@ -6,43 +6,13 @@
|
||||
* This file is copyright under the latest version of the EUPL.
|
||||
* Please see LICENSE file for your rights under this license. */
|
||||
|
||||
require_once("func.php");
|
||||
|
||||
if(!in_array(basename($_SERVER['SCRIPT_FILENAME']), ["settings.php", "teleporter.php"], true))
|
||||
{
|
||||
die("Direct access to this script is forbidden!");
|
||||
}
|
||||
|
||||
function validIP($address){
|
||||
if (preg_match('/[.:0]/', $address) && !preg_match('/[1-9a-f]/', $address)) {
|
||||
// Test if address contains either `:` or `0` but not 1-9 or a-f
|
||||
return false;
|
||||
}
|
||||
return !filter_var($address, FILTER_VALIDATE_IP) === false;
|
||||
}
|
||||
|
||||
function validCIDRIP($address){
|
||||
// This validation strategy has been taken from ../js/groups-common.js
|
||||
$isIPv6 = strpos($address, ":") !== false;
|
||||
if($isIPv6) {
|
||||
// One IPv6 element is 16bit: 0000 - FFFF
|
||||
$v6elem = "[0-9A-Fa-f]{1,4}";
|
||||
// CIDR for IPv6 is any multiple of 4 from 4 up to 128 bit
|
||||
$v6cidr = "(4";
|
||||
for ($i=8; $i <= 128; $i+=4) {
|
||||
$v6cidr .= "|$i";
|
||||
}
|
||||
$v6cidr .= ")";
|
||||
$validator = "/^(((?:$v6elem))((?::$v6elem))*::((?:$v6elem))((?::$v6elem))*|((?:$v6elem))((?::$v6elem)){7})\/$v6cidr$/";
|
||||
return preg_match($validator, $address);
|
||||
} else {
|
||||
// One IPv4 element is 8bit: 0 - 256
|
||||
$v4elem = "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)";
|
||||
// Note that rev-server accepts only /8, /16, /24, and /32
|
||||
$allowedv4cidr = "(8|16|24|32)";
|
||||
$validator = "/^$v4elem\.$v4elem\.$v4elem\.$v4elem\/$allowedv4cidr$/";
|
||||
return preg_match($validator, $address);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for existance of variable
|
||||
// and test it only if it exists
|
||||
function istrue(&$argument) {
|
||||
@@ -56,30 +26,6 @@ function istrue(&$argument) {
|
||||
return 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])*))*(\.([_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
|
||||
}
|
||||
|
||||
function validDomainWildcard($domain_name)
|
||||
{
|
||||
// There has to be either no or at most one "*" at the beginning of a line
|
||||
$validChars = preg_match("/^((\*\.)?[_a-z\d](-*[_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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function formatMAC($mac_addr)
|
||||
{
|
||||
preg_match("/([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})/", $mac_addr, $matches);
|
||||
@@ -88,16 +34,6 @@ function formatMAC($mac_addr)
|
||||
return null;
|
||||
}
|
||||
|
||||
function validEmail($email)
|
||||
{
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL)
|
||||
// Make sure that the email does not contain special characters which
|
||||
// may be used to execute shell commands, even though they may be valid
|
||||
// in an email address. If the escaped email does not equal the original
|
||||
// email, it is not safe to store in setupVars.
|
||||
&& escapeshellcmd($email) === $email;
|
||||
}
|
||||
|
||||
$dhcp_static_leases = array();
|
||||
function readStaticLeasesFile($origin_file="/etc/dnsmasq.d/04-pihole-static-dhcp.conf")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user