diff --git a/scripts/pi-hole/php/savesettings.php b/scripts/pi-hole/php/savesettings.php
index ef09491c..043fb4ad 100644
--- a/scripts/pi-hole/php/savesettings.php
+++ b/scripts/pi-hole/php/savesettings.php
@@ -6,7 +6,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
-if(!in_array(basename($_SERVER['SCRIPT_FILENAME']), array("settings.php", "teleporter.php"), true))
+if(!in_array(basename($_SERVER['SCRIPT_FILENAME']), ["settings.php", "teleporter.php"], true))
{
die("Direct access to this script is forbidden!");
}
@@ -53,7 +53,15 @@ function validDomainWildcard($domain_name)
function validMAC($mac_addr)
{
// Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case)
- return (preg_match('/([a-fA-F0-9]{2}[:]?){6}/', $mac_addr) == 1);
+ 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);
+ if(count($matches) > 0)
+ return $matches[0];
+ return null;
}
function validEmail($email)
@@ -66,15 +74,18 @@ function validEmail($email)
&& escapeshellcmd($email) === $email;
}
-function processStaticLeasesFile($file_path) {
- $dhcp_static_leases_local = array();
+$dhcp_static_leases = array();
+function readStaticLeasesFile($origin_file="/etc/dnsmasq.d/04-pihole-static-dhcp.conf")
+{
+ global $dhcp_static_leases;
+ $dhcp_static_leases = array();
try
{
- $dhcpstatic = @fopen($file_path, 'r');
+ $dhcpstatic = @fopen($origin_file, 'r');
}
catch(Exception $e)
{
- echo "Warning: Failed to read $file_path, this is not an error";
+ echo "Warning: Failed to read ".$origin_file.", this is not an error";
return false;
}
@@ -90,34 +101,21 @@ function processStaticLeasesFile($file_path) {
{
if(validIP($one) && strlen($two) == 0)
// dhcp-host=mac,IP - no HOST
- array_push($dhcp_static_leases_local,["hwaddr"=>$mac, "IP"=>$one, "host"=>""]);
+ array_push($dhcp_static_leases,["hwaddr"=>$mac, "IP"=>$one, "host"=>""]);
elseif(strlen($two) == 0)
// dhcp-host=mac,hostname - no IP
- array_push($dhcp_static_leases_local,["hwaddr"=>$mac, "IP"=>"", "host"=>$one]);
+ array_push($dhcp_static_leases,["hwaddr"=>$mac, "IP"=>"", "host"=>$one]);
else
// dhcp-host=mac,IP,hostname
- array_push($dhcp_static_leases_local,["hwaddr"=>$mac, "IP"=>$one, "host"=>$two]);
+ array_push($dhcp_static_leases,["hwaddr"=>$mac, "IP"=>$one, "host"=>$two]);
}
else if(validIP($one) && validDomain($mac))
{
// dhcp-host=hostname,IP - no MAC
- array_push($dhcp_static_leases_local,["hwaddr"=>"", "IP"=>$one, "host"=>$mac]);
+ array_push($dhcp_static_leases,["hwaddr"=>"", "IP"=>$one, "host"=>$mac]);
}
}
- return $dhcp_static_leases_local;
-}
-
-$dhcp_static_leases = array();
-function readStaticLeasesFile()
-{
- global $dhcp_static_leases;
- $dhcp_static_leases = array();
- $result = processStaticLeasesFile('/etc/dnsmasq.d/04-pihole-static-dhcp.conf');
- if($result !== false) {
- $dhcp_static_leases = $result;
- return true;
- }
- return $result;
+ return true;
}
function isequal(&$argument, &$compareto) {
@@ -195,64 +193,62 @@ function readAdlists()
return $list;
}
-function addDHCPLease($mac, $ip, $hostname) {
- $result = array('message' => "", 'value' => false);
+function addStaticDHCPLease($mac, $ip, $hostname) {
+ global $error, $success, $dhcp_static_leases;
- if(!validMAC($mac))
- {
- $result['message'] .= "MAC address (".htmlspecialchars($mac).") is invalid!
";
- }
- $mac = strtoupper($mac);
-
- if(!validIP($ip) && strlen($ip) > 0)
- {
- $result['message'] .= "IP address (".htmlspecialchars($ip).") is invalid!
";
- }
-
- if(!validDomain($hostname) && strlen($hostname) > 0)
- {
- $result['message'] .= "Host name (".htmlspecialchars($hostname).") is invalid!
";
- }
-
- if(strlen($hostname) == 0 && strlen($ip) == 0)
- {
- $result['message'] .= "You can not omit both the IP address and the host name!
";
- }
-
- if(strlen($hostname) == 0)
- $hostname = "nohost";
-
- if(strlen($ip) == 0)
- $ip = "noip";
-
- // Test if this lease is already included
- readStaticLeasesFile();
- global $dhcp_static_leases;
- foreach($dhcp_static_leases as $lease) {
- if($lease["hwaddr"] === $mac)
+ try {
+ if(!validMAC($mac))
{
- $result['message'] .= "Static release for MAC address (".htmlspecialchars($mac).") already defined!
";
- break;
+ throw new Exception("MAC address (".htmlspecialchars($mac).") is invalid!
", 0);
+ }
+ $mac = strtoupper($mac);
+
+ if(!validIP($ip) && strlen($ip) > 0)
+ {
+ throw new Exception("IP address (".htmlspecialchars($ip).") is invalid!
", 1);
+ }
+
+ if(!validDomain($hostname) && strlen($hostname) > 0)
+ {
+ throw new Exception("Host name (".htmlspecialchars($hostname).") is invalid!
", 2);
+ }
+
+ if(strlen($hostname) == 0 && strlen($ip) == 0)
+ {
+ throw new Exception("You can not omit both the IP address and the host name!
", 3);
+ }
+
+ if(strlen($hostname) == 0)
+ $hostname = "nohost";
+
+ if(strlen($ip) == 0)
+ $ip = "noip";
+
+ // Test if this lease is already included
+ readStaticLeasesFile();
+
+ foreach($dhcp_static_leases as $lease) {
+ if($lease["hwaddr"] === $mac)
+ {
+ throw new Exception("Static release for MAC address (".htmlspecialchars($mac).") already defined!
", 4);
+ }
+ if($ip !== "noip" && $lease["IP"] === $ip)
+ {
+ throw new Exception("Static lease for IP address (".htmlspecialchars($ip).") already defined!
", 5);
+ }
+ if($lease["host"] === $hostname)
+ {
+ throw new Exception("Static lease for hostname (".htmlspecialchars($hostname).") already defined!
", 6);
+ }
}
- if($ip !== "noip" && $lease["IP"] === $ip)
- {
- $result['message'] .= "Static lease for IP address (".htmlspecialchars($ip).") already defined!
";
- break;
- }
- if($lease["host"] === $hostname)
- {
- $result['message'] .= "Static lease for hostname (".htmlspecialchars($hostname).") already defined!
";
- break;
- }
- }
- if(!strlen($result['message']))
- {
exec("sudo pihole -a addstaticdhcp ".$mac." ".$ip." ".$hostname);
- $result['message'] = "A new static address has been added";
- $result['value'] = true;
+ $success .= "A new static address has been added";
+ return true;
+ } catch(Exception $exception) {
+ $error .= $exception->getMessage();
+ return false;
}
- return $result;
}
// Read available adlists
@@ -604,12 +600,11 @@ function addDHCPLease($mac, $ip, $hostname) {
if(isset($_POST["addstatic"]))
{
- $result = addDHCPLease($_POST["AddMAC"], $_POST["AddIP"], $_POST["AddHostname"]);
- if($result['value']) {
- $success .= $result['message'];
- } else {
- $error .= $result['message'];
- }
+ $mac = $_POST["AddMAC"];
+ $ip = $_POST["AddIP"];
+ $hostname = $_POST["AddHostname"];
+
+ addStaticDHCPLease($mac, $ip, $hostname);
break;
}
diff --git a/scripts/pi-hole/php/teleporter.php b/scripts/pi-hole/php/teleporter.php
index 8fb35702..8e741fae 100644
--- a/scripts/pi-hole/php/teleporter.php
+++ b/scripts/pi-hole/php/teleporter.php
@@ -9,7 +9,7 @@
require "password.php";
require "auth.php"; // Also imports func.php
require "database.php";
-require_once "savesettings.php";
+require "savesettings.php";
if (php_sapi_name() !== "cli") {
if(!$auth) die("Not authorized");
@@ -53,7 +53,6 @@ function archive_add_table($name, $table)
$archive[$name] = json_encode($content);
}
-
/**
* Restore the contents of a table from an uploaded archive
*
@@ -153,7 +152,6 @@ function archive_restore_table($file, $table, $flush=false)
return $num;
}
-=======
/**
* Create table rows from an uploaded archive file
*
@@ -198,6 +196,22 @@ function archive_add_directory($path,$subdir="")
}
}
+function limit_length(&$item, $key)
+{
+ // limit max length for a domain entry to 253 chars
+ // return only a part of the string if it is longer
+ $item = substr($item, 0, 253);
+}
+
+function process_file($contents)
+{
+ $domains = array_filter(explode("\n",$contents));
+ // Walk array and apply a max string length
+ // function to every member of the array of domains
+ array_walk($domains, "limit_length");
+ return $domains;
+}
+
if(isset($_POST["action"]))
{
if($_FILES["zip_file"]["name"] && $_POST["action"] == "in")
@@ -233,7 +247,7 @@ if(isset($_POST["action"]))
$flushtables = isset($_POST["flushtables"]);
- foreach($archive as $file)
+ foreach(new RecursiveIteratorIterator($archive) as $file)
{
if(isset($_POST["blacklist"]) && $file->getFilename() === "blacklist.txt")
{
@@ -312,6 +326,31 @@ if(isset($_POST["action"]))
echo "Processed domain_audit (".$num." entries)
\n";
$importedsomething = true;
}
+
+ if(isset($_POST["staticdhcpleases"]) && $file->getFilename() === "04-pihole-static-dhcp.conf")
+ {
+ if($flushtables) {
+ $local_file = @fopen("/etc/dnsmasq.d/04-pihole-static-dhcp.conf", "r+");
+ if ($local_file !== false) {
+ ftruncate($local_file, 0);
+ fclose($local_file);
+ }
+ }
+ $num = 0;
+ $staticdhcpleases = process_file(file_get_contents($file));
+ foreach($staticdhcpleases as $lease) {
+ list($mac,$ip,$hostname) = explode(",",$lease);
+ $mac = formatMAC($mac);
+ if(addStaticDHCPLease($mac,$ip,$hostname))
+ $num++;
+ }
+
+ readStaticLeasesFile();
+ echo "Processed static DHCP leases (".$num." entries)
\n";
+ if($num > 0) {
+ $importedsomething = true;
+ }
+ }
}
if($importedsomething)
diff --git a/settings.php b/settings.php
index 29094927..6cf8c0a9 100644
--- a/settings.php
+++ b/settings.php
@@ -1140,7 +1140,7 @@ if (isset($_GET['tab']) && in_array($_GET['tab'], array("sysadmin", "blocklists"