Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow space separated multiple items injection #1149

Merged
merged 3 commits into from Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 0 additions & 22 deletions scripts/pi-hole/js/settings.js
Expand Up @@ -217,28 +217,6 @@ $(document).ready(function() {
$('[data-toggle="tooltip"]').tooltip({ html: true, container: "body" });
});

// Handle list deletion
$("button[id^='adlist-btn-']").on("click", function(e) {
var id = parseInt($(this).context.id.replace(/[^0-9.]/g, ""), 10);
e.preventDefault();

var status = $('input[name="adlist-del-' + id + '"]').is(":checked");
var textType = status ? "none" : "line-through";

// Check hidden delete box (or reset)
$('input[name="adlist-del-' + id + '"]').prop("checked", !status);
// Untick and disable check box (or reset)
$('input[name="adlist-enable-' + id + '"]')
.prop("checked", status)
.prop("disabled", !status);
// Strike through text (or reset)
$('a[id="adlist-text-' + id + '"]').css("text-decoration", textType);
// Highlight that the button has to be clicked in order to make the change live
$('button[id="blockinglistsaveupdate"]')
.addClass("btn-danger")
.css("font-weight", "bold");
});

// Change "?tab=" parameter in URL for save and reload
$(".nav-tabs a").on("shown.bs.tab", function(e) {
var tab = e.target.hash.substring(1);
Expand Down
125 changes: 66 additions & 59 deletions scripts/pi-hole/php/groups.php
Expand Up @@ -54,21 +54,24 @@ function JSON_error($message = null)
} elseif ($_POST['action'] == 'add_group') {
// Add new group
try {
$names = explode(' ', $_POST['name']);
$stmt = $db->prepare('INSERT INTO "group" (name,description) VALUES (:name,:desc)');
if (!$stmt) {
throw new Exception('While preparing statement: ' . $db->lastErrorMsg());
}

if (!$stmt->bindValue(':name', $_POST['name'], SQLITE3_TEXT)) {
throw new Exception('While binding name: ' . $db->lastErrorMsg());
}

if (!$stmt->bindValue(':desc', $_POST['desc'], SQLITE3_TEXT)) {
throw new Exception('While binding desc: ' . $db->lastErrorMsg());
}

if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
foreach ($names as $name) {
if (!$stmt->bindValue(':name', $name, SQLITE3_TEXT)) {
throw new Exception('While binding name: ' . $db->lastErrorMsg());
}

if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
}
}

$reload = true;
Expand Down Expand Up @@ -157,7 +160,6 @@ function JSON_error($message = null)
throw new Exception('Error while querying gravity\'s client table: ' . $db->lastErrorMsg());
}


$data = array();
while (($res = $query->fetchArray(SQLITE3_ASSOC)) !== false) {
$group_query = $db->query('SELECT group_id FROM client_by_group WHERE client_id = ' . $res['id'] . ';');
Expand Down Expand Up @@ -232,26 +234,29 @@ function JSON_error($message = null)
} elseif ($_POST['action'] == 'add_client') {
// Add new client
try {
$ips = explode(' ', $_POST['ip']);
$stmt = $db->prepare('INSERT INTO client (ip,comment) VALUES (:ip,:comment)');
if (!$stmt) {
throw new Exception('While preparing statement: ' . $db->lastErrorMsg());
}

if (!$stmt->bindValue(':ip', $_POST['ip'], SQLITE3_TEXT)) {
throw new Exception('While binding ip: ' . $db->lastErrorMsg());
}
foreach ($ips as $ip) {
if (!$stmt->bindValue(':ip', $ip, SQLITE3_TEXT)) {
throw new Exception('While binding ip: ' . $db->lastErrorMsg());
}

$comment = $_POST['comment'];
if (strlen($comment) == 0) {
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
}
$comment = $_POST['comment'];
if (strlen($comment) == 0) {
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
}

if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
}
}

$reload = true;
Expand Down Expand Up @@ -405,39 +410,13 @@ function JSON_error($message = null)
} elseif ($_POST['action'] == 'add_domain') {
// Add new domain
try {
$domains = explode(' ', $_POST['domain']);
$stmt = $db->prepare('INSERT INTO domainlist (domain,type,comment) VALUES (:domain,:type,:comment)');
if (!$stmt) {
throw new Exception('While preparing statement: ' . $db->lastErrorMsg());
}

$type = intval($_POST['type']);
$domain = $_POST['domain'];

if(strlen($_POST['type']) === 2 && $_POST['type'][1] === 'W')
{
// Apply wildcard-style formatting
$domain = "(\\.|^)".str_replace(".","\\.",$domain)."$";
}

if ($type === ListType::whitelist || $type === ListType::blacklist) {
// Convert domain name to IDNA ASCII form for international
// domains and convert the domain to lower case
// Only use IDN routine when php-intl is available
if (extension_loaded("intl")) {
$domain = idn_to_ascii($domain);
}
$domain = strtolower($domain);

// Check validity of domain
if(filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) === false)
{
throw new Exception('Domain ' . htmlentities(utf8_encode($domain)) . 'is not a valid domain.');
}
}

if (!$stmt->bindValue(':domain', $domain, SQLITE3_TEXT)) {
throw new Exception('While binding domain: ' . $db->lastErrorMsg());
}

if (!$stmt->bindValue(':type', $type, SQLITE3_TEXT)) {
throw new Exception('While binding type: ' . $db->lastErrorMsg());
Expand All @@ -447,8 +426,33 @@ function JSON_error($message = null)
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
}

if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
foreach ($domains as $domain) {
// Convert domain name to IDNA ASCII form for international domains
$domain = idn_to_ascii($domain);

if(strlen($_POST['type']) === 2 && $_POST['type'][1] === 'W')
{
// Apply wildcard-style formatting
$domain = "(\\.|^)".str_replace(".","\\.",$domain)."$";
}

if($type === ListType::whitelist || $type === ListType::blacklist)
{
// 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)
{
throw new Exception('Domain ' . htmlentities(utf8_encode($domain)) . 'is not a valid domain.');
}
}

if (!$stmt->bindValue(':domain', $domain, SQLITE3_TEXT)) {
throw new Exception('While binding domain: ' . $db->lastErrorMsg());
}

if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
}
}

$reload = true;
Expand Down Expand Up @@ -600,26 +604,29 @@ function JSON_error($message = null)
} elseif ($_POST['action'] == 'add_adlist') {
// Add new adlist
try {
$address = $_POST['address'];
if(preg_match("/[^a-zA-Z0-9:\/?&%=~._-]/", $address) !== 0) {
throw new Exception('Invalid adlist URL');
}
$addresses = explode(' ', $_POST['address']);

$stmt = $db->prepare('INSERT INTO adlist (address,comment) VALUES (:address,:comment)');
if (!$stmt) {
throw new Exception('While preparing statement: ' . $db->lastErrorMsg());
}

if (!$stmt->bindValue(':address', $address, SQLITE3_TEXT)) {
throw new Exception('While binding address: ' . $db->lastErrorMsg());
}

if (!$stmt->bindValue(':comment', $_POST['comment'], SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
}

if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
foreach ($addresses as $address) {
if(preg_match("/[^a-zA-Z0-9:\/?&%=~._-]/", $address) !== 0) {
throw new Exception('Invalid adlist URL');
}

if (!$stmt->bindValue(':address', $address, SQLITE3_TEXT)) {
throw new Exception('While binding address: ' . $db->lastErrorMsg());
}

if (!$stmt->execute()) {
throw new Exception('While executing: ' . $db->lastErrorMsg());
}
}

$reload = true;
Expand Down
55 changes: 0 additions & 55 deletions scripts/pi-hole/php/savesettings.php
Expand Up @@ -174,24 +174,6 @@ function readDNSserversList()
}

require_once("database.php");
$adlist = [];
function readAdlists()
{
// Reset list
$list = [];
$db = SQLite3_connect(getGravityDBFilename());
if ($db)
{
$results = $db->query("SELECT * FROM adlist");

while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{
array_push($list, $res);
}
$db->close();
}
return $list;
}

function addStaticDHCPLease($mac, $ip, $hostname) {
global $error, $success, $dhcp_static_leases;
Expand Down Expand Up @@ -251,8 +233,6 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
}
}

// Read available adlists
$adlist = readAdlists();
// Read available DNS server list
$DNSserverslist = readDNSserversList();

Expand Down Expand Up @@ -698,41 +678,6 @@ function addStaticDHCPLease($mac, $ip, $hostname) {

break;

case "adlists":
foreach ($adlist as $key => $value)
{
if(isset($_POST["adlist-del-".$key]))
{
// Delete list
exec("sudo pihole -a adlist del ".escapeshellcmd($value["address"]));
}
elseif(isset($_POST["adlist-enable-".$key]) && $value["enabled"] !== 1)
{
// Is not enabled, but should be
exec("sudo pihole -a adlist enable ".escapeshellcmd($value["address"]));

}
elseif(!isset($_POST["adlist-enable-".$key]) && $value["enabled"] === 1)
{
// Is enabled, but shouldn't be
exec("sudo pihole -a adlist disable ".escapeshellcmd($value["address"]));
}
}

if(strlen($_POST["newuserlists"]) > 1)
{
$domains = array_filter(preg_split('/\r\n|[\r\n]/', $_POST["newuserlists"]));
$comment = "'".$_POST["newusercomment"]."'";
foreach($domains as $domain)
{
exec("sudo pihole -a adlist add ".escapeshellcmd($domain)." ".escapeshellcmd($comment));
}
}

// Reread available adlists
$adlist = readAdlists();
break;

case "privacyLevel":
$level = intval($_POST["privacylevel"]);
if($level >= 0 && $level <= 4)
Expand Down
61 changes: 2 additions & 59 deletions settings.php
Expand Up @@ -250,67 +250,10 @@
<div class="col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Blocklists used to generate Pi-hole's Gravity: <?php echo count($adlist); ?></h3>
<h3 class="box-title">Blocklists used to generate Pi-hole's Gravity</h3>
</div>
<div class="box-body">
<div class="table-responsive">
<table class="table table-striped table-bordered dt-responsive nowrap">
<thead>
<tr>
<th style="width:1%">Enabled</th>
<th>List</th>
<th>Added</th>
<th>Last modified</th>
<th>Comment</th>
<th style="width:1%">Delete</th>
</tr>
</thead>
<tbody>
<?php foreach ($adlist as $key => $value) { ?>
<tr>
<td>
<input type="checkbox" name="adlist-enable-<?php echo $key; ?>" <?php if ($value["enabled"] === 1){ ?>checked<?php } ?>>
</td>
<td>
<a href="<?php echo htmlentities($value["address"]); ?>" target="_new" id="adlist-text-<?php echo $key; ?>"><?php echo htmlentities($value["address"]); ?></a>
</td>
<td>
<?php echo date(DateTime::RFC2822, intval($value["date_added"])); ?>
</td>
<td>
<?php echo date(DateTime::RFC2822, intval($value["date_modified"])); ?>
</td>
<td>
<?php echo htmlentities($value["comment"]); ?>
</td>
<td class="text-center">
<button class="btn btn-danger btn-xs" id="adlist-btn-<?php echo $key; ?>">
<span class="glyphicon glyphicon-trash"></span>
</button>
<input type="checkbox" name="adlist-del-<?php echo $key; ?>" hidden>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<div class="form-group row">
<div class="col-xs-6">
<label for="newuserlists">Domain:</label>
<input name="newuserlists" type="text" class="form-control" placeholder="Enter a URL to add a new blocklist">
</div>
<div class="col-xs-6">
<label for="newusercomment">Comment:</label>
<input name="newusercomment" type="text" class="form-control" placeholder="Include a comment (optional)">
</div>
</div>
<input type="hidden" name="field" value="adlists">
<input type="hidden" name="token" value="<?php echo $token ?>">
</div>
<div class="box-footer clearfix">
<button type="submit" class="btn btn-primary" name="submit" value="save" id="blockinglistsave">Save</button>
<span><strong>Important: </strong>Save and Update when you're done!</span>
<button type="submit" class="btn btn-primary pull-right" name="submit" id="blockinglistsaveupdate" value="saveupdate">Save and Update</button>
<p>Please use the <a href="groups-adlists.php">group management pages</a> to edit the blocklists used by Pi-hole.</p>
</div>
</div>
</div>
Expand Down