SSL-Verifizierung als Opt-in: pro Site (UniFi) und für SMTP

- UniFiController: CURLOPT_SSL_VERIFYPEER/-HOST über neues Site-Feld
  ssl_verify steuerbar (Default aus, da UniFi meist self-signed);
  testConnection() und alle Aufrufer angepasst
- sites: Checkbox in Anlegen/Bearbeiten-Modal, Spalte via Migration 0003
  (Alt-Installationen tolerant über '?? 0')
- Mailer: stream_context verify_peer/verify_peer_name über neues Setting
  smtp_verify_ssl (Checkbox im SMTP-Tab)
- Sprach-Keys de/en ergänzt

https://claude.ai/code/session_01KKVpVPJjrTKGoRgpJcySD4
This commit is contained in:
Claude 2026-06-09 19:46:19 +00:00
parent 6e19958a37
commit 968afbb212
No known key found for this signature in database
12 changed files with 68 additions and 26 deletions

View file

@ -7,6 +7,7 @@ class Mailer {
private $smtpUsername;
private $smtpPassword;
private $smtpEncryption;
private $smtpVerifySsl;
private $fromEmail;
private $fromName;
@ -22,6 +23,7 @@ class Mailer {
$this->smtpUsername = $this->db->getSetting('smtp_username', '');
$this->smtpPassword = $this->db->getSetting('smtp_password', '');
$this->smtpEncryption = $this->db->getSetting('smtp_encryption', 'tls');
$this->smtpVerifySsl = $this->db->getSetting('smtp_verify_ssl', '0') === '1';
$this->fromEmail = $this->db->getSetting('smtp_from_email', 'noreply@' . ($_SERVER['HTTP_HOST'] ?? 'localhost'));
$this->fromName = $this->db->getSetting('smtp_from_name', $this->db->getSetting('app_title', 'UniFi Voucher System'));
}
@ -122,11 +124,12 @@ class Mailer {
}
private function connectToSmtp() {
// Zertifikatspruefung optional aktivierbar (Setting smtp_verify_ssl)
$context = stream_context_create([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
'verify_peer' => $this->smtpVerifySsl,
'verify_peer_name' => $this->smtpVerifySsl,
'allow_self_signed' => !$this->smtpVerifySsl
]
]);

View file

@ -10,12 +10,15 @@ class UniFiController {
private $csrfToken = null;
private $sessionCookie = null;
private $loggedIn = false;
/** SSL-Zertifikat pruefen? Default aus, da UnifFi-Controller meist self-signed sind. */
private $sslVerify = false;
public function __construct($controllerUrl, $username, $password, $siteId) {
public function __construct($controllerUrl, $username, $password, $siteId, $sslVerify = false) {
$this->controllerUrl = rtrim($controllerUrl, '/');
$this->username = $username;
$this->password = $password;
$this->siteId = $siteId;
$this->sslVerify = (bool)$sslVerify;
$this->cookieFile = tempnam(sys_get_temp_dir(), 'UNIFI_');
}
@ -41,7 +44,8 @@ class UniFiController {
'password' => $this->password
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYPEER => $this->sslVerify,
CURLOPT_SSL_VERIFYHOST => $this->sslVerify ? 2 : 0,
CURLOPT_COOKIEJAR => $this->cookieFile,
CURLOPT_COOKIEFILE => $this->cookieFile,
CURLOPT_TIMEOUT => 10,
@ -116,7 +120,8 @@ class UniFiController {
$options = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYPEER => $this->sslVerify,
CURLOPT_SSL_VERIFYHOST => $this->sslVerify ? 2 : 0,
CURLOPT_TIMEOUT => 10,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_HTTPHEADER => $headers
@ -325,9 +330,9 @@ class UniFiController {
}
// Verbindung testen
public static function testConnection($controllerUrl, $username, $password, $siteId) {
public static function testConnection($controllerUrl, $username, $password, $siteId, $sslVerify = false) {
try {
$controller = new self($controllerUrl, $username, $password, $siteId);
$controller = new self($controllerUrl, $username, $password, $siteId, $sslVerify);
$controller->login();
return true;
} catch (Exception $e) {