Zeilenenden vereinheitlichen: LF ueberall ausser im Fremdcode
Bisher entschied jede Arbeitsstation fuer sich, welche Zeilenenden ein Commit bekommt: Git fuer Windows setzt core.autocrlf=input in seiner System-Konfiguration, die NAS setzt nichts. Weil der Bestand ausserdem in sich gemischt war - 34 PHP-Dateien mit LF, 30 mit CRLF -, gab es gar kein richtiges Zeilenende, an das ein Werkzeug sich haette halten koennen. Jede Ergaenzung mit LF in einer CRLF-Datei ergab eine gemischte Datei; helper.php und js/solar/homeMQTT.js waren bereits so entstanden. .gitattributes macht die Zeilenenden zur Eigenschaft des Repositorys. LF, weil dieses Verzeichnis der Web-Ordner der NAS ist und von Linux ausgeliefert wird - und weil Git fuer Windows mit "input" ohnehin schon dorthin zeigt. restricted/WebAuthn bleibt ausgenommen und damit byteweise so, wie die Bibliothek geliefert wurde; darunter liegen 292 Zertifikate. Von den 47 geaenderten Dateien wurde nachgerechnet keine einzige im Inhalt angefasst - der Vergleich HEAD-ohne-CR gegen Index ist ueberall gleich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+132
-132
@@ -1,96 +1,96 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once("restricted/mysql.php");
|
||||
$_SESSION["local"] =false;
|
||||
|
||||
// Netze, die als lokal gelten und damit ohne Anmeldung Zugriff bekommen.
|
||||
// Bewusst eine sichtbare Liste statt eines Zeichenkettenvergleichs.
|
||||
const LOCAL_NETWORKS = ["192.168.179.0/24"];
|
||||
|
||||
/**
|
||||
* Liegt $ip im Netz $cidr? Verglichen wird binaer (inet_pton), also
|
||||
* unabhaengig von der Schreibweise: "2001:db8::" und "2001:0db8:0000::"
|
||||
* sind dieselbe Adresse.
|
||||
*/
|
||||
function ipInNetwork($ip, $cidr)
|
||||
{
|
||||
$teile = explode("/", $cidr, 2);
|
||||
$adresse = @inet_pton($ip);
|
||||
$netz = @inet_pton($teile[0]);
|
||||
if ($adresse === false || $netz === false || strlen($adresse) !== strlen($netz)) {
|
||||
return false; // ungueltig oder verschiedene Adressfamilien
|
||||
}
|
||||
// Praefixlaenge streng pruefen. Ohne das macht ein Tippfehler in
|
||||
// LOCAL_NETWORKS die Funktion fail-open: "/-5" etwa liefert eine
|
||||
// Nullmaske, und dann liegt jede Adresse in jedem Netz.
|
||||
if (isset($teile[1])) {
|
||||
if (!ctype_digit($teile[1])) {
|
||||
return false;
|
||||
}
|
||||
$bits = intval($teile[1]);
|
||||
if ($bits > strlen($adresse) * 8) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$bits = strlen($adresse) * 8;
|
||||
}
|
||||
$ganzeBytes = intdiv($bits, 8);
|
||||
$restBits = $bits % 8;
|
||||
if ($ganzeBytes > 0 && strncmp($adresse, $netz, $ganzeBytes) !== 0) {
|
||||
return false;
|
||||
}
|
||||
if ($restBits === 0) {
|
||||
return true;
|
||||
}
|
||||
$maske = chr((0xFF << (8 - $restBits)) & 0xFF);
|
||||
return ($adresse[$ganzeBytes] & $maske) === ($netz[$ganzeBytes] & $maske);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kommt die Anfrage aus dem Heimnetz? Nur dann gilt sie ohne Anmeldung als
|
||||
* berechtigt.
|
||||
*
|
||||
* REMOTE_ADDR stammt aus der TCP-Verbindung und ist nicht faelschbar.
|
||||
* Weiterleitungs-Header wie X-Forwarded-For duerfen hier bewusst NICHT
|
||||
* herangezogen werden - sie kann jeder Aufrufer frei setzen.
|
||||
*/
|
||||
function isLocal()
|
||||
{
|
||||
$_SESSION["local"] = false;
|
||||
$remote = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
|
||||
$server = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '';
|
||||
|
||||
if (filter_var($remote, FILTER_VALIDATE_IP) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Auf IPv6 abgebildete IPv4-Adressen (::ffff:192.168.179.44) auf ihre
|
||||
// IPv4-Form zurueckfuehren. Ein Server mit Dual-Stack-Socket meldet
|
||||
// LAN-Clients so - ohne diesen Schritt faellt das Heimnetz durch.
|
||||
if (preg_match('/^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/i', $remote, $treffer)) {
|
||||
$remote = $treffer[1];
|
||||
}
|
||||
|
||||
$lokal = false;
|
||||
foreach (LOCAL_NETWORKS as $netz) {
|
||||
if (ipInNetwork($remote, $netz)) {
|
||||
$lokal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Gleiches IPv6-/64 wie der Server. Das Praefix vergibt der Provider und
|
||||
// es kann sich aendern, deshalb aus SERVER_ADDR abgeleitet statt fest.
|
||||
if (!$lokal
|
||||
&& filter_var($remote, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false
|
||||
&& filter_var($server, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
|
||||
$lokal = substr(inet_pton($remote), 0, 8) === substr(inet_pton($server), 0, 8);
|
||||
}
|
||||
|
||||
$_SESSION["local"] = $lokal;
|
||||
return $lokal;
|
||||
}
|
||||
|
||||
<?php
|
||||
session_start();
|
||||
require_once("restricted/mysql.php");
|
||||
$_SESSION["local"] =false;
|
||||
|
||||
// Netze, die als lokal gelten und damit ohne Anmeldung Zugriff bekommen.
|
||||
// Bewusst eine sichtbare Liste statt eines Zeichenkettenvergleichs.
|
||||
const LOCAL_NETWORKS = ["192.168.179.0/24"];
|
||||
|
||||
/**
|
||||
* Liegt $ip im Netz $cidr? Verglichen wird binaer (inet_pton), also
|
||||
* unabhaengig von der Schreibweise: "2001:db8::" und "2001:0db8:0000::"
|
||||
* sind dieselbe Adresse.
|
||||
*/
|
||||
function ipInNetwork($ip, $cidr)
|
||||
{
|
||||
$teile = explode("/", $cidr, 2);
|
||||
$adresse = @inet_pton($ip);
|
||||
$netz = @inet_pton($teile[0]);
|
||||
if ($adresse === false || $netz === false || strlen($adresse) !== strlen($netz)) {
|
||||
return false; // ungueltig oder verschiedene Adressfamilien
|
||||
}
|
||||
// Praefixlaenge streng pruefen. Ohne das macht ein Tippfehler in
|
||||
// LOCAL_NETWORKS die Funktion fail-open: "/-5" etwa liefert eine
|
||||
// Nullmaske, und dann liegt jede Adresse in jedem Netz.
|
||||
if (isset($teile[1])) {
|
||||
if (!ctype_digit($teile[1])) {
|
||||
return false;
|
||||
}
|
||||
$bits = intval($teile[1]);
|
||||
if ($bits > strlen($adresse) * 8) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$bits = strlen($adresse) * 8;
|
||||
}
|
||||
$ganzeBytes = intdiv($bits, 8);
|
||||
$restBits = $bits % 8;
|
||||
if ($ganzeBytes > 0 && strncmp($adresse, $netz, $ganzeBytes) !== 0) {
|
||||
return false;
|
||||
}
|
||||
if ($restBits === 0) {
|
||||
return true;
|
||||
}
|
||||
$maske = chr((0xFF << (8 - $restBits)) & 0xFF);
|
||||
return ($adresse[$ganzeBytes] & $maske) === ($netz[$ganzeBytes] & $maske);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kommt die Anfrage aus dem Heimnetz? Nur dann gilt sie ohne Anmeldung als
|
||||
* berechtigt.
|
||||
*
|
||||
* REMOTE_ADDR stammt aus der TCP-Verbindung und ist nicht faelschbar.
|
||||
* Weiterleitungs-Header wie X-Forwarded-For duerfen hier bewusst NICHT
|
||||
* herangezogen werden - sie kann jeder Aufrufer frei setzen.
|
||||
*/
|
||||
function isLocal()
|
||||
{
|
||||
$_SESSION["local"] = false;
|
||||
$remote = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
|
||||
$server = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '';
|
||||
|
||||
if (filter_var($remote, FILTER_VALIDATE_IP) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Auf IPv6 abgebildete IPv4-Adressen (::ffff:192.168.179.44) auf ihre
|
||||
// IPv4-Form zurueckfuehren. Ein Server mit Dual-Stack-Socket meldet
|
||||
// LAN-Clients so - ohne diesen Schritt faellt das Heimnetz durch.
|
||||
if (preg_match('/^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/i', $remote, $treffer)) {
|
||||
$remote = $treffer[1];
|
||||
}
|
||||
|
||||
$lokal = false;
|
||||
foreach (LOCAL_NETWORKS as $netz) {
|
||||
if (ipInNetwork($remote, $netz)) {
|
||||
$lokal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Gleiches IPv6-/64 wie der Server. Das Praefix vergibt der Provider und
|
||||
// es kann sich aendern, deshalb aus SERVER_ADDR abgeleitet statt fest.
|
||||
if (!$lokal
|
||||
&& filter_var($remote, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false
|
||||
&& filter_var($server, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
|
||||
$lokal = substr(inet_pton($remote), 0, 8) === substr(inet_pton($server), 0, 8);
|
||||
}
|
||||
|
||||
$_SESSION["local"] = $lokal;
|
||||
return $lokal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kleine HTTP-GET-Anfrage im Heimnetz, Antwort als JSON-Array.
|
||||
* Ersetzt die frueher in carOG.php, heater.php und AutoAction.php je einzeln
|
||||
@@ -106,43 +106,43 @@ function httpGetJson($url){
|
||||
return json_decode($response, true);
|
||||
}
|
||||
|
||||
function checkLogin(){
|
||||
$mysql = new mysqli($GLOBALS["mysql_server"],$GLOBALS["mysql_user"],$GLOBALS["mysql_pass"],$GLOBALS["mysql_db"]);
|
||||
if(isLocal()){
|
||||
$_SESSION["local"] =true;
|
||||
return true;
|
||||
}
|
||||
if(isset($_SESSION["authKey"])){
|
||||
$res = mysqli_query($mysql,"SELECT id FROM users WHERE lastAuth > DATE_SUB(NOW(), INTERVAL 2 DAY) AND authKey = '".mysqli_real_escape_string($mysql,$_SESSION["authKey"])."' AND name = '".mysqli_real_escape_string($mysql,$_SESSION["user"])."';");
|
||||
if(!$res){
|
||||
echo mysqli_error($mysql);
|
||||
return false;
|
||||
}
|
||||
if(mysqli_num_rows($res) == 1){
|
||||
return isset($_SESSION["Logged"]);
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function checkAdduser(){
|
||||
$mysql = new mysqli($GLOBALS["mysql_server"],$GLOBALS["mysql_user"],$GLOBALS["mysql_pass"],$GLOBALS["mysql_db"]);
|
||||
if(!mysqli_query($mysql,"DELETE FROM addUser WHERE datetime < DATE_SUB(NOW(), INTERVAL 1 MINUTE);")){
|
||||
echo mysqli_error($mysql);
|
||||
}
|
||||
$result = mysqli_query($mysql,"SELECT * FROM addUser WHERE accesskey='".mysqli_real_escape_string($mysql,$_GET["addUser"])."';");
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
if ($result->num_rows > 0) {
|
||||
// Freigabe fuer die Passkey-Registrierung vermerken. authServer.php
|
||||
// prueft dieses Merkmal; ohne das waeren getCreateArgs/processCreate
|
||||
// direkt aufrufbar und der Einmalschluessel wirkungslos.
|
||||
$_SESSION["mayRegister"] = time();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkLogin(){
|
||||
$mysql = new mysqli($GLOBALS["mysql_server"],$GLOBALS["mysql_user"],$GLOBALS["mysql_pass"],$GLOBALS["mysql_db"]);
|
||||
if(isLocal()){
|
||||
$_SESSION["local"] =true;
|
||||
return true;
|
||||
}
|
||||
if(isset($_SESSION["authKey"])){
|
||||
$res = mysqli_query($mysql,"SELECT id FROM users WHERE lastAuth > DATE_SUB(NOW(), INTERVAL 2 DAY) AND authKey = '".mysqli_real_escape_string($mysql,$_SESSION["authKey"])."' AND name = '".mysqli_real_escape_string($mysql,$_SESSION["user"])."';");
|
||||
if(!$res){
|
||||
echo mysqli_error($mysql);
|
||||
return false;
|
||||
}
|
||||
if(mysqli_num_rows($res) == 1){
|
||||
return isset($_SESSION["Logged"]);
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function checkAdduser(){
|
||||
$mysql = new mysqli($GLOBALS["mysql_server"],$GLOBALS["mysql_user"],$GLOBALS["mysql_pass"],$GLOBALS["mysql_db"]);
|
||||
if(!mysqli_query($mysql,"DELETE FROM addUser WHERE datetime < DATE_SUB(NOW(), INTERVAL 1 MINUTE);")){
|
||||
echo mysqli_error($mysql);
|
||||
}
|
||||
$result = mysqli_query($mysql,"SELECT * FROM addUser WHERE accesskey='".mysqli_real_escape_string($mysql,$_GET["addUser"])."';");
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
if ($result->num_rows > 0) {
|
||||
// Freigabe fuer die Passkey-Registrierung vermerken. authServer.php
|
||||
// prueft dieses Merkmal; ohne das waeren getCreateArgs/processCreate
|
||||
// direkt aufrufbar und der Einmalschluessel wirkungslos.
|
||||
$_SESSION["mayRegister"] = time();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user