Merge branch 'master' into feat/plugin-manager

This commit is contained in:
Bill Zimmerman
2025-01-26 10:33:49 +01:00
committed by GitHub
47 changed files with 335 additions and 75 deletions

View File

@@ -1,16 +1,10 @@
<?php
if (RASPI_AUTH_ENABLED) {
$user = $_SERVER['PHP_AUTH_USER'] ?? '';
$pass = $_SERVER['PHP_AUTH_PW'] ?? '';
$auth = new \RaspAP\Auth\HTTPAuth;
if (!$auth->isLogged()) {
if ($auth->login($user, $pass)) {
$config = $auth->getAuthConfig();
} else {
$auth->authenticate();
}
$auth->authenticate();
}
}

View File

@@ -1,7 +1,6 @@
<?php
require_once 'functions.php';
require_once 'session.php';
if (csrfValidateRequest() && !CSRFValidate()) {
handleInvalidCSRFToken();

View File

@@ -6,7 +6,8 @@ if (!defined('RASPI_CONFIG')) {
$defaults = [
'RASPI_BRAND_TEXT' => 'RaspAP',
'RASPI_VERSION' => '3.2.4',
'RASPI_BRAND_TITLE' => RASPI_BRAND_TEXT.' Admin Panel',
'RASPI_VERSION' => '3.2.5',
'RASPI_CONFIG_NETWORK' => RASPI_CONFIG.'/networking/defaults.json',
'RASPI_CONFIG_PROVIDERS' => 'config/vpn-providers.json',
'RASPI_CONFIG_API' => RASPI_CONFIG.'/api',
@@ -16,6 +17,7 @@ $defaults = [
'RASPI_ERROR_LOG' => sys_get_temp_dir() . '/raspap_error.log',
'RASPI_DEBUG_LOG' => 'raspap_debug.log',
'RASPI_LOG_SIZE_LIMIT' => 64,
'RASPI_SESSION_TIMEOUT' => 1440,
// Constants for configuration file paths.
// These are typical for default RPi installs. Modify if needed.

View File

@@ -268,6 +268,9 @@ function updateDnsmasqConfig($iface,$status)
}
$config .= PHP_EOL;
}
if ($_POST['dhcp-ignore'] == "1") {
$config .= 'dhcp-ignore=tag:!known'.PHP_EOL;
}
file_put_contents("/tmp/dnsmasqdata", $config);
$msg = file_exists(RASPI_DNSMASQ_PREFIX.$iface.'.conf') ? 'updated' : 'added';
system('sudo cp /tmp/dnsmasqdata '.RASPI_DNSMASQ_PREFIX.$iface.'.conf', $result);

View File

@@ -1,4 +1,6 @@
<div class="d-flex align-items-center justify-content-between small">
<?php $_SESSION['lastActivity'] = time(); ?>
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted">
<span class="pe-2"><a href="/about">v<?php echo RASPI_VERSION; ?></a></span> |
<span class="ps-2">Created by the <a href="https://github.com/RaspAP" target="_blank" rel="noopener">RaspAP Team</a></span>
@@ -8,3 +10,19 @@
</div>
</div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="sessionTimeoutModal" tabindex="-1" aria-labelledby="sessionTimeoutLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title" id="sessionTimeoutLabel"><i class="fa fa-clock me-2"></i><?php echo _("Session Expired"); ?></div>
</div>
<div class="modal-body">
<?php echo _("Your session has expired. Please login to continue.") ?>
</div>
<div class="modal-footer">
<button type="button" id="js-session-expired-login" class="btn btn-outline btn-primary"><?php echo _("Login"); ?></button>
</div>
</div>
</div>
</div>

View File

@@ -1,3 +1,4 @@
<?php require_once 'session.php'; ?>
<?php
/* Functions for Networking */
@@ -336,23 +337,26 @@ function CSRFMetaTag()
*/
function CSRFValidate()
{
if(isset($_POST['csrf_token'])) {
$post_token = $_POST['csrf_token'];
$header_token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null;
if (empty($_SESSION['csrf_token']) || !is_string($_SESSION['csrf_token'])) {
error_log('Session expired or CSRF token is missing.');
header('Location: /login');
exit;
}
if (empty($post_token) && is_null($header_token)) {
return false;
}
$request_token = $post_token;
if (empty($post_token)) {
$request_token = $header_token;
}
if (hash_equals($_SESSION['csrf_token'], $request_token)) {
return true;
} else {
error_log('CSRF violation');
return false;
}
$post_token = $_POST['csrf_token'] ?? null;
$header_token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null;
if (empty($post_token) && is_null($header_token)) {
error_log('CSRF token missing in the request');
return false;
}
$request_token = $post_token ?: $header_token;
if (hash_equals($_SESSION['csrf_token'], $request_token)) {
return true;
} else {
error_log('CSRF token mismatch');
return false;
}
}

40
includes/login.php Executable file
View File

@@ -0,0 +1,40 @@
<?php
require_once 'includes/config.php';
require_once 'includes/functions.php';
/**
* Handler for administrative user login
*/
function DisplayLogin()
{
// initialize auth object
$auth = new \RaspAP\Auth\HTTPAuth;
$status = null;
$redirectUrl = null;
// handle page action
if (RASPI_AUTH_ENABLED) {
if (isset($_POST['login-auth'])) {
// authenticate user
$username = $_POST['username'];
$password = $_POST['password'];
$redirectUrl = $_POST['redirect-url'];
if ($auth->login($username, $password)) {
$config = $auth->getAuthConfig();
header('Location: ' . $redirectUrl);
die();
} else {
$status = "Login failed";
}
}
}
echo renderTemplate(
"login", compact(
"status",
"redirectUrl"
)
);
}

View File

@@ -70,6 +70,9 @@ function handleCorePageAction(string $page, array &$extraFooterScripts): void
case "/about":
DisplayAbout();
break;
case "/login":
DisplayLogin();
break;
default:
DisplayDashboard($extraFooterScripts);
}

View File

@@ -3,3 +3,8 @@
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (!isset($_SESSION['lastActivity'])) {
$_SESSION['lastActivity'] = time();
}

View File

@@ -207,7 +207,10 @@ function SaveWireGuardConfig($status)
}
if (isset($_POST['wg_pendpoint']) && strlen(trim($_POST['wg_pendpoint']) >0 )) {
$wg_pendpoint_seg = substr($_POST['wg_pendpoint'],0,strpos($_POST['wg_pendpoint'],':'));
if (!filter_var($wg_pendpoint_seg,FILTER_VALIDATE_IP)) {
$host_port = explode(':', $wg_pendpoint_seg);
$hostname = $host_port[0];
if (!filter_var($hostname, FILTER_VALIDATE_IP) &&
!filter_var($hostname, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
$status->addMessage('Invalid value for endpoint address', 'danger');
$good_input = false;
}