Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions simpleAPI/config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// MQTT Broker Konfiguration
'mqtt' => [
'server' => 'localhost',
'port' => 1884,
'port' => 8883,
Comment thread
kevinwieland marked this conversation as resolved.
'validate_cert' => false,
'username' => '',
'password' => '',
Expand All @@ -19,7 +19,7 @@

// Authentifizierung
'auth' => [
'enabled' => false,
'enabled' => true,
'require_https' => false,

// Gültige Tokens
Expand Down
28 changes: 24 additions & 4 deletions simpleAPI/simpleapi.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public function __construct()
// Parameter Handler initialisieren
$this->parameterHandler = new ParameterHandler($this->mqttClient);

// Authenticator initialisieren
$this->authenticator = new Authenticator($this->config);
// Authenticator initialisieren (mit MqttClient für Anmeldedaten-Test)
$this->authenticator = new Authenticator($this->config, $this->mqttClient);
}

/**
Expand Down Expand Up @@ -61,6 +61,7 @@ public function handleRequest()
$params = array_merge($_GET, $_POST);

// Debug-Modus
$debugInfo = [];
if (isset($params['debug']) && $params['debug'] === 'true') {
$this->config['debug'] = true;
}
Expand All @@ -75,6 +76,20 @@ public function handleRequest()
return;
}

// MQTT-Anmeldedaten aus Parametern übernehmen falls vorhanden
if (isset($params['username']) && isset($params['password'])) {
$this->mqttClient->setCredentials($params['username'], $params['password']);

if ($this->config['debug']) {
$debugInfo[] = "Using MQTT credentials from parameters: username={$params['username']}";
}
} else {
// Keine Parameter-Anmeldedaten vorhanden
if ($this->config['debug']) {
$debugInfo[] = "No credentials provided via parameters, using config or anonymous access";
Comment on lines +79 to +89
}
}

// Schreibvorgänge prüfen
$writeParams = $this->getWriteParameters($params);
if (!empty($writeParams)) {
Expand All @@ -96,7 +111,7 @@ public function handleRequest()
// Lesevorgänge verarbeiten
$readParams = $this->getReadParameters($params);
if (!empty($readParams)) {
$result = $this->handleReadRequest($readParams, $params);
$result = $this->handleReadRequest($readParams, $params, $debugInfo);

// Raw-Ausgabe Validierung
if (isset($params['raw']) && $params['raw'] === 'true') {
Expand Down Expand Up @@ -345,9 +360,14 @@ private function handleWriteRequest($writeParams, $allParams)
/**
* Leseanfrage verarbeiten
*/
private function handleReadRequest($readParams, $allParams)
private function handleReadRequest($readParams, $allParams, $debugInfo = [])
{
$result = [];

// Debug-Informationen hinzufügen wenn vorhanden
if (!empty($debugInfo) && $this->config['debug']) {
$result['debug_info'] = $debugInfo;
}
Comment on lines +367 to +370

foreach ($readParams as $param => $id) {
try {
Expand Down
52 changes: 40 additions & 12 deletions simpleAPI/src/Authenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
class Authenticator
{
private $config;
private $mqttClient;

public function __construct($config)
public function __construct($config, $mqttClient = null)
{
$this->config = $config;
$this->mqttClient = $mqttClient;
}

/**
Expand Down Expand Up @@ -39,6 +41,11 @@ public function authenticate($params)
return true;
}

// Fallback: Prüfen ob MQTT Broker ohne Authentifizierung zugänglich ist
if ($this->checkMqttNoAuth()) {
return true;
}

Comment on lines +44 to +48
return false;
}

Expand Down Expand Up @@ -130,20 +137,27 @@ private function validateCredentials($username, $password)
{
$users = $this->config['auth']['users'] ?? [];

if (!isset($users[$username])) {
return false;
// Zuerst gegen definierte Benutzer prüfen
if (!empty($users) && isset($users[$username])) {
$storedPassword = $users[$username];

// Passwort-Hash prüfen
if (strpos($storedPassword, '$') === 0) {
// Gehashtes Passwort
return password_verify($password, $storedPassword);
} else {
// Klartext (nicht empfohlen)
return hash_equals($storedPassword, $password);
}
}

$storedPassword = $users[$username];

// Passwort-Hash prüfen
if (strpos($storedPassword, '$') === 0) {
// Gehashtes Passwort
return password_verify($password, $storedPassword);
} else {
// Klartext (nicht empfohlen)
return hash_equals($storedPassword, $password);
// Wenn keine lokalen Benutzer definiert sind oder MqttClient verfügbar ist:
// Anmeldedaten gegen MQTT Broker testen
if ($this->mqttClient && (empty($users) || !isset($users[$username]))) {
Comment on lines +154 to +156
return $this->mqttClient->testCredentials($username, $password);
}

return false;
}

/**
Expand Down Expand Up @@ -181,4 +195,18 @@ private function isHttps()
$_SERVER['SERVER_PORT'] == 443 ||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https');
}

/**
* Prüfen ob MQTT Broker ohne Authentifizierung zugänglich ist
*/
private function checkMqttNoAuth()
{
// Nur wenn MqttClient verfügbar ist
if (!$this->mqttClient) {
return false;
}

// Test-Verbindung ohne Anmeldedaten
return $this->mqttClient->testCredentials('', '');
}
}
50 changes: 46 additions & 4 deletions simpleAPI/src/MqttClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ public function __construct($config)
$this->clientid = $config['mqtt']['clientid'] ?? 'SimpleAPI_' . uniqid();
}

/**
* MQTT-Anmeldedaten aktualisieren
*/
public function setCredentials($username, $password)
{
$this->username = $username;
$this->password = $password;
}

/**
* Verbindung testen
*/
Expand All @@ -41,6 +50,28 @@ public function connect()
return !preg_match('/error|failed|unable/i', $result ?? '');
}

/**
* Anmeldedaten am MQTT Broker testen
*/
public function testCredentials($username, $password)
{
// Test-Verbindung mit mosquitto_sub (sehr kurzes Timeout)
$cmd = $this->buildMosquittoCommandWithCredentials('sub', '$SYS/broker/uptime', '', 1, 2, $username, $password);
$result = shell_exec($cmd . ' 2>&1');

// Prüfen auf Authentifizierungsfehler
if (preg_match('/not authorised|connection refused|authentication failed|username or password invalid/i', $result ?? '')) {
return false;
}

// Prüfen auf andere schwerwiegende Fehler
if (preg_match('/connection error|network unreachable|no such host/i', $result ?? '')) {
return false;
}

return true;
}

/**
* Wert aus MQTT Topic lesen
*/
Expand Down Expand Up @@ -107,6 +138,14 @@ public function setValue($topic, $value)
* Mosquitto-Kommando erstellen
*/
private function buildMosquittoCommand($type, $topics, $message = '', $count = null, $timeout = 1, $extraArgs = [])
{
return $this->buildMosquittoCommandWithCredentials($type, $topics, $message, $count, $timeout, $this->username, $this->password, $extraArgs);
}

/**
* Mosquitto-Kommando mit spezifischen Anmeldedaten erstellen
*/
private function buildMosquittoCommandWithCredentials($type, $topics, $message = '', $count = null, $timeout = 1, $username = null, $password = null, $extraArgs = [])
{
$binary = $type === 'sub' ? 'mosquitto_sub' : 'mosquitto_pub';

Expand All @@ -123,11 +162,14 @@ private function buildMosquittoCommand($type, $topics, $message = '', $count = n
}

// Username/Passwort hinzufügen falls konfiguriert
if (!empty($this->username)) {
$cmd .= sprintf(" -u %s", escapeshellarg($this->username));
$useUsername = $username !== null ? $username : $this->username;
$usePassword = $password !== null ? $password : $this->password;

if (!empty($useUsername)) {
$cmd .= sprintf(" -u %s", escapeshellarg($useUsername));
}
if (!empty($this->password)) {
$cmd .= sprintf(" -P %s", escapeshellarg($this->password));
if (!empty($usePassword)) {
$cmd .= sprintf(" -P %s", escapeshellarg($usePassword));
}

// Topic(s) hinzufügen
Expand Down
Loading