Remove "Remember me for 7 days" checkbox. Each user gets their own independent session. By default, the session will expire after 5 minutes of no web interface being open (otherwise, it is continuously prolonged because of all the background API activity while refreshing the statistics). This timeout, however, can be set freely in pihole.toml and soon also in the web interface so this checkbox has stoped being useful.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2023-02-03 18:07:11 +01:00
parent ccced4c1a8
commit d7eada8156
6 changed files with 3 additions and 438 deletions

View File

@@ -9,7 +9,6 @@
*/
$wrongpassword = false;
require_once 'func.php';
require 'scripts/pi-hole/php/theme.php';
require 'scripts/pi-hole/php/header.php';
@@ -27,7 +26,7 @@ require 'scripts/pi-hole/php/header.php';
<div class="card">
<div class="card-body login-card-body">
<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>
<div id="cookieInfo" class="panel-title text-center text-red" style="font-size: 150%" hidden>Verify that cookies are allowed</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>
@@ -42,10 +41,6 @@ require 'scripts/pi-hole/php/header.php';
<input type="password" id="loginpw" name="pw" class="form-control" placeholder="Password" spellcheck="false" autocomplete="current-password" autofocus>
<span class="fa fa-key form-control-feedback"></span>
</div>
<div>
<input type="checkbox" id="logincookie" name="persistentlogin" disabled="true">
<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>

View File

@@ -1,134 +0,0 @@
<?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_once 'func.php';
$ERRORLOG = getenv('PHP_ERROR_LOG');
if (empty($ERRORLOG)) {
$ERRORLOG = '/var/log/lighttpd/error-pihole.log';
if (!file_exists($ERRORLOG) || !is_writable($ERRORLOG)) {
$ERRORLOG = '/var/log/apache2/error.log';
if (!file_exists($ERRORLOG) || !is_writable($ERRORLOG)) {
$ERRORLOG = '/tmp/pi-hole-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);
exit($message);
}
function check_cors()
{
$ip = $_SERVER['SERVER_ADDR'];
// Check CORS
$AUTHORIZED_HOSTNAMES = array(
$ip,
str_replace(array('[', ']'), array('', ''), $_SERVER['SERVER_NAME']),
'pi.hole',
'localhost',
);
// Allow user set virtual hostnames
$virtual_host = getenv('VIRTUAL_HOST');
if (!empty($virtual_host)) {
array_push($AUTHORIZED_HOSTNAMES, $virtual_host);
}
// Allow user set CORS
$cors_hosts = getenv('CORS_HOSTS');
if (!empty($cors_hosts)) {
// Push all hosts from comma separated list
$cors_hosts_array = explode(',', $cors_hosts);
// Add all hosts to the list of authorized hosts
foreach ($cors_hosts_array as $host) {
array_push($AUTHORIZED_HOSTNAMES, $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.
$server_host = $_SERVER['HTTP_HOST'];
// Use parse_url if HTTP_HOST contains a colon (:) to get the host name
// e.g.
// https://pi.hole
// pi.hole:8080
// However, we don't use parse_url(...) if there is no colon, since it will fail for e.g. "pi.hole"
// Don't use parse_url for IPv6 addresses, since it does not support them
// see PHP bug report: https://bugs.php.net/bug.php?id=72811
if (strpos($server_host, ':') && !strpos($server_host, '[') && !strpos($server_host, ']')) {
$server_host = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST);
}
// Remove "[" ... "]"
$server_host = str_replace(array('[', ']'), array('', ''), $server_host);
if (isset($_SERVER['HTTP_HOST']) && !in_array($server_host, $AUTHORIZED_HOSTNAMES)) {
log_and_die('Failed Host Check: '.$server_host.' vs '.htmlspecialchars(join(', ', $AUTHORIZED_HOSTNAMES)));
}
if (isset($_SERVER['HTTP_ORIGIN'])) {
$server_origin = $_SERVER['HTTP_ORIGIN'];
// Detect colon in $_SERVER['HTTP_ORIGIN'] (see comment above)
if (strpos($server_origin, ':') && !strpos($server_origin, '[') && !strpos($server_origin, ']')) {
$server_origin = parse_url($_SERVER['HTTP_ORIGIN'], PHP_URL_HOST);
}
// Remove "[", "]","http://", and "https://"
$server_origin = str_replace(array('[', ']', 'http://', 'https://'), array('', '', '', ''), $server_origin);
if (!in_array($server_origin, $AUTHORIZED_HOSTNAMES)) {
log_and_die('Failed CORS: '.htmlspecialchars($server_origin).' vs '.htmlspecialchars(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)
{
// Start a new PHP session (or continue an existing one)
if (session_status() != PHP_SESSION_ACTIVE) {
start_php_session();
}
if (!isset($_SESSION['token'])) {
log_and_die('Session expired! Please re-login on the Pi-hole dashboard.');
}
if (empty($token)) {
log_and_die('Empty token! Check if cookies are enabled on your system.');
}
if (!hash_equals($_SESSION['token'], $token)) {
log_and_die('Wrong token! Please re-login on the Pi-hole dashboard.');
}
}
function check_domain(&$domains)
{
foreach ($domains as &$domain) {
$validDomain = validDomain($domain);
if (!$validDomain) {
log_and_die(htmlspecialchars($domain.' is not a valid domain'));
}
}
}

View File

@@ -1,290 +0,0 @@
<?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.
*/
// 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)
{
// special handling of the root zone `.`
if ($domain_name == '.') {
return true;
}
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)
{
// Skip this checks for the root zone `.`
if ($domain_name == '.') {
return true;
}
// 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}';
// dnsmasq allows arbitrary prefix-length since https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=35f93081dc9a52e64ac3b7196ad1f5c1106f8932
$v6cidr = '([1-9]|[1-9][0-9]|1[01][0-9]|12[0-8])';
$validator = "/^(((?:{$v6elem}))((?::{$v6elem}))*::((?:{$v6elem}))((?::{$v6elem}))*|((?:{$v6elem}))((?::{$v6elem})){7})\\/{$v6cidr}$/";
return preg_match($validator, $address);
}
// 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)';
// dnsmasq allows arbitrary prefix-length
$allowedv4cidr = '(([1-9]|[12][0-9]|3[0-2]))';
$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 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);
}
*/
function checkfile($filename)
{
if (is_readable($filename)) {
return $filename;
}
// substitute dummy file
return '/dev/null';
}
// 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;
}
}
function returnSuccess($message = '', $json = true)
{
if ($json) {
return array('success' => true, 'message' => $message);
}
echo $message.'<br>';
return true;
}
function returnError($message = '', $json = true)
{
$message = htmlentities($message);
if ($json) {
return array('success' => false, 'message' => $message);
}
echo $message.'<br>';
return false;
}
function getQueryTypeStr($querytype)
{
$qtypes = array('A', 'AAAA', 'ANY', 'SRV', 'SOA', 'PTR', 'TXT', 'NAPTR', 'MX', 'DS', 'RRSIG', 'DNSKEY', 'NS', 'OTHER', 'SVCB', 'HTTPS');
$qtype = intval($querytype);
if ($qtype > 0 && $qtype <= count($qtypes)) {
return $qtypes[$qtype - 1];
}
return 'TYPE'.($qtype - 100);
}
// Functions to return Alert messages (success, error, warning) in JSON format.
// Used in multiple pages.
// Return Success message in JSON format
function JSON_success($message = null)
{
/* header('Content-type: application/json'); */
echo json_encode(array('success' => true, 'message' => $message));
}
// Return Error message in JSON format
function JSON_error($message = null)
{
/* header('Content-type: application/json'); */
$response = array('success' => false, 'message' => $message);
if (isset($_POST['action'])) {
array_push($response, array('action' => $_POST['action']));
}
echo json_encode($response);
}
// Return Warning message in JSON format.
// - sends "success", because it wasn't a failure.
// - sends "warning" to use the correct alert type.
function JSON_warning($message = null)
{
/* header('Content-type: application/json'); */
echo json_encode(array(
'success' => true,
'warning' => true,
'message' => $message,
));
}
// Try to convert possible IDNA domain to Unicode
function convertIDNAToUnicode($IDNA)
{
if (extension_loaded('intl')) {
// we try the UTS #46 standard first
// as this is the new default, see https://sourceforge.net/p/icu/mailman/message/32980778/
// We know that this fails for some Google domains violating the standard
// see https://github.com/pi-hole/AdminLTE/issues/1223
if (defined('INTL_IDNA_VARIANT_UTS46')) {
// We have to use the option IDNA_NONTRANSITIONAL_TO_ASCII here
// to ensure sparkasse-gießen.de is not converted into
// sparkass-giessen.de but into xn--sparkasse-gieen-2ib.de
// as mandated by the UTS #46 standard
$unicode = idn_to_utf8($IDNA, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
} elseif (defined('INTL_IDNA_VARIANT_2003')) {
// If conversion failed, try with the (deprecated!) IDNA 2003 variant
// We have to check for its existence as support of this variant is
// scheduled for removal with PHP 8.0
// see https://wiki.php.net/rfc/deprecate-and-remove-intl_idna_variant_2003
$unicode = idn_to_utf8($IDNA, IDNA_DEFAULT, INTL_IDNA_VARIANT_2003);
}
}
// if the conversion failed (e.g. domain to long) return the original domain
if ($unicode == false) {
return $IDNA;
} else {
return $unicode;
}
}
// Convert a given (unicode) domain to IDNA ASCII
function convertUnicodeToIDNA($unicode)
{
if (extension_loaded('intl')) {
// Be prepared that this may fail and see our comments about convertIDNAToUnicode()
if (defined('INTL_IDNA_VARIANT_UTS46')) {
$IDNA = idn_to_ascii($unicode, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
} elseif (defined('INTL_IDNA_VARIANT_2003')) {
$IDNA = idn_to_ascii($unicode, IDNA_DEFAULT, INTL_IDNA_VARIANT_2003);
}
}
// if the conversion failed (e.g. domain to long) return the original domain
if ($IDNA == false) {
return $unicode;
} else {
return $IDNA;
}
}
// Get FTL process information (used in settings.php)
function get_FTL_data($FTLpid, $arg)
{
return trim(exec('ps -p '.$FTLpid.' -o '.$arg));
}
// Convert seconds into readable time (used in settings.php)
function convertseconds($argument)
{
$seconds = round($argument);
if ($seconds < 60) {
return sprintf('%ds', $seconds);
}
if ($seconds < 3600) {
return sprintf('%dm %ds', $seconds / 60, $seconds % 60);
}
if ($seconds < 86400) {
return sprintf('%dh %dm %ds', $seconds / 3600 % 24, $seconds / 60 % 60, $seconds % 60);
}
return sprintf('%dd %dh %dm %ds', $seconds / 86400, $seconds / 3600 % 24, $seconds / 60 % 60, $seconds % 60);
}
function start_php_session()
{
// Prevent Session ID from being passed through URLs
/* ini_set('session.use_only_cookies', 1); */
/* session_start(); */
// HttpOnly: Prevents javascript XSS attacks aimed to steal the session ID
//
// SameSite=Strict: Allows servers to assert that a cookie ought not to be
// sent along with cross-site requests. This assertion allows user agents to
// mitigate the risk of cross-origin information leakage, and provides some
// protection against cross-site request forgery attacks.
// Direct support of Samesite has been added to PHP only in version 7.3
// We manually set the cookie option ourselves to ensure backwards compatibility
/* header('Set-Cookie: PHPSESSID='.session_id().'; path=/; HttpOnly; SameSite=Strict'); */
}

View File

@@ -8,12 +8,7 @@
* Please see LICENSE file for your rights under this license.
*/
require 'scripts/pi-hole/php/auth.php';
require_once 'scripts/pi-hole/php/func.php';
require 'scripts/pi-hole/php/theme.php';
check_cors();
require 'header.php';
?>
<link rel="stylesheet" href="<?php echo fileversion('style/vendor/datatables.min.css'); ?>">

View File

@@ -86,8 +86,8 @@
<a href="groups-adlists.php">
<i class="fa fa-fw menu-icon fa-shield-alt"></i> <span>Adists
<span class="pull-right-container">
<span class="label bg-blue pull-right" id="num_gravity" title="Total number of domains blocked by your Pi-hole"></span>
<span class="label bg-yellow pull-right" id="num_lists" title="Number of defined adlists"></span>
<span class="label bg-blue pull-right" id="num_lists" title="Number of defined adlists"></span>
<span class="label bg-yellow pull-right" id="num_gravity" title="Total number of domains blocked by your Pi-hole"></span>
</span>
</a>
</li>

View File

@@ -582,7 +582,6 @@ td.details-control {
.login-options div:last-child {
margin-right: 2px;
margin-bottom: 0 !important;
flex: 0 1 auto;
font-size: 95%;
}