inc/security.php
010bf846
 <?php
c208bd90
 /*
 This file belongs to the Webinterface of schokokeks.org Hosting
 
cf54502a
 Written 2008-2018 by schokokeks.org Hosting, namely
c208bd90
   Bernd Wurst <bernd@schokokeks.org>
   Hanno Böck <hanno@schokokeks.org>
 
 To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
 
2626dd47
 You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see
c208bd90
 http://creativecommons.org/publicdomain/zero/1.0/
 
 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.
 */
010bf846
 
33986238
 require_once('inc/error.php');
28cd1b25
 require_once('vendor/autoload.php');
33986238
 
010bf846
 
28cd1b25
 function strong_password($password, $user = array())
a78147ca
 {
2626dd47
     $passwordchecker = new ZxcvbnPhp\Zxcvbn();
     $strength = $passwordchecker->passwordStrength($password, $user);
4c7e58dd
 
2626dd47
     if ($strength['score'] < 2) {
         return "Das Passwort ist zu einfach!";
     }
a78147ca
 
2626dd47
     return true;
a78147ca
 }
 
 
2626dd47
 function filter_input_general($input)
010bf846
 {
2626dd47
     if ($input === null) {
         return null;
     }
     return htmlspecialchars(iconv('UTF-8', 'UTF-8', $input), ENT_QUOTES, 'UTF-8');
33986238
 }
 
 
2626dd47
 function verify_input_general($input)
33986238
 {
2626dd47
     if (filter_input_general($input) !== $input) {
         system_failure("Ihre Daten enthielten ungültige Zeichen!");
         logger(LOG_WARNING, 'inc/security', 'verify_input_general', 'Ungültige Daten: '.$input);
     } else {
         return $input;
     }
010bf846
 }
 
 
2626dd47
 function filter_input_username($input)
010bf846
 {
2626dd47
     $username=preg_replace("/[^[:alnum:]\_\.\+\-]/", "", $input);
     if ($username === "") {
         system_failure("Leerer Benutzername!");
     }
     return $username;
391c907d
 }
 
2626dd47
 function verify_input_username($input)
391c907d
 {
2626dd47
     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!");
     }
010bf846
 }
 
33986238
 
 
2626dd47
 function filter_input_hostname($input, $wildcard=false)
07263d42
 {
2626dd47
     // FIXME: Eine "filter"-Funktion sollte keinen system_failure verursachen sondern einfach einen bereinigten String liefern.
9086c9ad
 
2626dd47
     DEBUG('filter_input_hostname("'.$input.'", $wildcard='.$wildcard.')');
ec5ed2ed
     $input = strtolower($input);
2626dd47
     $input = rtrim($input, "\t\n\r\x00 .");
     $input = ltrim($input, "\t\n\r\x00 .");
     if (preg_replace("/[^.]_/", "", $input) != $input) {
         system_failure("Der Unterstrich ist nur als erstes Zeichen eines Hostnames erlaubt.");
     }
ec5ed2ed
     if (preg_replace("/[^[:alnum:]_*\.\-]/u", "", $input) != $input) {
2626dd47
         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;
07263d42
 }
 
2626dd47
 function verify_input_hostname($input, $wildcard=false)
3e33855c
 {
2626dd47
     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!");
     }
3e33855c
 }
 
 
2626dd47
 function verify_input_ipv4($input)
3e33855c
 {
2626dd47
     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');
     }
3e33855c
 }
 
 
2626dd47
 function verify_input_ipv6($input)
3e33855c
 {
2626dd47
     // 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");
     }
3e33855c
 }
33986238
 
2626dd47
 function verify_input_recorddata($input)
33a6604d
 {
2626dd47
     if (strstr($input, "\\") || strstr($input, '"')) {
         system_failure("Ungültige Zeichen");
     }
33a6604d
 }
33986238
 
2626dd47
 function filter_quotes($input)
0dae1273
 {
2626dd47
     return preg_replace('/["\'`]/', '', $input);
0dae1273
 }
 
33986238
 
 
2626dd47
 function filter_shell($input)
19a2c966
 {
2626dd47
     return preg_replace('/[^-[:alnum:]\_\.\+ßäöüÄÖÜ/%§=]/', '', $input);
33986238
 }
 
2626dd47
 function verify_shell($input)
33986238
 {
2626dd47
     if (filter_shell($input) != $input) {
         system_failure("Ihre Daten enthielten ungültige Zeichen!");
     }
19a2c966
 }
010bf846
 
33986238
 
690f4b9d
 function filter_ssh_key($key)
 {
2626dd47
     $keyparts = explode(" ", trim($key));
690f4b9d
 
2626dd47
     if ((count($keyparts) > 3) || (count($keyparts) < 2)) {
         system_failure("Ungültiger SSH-Key!");
     }
690f4b9d
 
2626dd47
     if (preg_match("/^[a-z0-9]+-[a-z0-9-]+$/", $keyparts[0]) === 0) {
         system_failure("Ungültiger SSH-Key!");
     }
690f4b9d
 
2626dd47
     if (base64_decode($keyparts[1], 1) == false) {
         system_failure("Ungültiger SSH-Key!");
     }
690f4b9d
 
2626dd47
     if ((count($keyparts) === 3) && (preg_match("/^[a-zA-Z0-9@.-_]+$/", $keyparts[2]) === 0)) {
         system_failure("Ungültige Zeichen im Kommentar des SSH-Keys!");
     }
690f4b9d
 
2626dd47
     if (count($keyparts) === 2) {
         return $keyparts[0]." ".$keyparts[1];
     } else {
         return $keyparts[0]." ".$keyparts[1]." ".$keyparts[2];
     }
690f4b9d
 }
 
33986238
 
2626dd47
 function check_path($input)
af8c8976
 {
2626dd47
     DEBUG("checking {$input} for valid path name");
     if ($input != filter_input_general($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;
         }
af8c8976
     }
2626dd47
     return (preg_match('/^[ A-Za-z0-9.@\/_-]*$/', $input) == 1);
af8c8976
 }
 
 
d5f2f3f4
 function in_homedir($path)
 {
2626dd47
     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;
     }
ee11b5e6
     return strncmp($_SESSION['userinfo']['homedir'], $path, strlen($_SESSION['userinfo']['homedir'])) == 0;
d5f2f3f4
 }
 
2626dd47
 function check_date($input)
92f2aa62
 {
2626dd47
     return (bool) preg_match("/[0-9]{4}-(0?[1-9]|10|11|12)-([012]?[0-9]|30|31)/", $input);
92f2aa62
 }
 
d5f2f3f4
 
2626dd47
 function check_emailaddr($input)
0d1b7607
 {
2626dd47
     return (bool) filter_var($input, FILTER_VALIDATE_EMAIL) == $input;
dd4ea394
 }
 
2626dd47
 function check_domain($input)
dd4ea394
 {
2626dd47
     return (bool) preg_match("/^[a-z0-9\.\-]+\.[a-z\-]{2,63}$/i", $input);
0d1b7607
 }