git.schokokeks.org
Repositories
Help
Report an Issue
webinterface.git
Code
Commits
Branches
Tags
Suche
Strukturansicht:
523f8e8
Branches
Tags
master
ticket
webinterface.git
inc
security.php
move crypt password hash verification to its own function
Hanno Böck
commited
523f8e8
at 2023-12-08 21:33:48
security.php
Blame
History
Raw
<?php /* This file belongs to the Webinterface of schokokeks.org Hosting Written by schokokeks.org Hosting, namely Bernd Wurst <bernd@schokokeks.org> Hanno Böck <hanno@schokokeks.org> This code is published under a 0BSD license. Nevertheless, in case you use a significant part of this code, we ask (but not require, see the license) that you keep the authors' names in place and return your changes to the public. We would be especially happy if you tell us what you're going to do with this code. */ require_once('inc/error.php'); require_once('inc/base.php'); require_once('vendor/autoload.php'); function gen_pw_hash($password) { $pwhash = crypt($password, '$6$' . random_string(6)); if (strlen($pwhash) < 13) { /* returns a string shorter than 13 chars on failure */ system_failure("Failed to calculate password hash!"); } return $pwhash; } function check_pw_hash($password, $pwhash) { $checkhash = crypt($password, $pwhash); if (strlen($checkhash) < 13) { /* returns a string shorter than 13 chars on failure */ system_failure("Invalid password hash!"); } return hash_equals($checkhash, $pwhash); } function strong_password($password, $user = []) { $pwcheck = config('pwcheck'); $result = null; if ($pwcheck) { DEBUG($pwcheck); $req = curl_init($pwcheck); curl_setopt($req, CURLOPT_RETURNTRANSFER, 1); curl_setopt($req, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($req, CURLOPT_SSL_VERIFYSTATUS, 1); curl_setopt($req, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($req, CURLOPT_TIMEOUT, 5); curl_setopt($req, CURLOPT_FOLLOWLOCATION, 0); curl_setopt($req, CURLOPT_POST, 1); curl_setopt($req, CURLOPT_POSTFIELDS, "password=" . urlencode($password)); $result = chop(curl_exec($req)); DEBUG($result); } if ($result === 'good') { return true; } elseif ($result === 'bad') { return "Unsere Überprüfung hat ergeben, dass dieses Passwort in bisher veröffentlichten Passwortlisten enthalten ist. Es wird daher nicht akzeptiert."; } // Kein Online-Check eingerichtet oder der request war nicht erfolgreich DEBUG('using Zxcvbn for password check!'); $passwordchecker = new ZxcvbnPhp\Zxcvbn(); if ($user) { $strength = $passwordchecker->passwordStrength($password, $user); } else { $strength = $passwordchecker->passwordStrength($password); } DEBUG('password strength: ' . $strength['score']); if ($strength['score'] < 2) { return "Das Passwort ist zu einfach!"; } return true; } function filter_input_general($input) { if ($input === null) { return null; } $input = (string) $input; $filtered = preg_replace('/[\x00-\x09\x0b-\x0c\x0e-\x1f]/', '', $input); if ($filtered !== $input) { system_failure("Ihre Daten enthielten ungültige Zeichen!"); logger(LOG_WARNING, 'inc/security', 'filter_input_general', 'Ungültige Daten!'); } return $filtered; } function filter_input_oneline($input) { if ($input === null) { return null; } $input = (string) $input; $filtered = preg_replace('/[\x00-\x1f]/', '', $input); if ($filtered !== $input) { system_failure("Ihre Daten enthielten ungültige Zeichen!"); logger(LOG_WARNING, 'inc/security', 'filter_input_oneline', 'Ungültige Daten!'); } return $filtered; } function filter_output_html($data) { if (!$data) { return ""; } return htmlspecialchars($data, ENT_QUOTES); } function verify_input_ascii($data) { $data = (string) $data; $filtered = filter_var($data, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH); if ($filtered != $data) { logger(LOG_WARNING, 'inc/security', 'verify_input_ascii', 'Ungültige Daten: ' . $data); system_failure("Ihre Eingabe enthielt ungültige Zeichen"); } return $filtered; } function verify_input_identifier($data) { $data = (string) $data; if ($data === "") { system_failure("Leerer Bezeichner"); } $filtered = preg_replace("/[^[:alnum:]\_\.\-]/", "", $data); if ($filtered !== $data) { logger(LOG_WARNING, 'inc/security', 'verify_input_identifier', 'Ungültige Daten: ' . $data); system_failure("Ihre Daten enthielten ungültige Zeichen!"); } return $filtered; } function filter_input_username($input) { $username = preg_replace("/[^[:alnum:]\_\.\+\-]/", "", $input); if ($username === "") { system_failure("Leerer Benutzername!"); } return $username; } function verify_input_username($input) { if (filter_input_username($input) != $input) { logger(LOG_WARNING, 'inc/security', 'verify_input_username', 'Ungültige Daten: ' . $input); system_failure("Ihre Daten enthielten ungültige Zeichen!"); } } function filter_input_hostname($input, $wildcard = false) { DEBUG('filter_input_hostname("' . $input . '", $wildcard=' . $wildcard . ')'); $input = strtolower($input); $input = trim($input, "\t\n\r\x00 ."); if (preg_replace("/[^.]_/", "", $input) != $input) { system_failure("Der Unterstrich ist nur als erstes Zeichen eines Hostnames erlaubt."); } if (preg_replace("/[^[:alnum:]_*\.\-]/u", "", $input) != $input) { system_failure("Ihre Daten enthielten ungültige Zeichen!"); } if (preg_match("/^.+\*/", $input)) { system_failure("Ihre Daten enthielten ungültige Zeichen (Wildcard-Stern muss ganz vorne stehen)!"); } if (!$wildcard && preg_replace("/^\*/", "", $input) != $input) { system_failure("Ihre Daten enthielten ungültige Zeichen (Keine Wildcards erlaubt)!"); } if (strstr($input, '..')) { system_failure("Ungültiger Hostname"); } return $input; } function verify_input_hostname($input, $wildcard = false) { if (filter_input_hostname($input, $wildcard) != $input) { logger(LOG_WARNING, 'inc/security', 'verify_input_hostname', 'Ungültige Daten: ' . $input); system_failure("Ihre Daten enthielten ungültige Zeichen!"); } } function verify_input_hostname_utf8($input) { $puny = idn_to_ascii($input, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46); if ($puny === false) { system_failure("Ungültiger Hostname! idn " . $input); } $filter = filter_var($puny, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME); if ($filter !== $puny) { system_failure("Ungültiger Hostname! filter " . $input); } } function verify_input_ipv4($input) { if (!preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $input)) { system_failure('Keine IP-Adresse'); } } function verify_input_ipv6($input) { // ripped from Perl module Net-IPv6Addr v0.2 if (!preg_match("/^(([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}|[0-9a-f]{0,4}::|:(?::[a-f0-9]{1,4}){1,6}|(?:[a-f0-9]{1,4}:){1,6}:|(?:[a-f0-9]{1,4}:)(?::[a-f0-9]{1,4}){1,6}|(?:[a-f0-9]{1,4}:){2}(?::[a-f0-9]{1,4}){1,5}|(?:[a-f0-9]{1,4}:){3}(?::[a-f0-9]{1,4}){1,4}|(?:[a-f0-9]{1,4}:){4}(?::[a-f0-9]{1,4}){1,3}|(?:[a-f0-9]{1,4}:){5}(?::[a-f0-9]{1,4}){1,2}|(?:[a-f0-9]{1,4}:){6}(?::[a-f0-9]{1,4}))$/i", $input)) { system_failure("Ungültige IPv6-Adresse"); } } function verify_input_recorddata($input) { if (strstr($input, "\\") || strstr($input, '"')) { system_failure("Ungültige Zeichen"); } } function filter_quotes($input) { return preg_replace('/["\'`]/', '', $input); } function filter_shell($input) { return preg_replace('/[^-[:alnum:]\_\.\+ßäöüÄÖÜ/%§=]/', '', $input); } function verify_shell($input) { if (filter_shell($input) != $input) { system_failure("Ihre Daten enthielten ungültige Zeichen!"); } } function filter_ssh_key($key) { $keyparts = explode(" ", trim($key)); if ((count($keyparts) > 3) || (count($keyparts) < 2)) { system_failure("Ungültiger SSH-Key!"); } if (preg_match("/^[a-z0-9]+-[a-z0-9-]+$/", $keyparts[0]) === 0) { system_failure("Ungültiger SSH-Key!"); } if (base64_decode($keyparts[1], 1) == false) { system_failure("Ungültiger SSH-Key!"); } if ((count($keyparts) === 3) && (preg_match("/^[a-zA-Z0-9@._-]+$/", $keyparts[2]) === 0)) { system_failure("Ungültige Zeichen im Kommentar des SSH-Keys!"); } if (count($keyparts) === 2) { return $keyparts[0] . " " . $keyparts[1]; } else { return $keyparts[0] . " " . $keyparts[1] . " " . $keyparts[2]; } } function check_path($input) { DEBUG("checking {$input} for valid path name"); if ($input != filter_output_html($input)) { logger(LOG_WARNING, 'inc/security', 'check_path', 'HTML-Krams im Pfad: ' . $input); DEBUG("HTML-Krams im Pfad"); return false; } $components = explode("/", $input); foreach ($components as $item) { if ($item == '..') { logger(LOG_WARNING, 'inc/security', 'check_path', '»..« im Pfad: ' . $input); DEBUG("»..« im Pfad"); return false; } if (strlen($item) > 255) { return false; } } if (strlen($input) > 2048) { return false; } return (preg_match('/^[ A-Za-z0-9.@\/_-]*$/', $input) == 1); } function in_homedir($path) { DEBUG("Prüfe »{$path}«"); if (!check_path($path)) { DEBUG('Kein Pfad'); return false; } if (!isset($_SESSION['userinfo']['homedir'])) { DEBUG("Kann homedir nicht ermitteln"); return false; } return strncmp($_SESSION['userinfo']['homedir'], $path, strlen($_SESSION['userinfo']['homedir'])) == 0; } function check_date($input) { return (bool) preg_match("/[0-9]{4}-(0?[1-9]|10|11|12)-([012]?[0-9]|30|31)/", $input); } function check_emailaddr($input) { return (bool) filter_var($input, FILTER_VALIDATE_EMAIL) == $input; } function check_domain($input) { return (bool) preg_match("/^[a-z0-9\.\-]+\.[a-z\-]{2,63}$/i", $input); } function check_input_types($input, $types) { foreach ($types as $key => $type) { if (!array_key_exists($key, $input)) { system_failure("Interner Fehler bei Eingabevariablen"); } if ($type === 'int') { if ($input[$key] !== (string)(int)$input[$key]) { system_failure("Interner Fehler bei Eingabevariablen"); } continue; } elseif ($type === 'string') { if (!is_string($input[$key])) { system_failure("Interner Fehler bei Eingabevariablen"); } } else { system_failure("Interner Fehler: Ungültier Typ"); } } }