* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) */ class Panel { function beforeRoute($f3) { /* check for existing session */ if ($f3->exists('SESSION.expiration')) { if ($f3->get('SESSION.expiration') > time()) { $f3->set('SESSION.expiration', time() + $f3->get('TIMEOUT')); if ($f3->get('PATH') == '/Login') { $f3->reroute('/'); } } else { $f3->clear('SESSION.expiration'); $messages[] = "Login has expired. Please re-enter login info."; $f3->set('SESSION.messages', $messages); if ($f3->get('PATH') != '/Login') { $f3->reroute('/Login'); } } } else { if ($f3->get('PATH') != '/Login') { $f3->reroute('/Login'); } } /* build subnav */ $nav_home = preg_replace('/^\//', '', $f3->get('BASE')); $nav_path = $f3->get('PATH'); if ($nav_path != '/') { $nav_parts = explode('/', $nav_path); $nav_parts[0] = $nav_home; $subnav = array(); $subnav_path = ''; foreach ($nav_parts as $k=>$v) { $subnav_part = $v; $subnav_path .= "/$subnav_part"; $subnav_name = str_replace('_', ' ', $v); $subnav[$subnav_path] = $subnav_name; } array_shift($subnav); $f3->set('NAV.subnav', $subnav); $f3->set('NAV.subnav_count', count($subnav)); } $f3->set('NAV.fullpath', preg_replace('/\/$/', '', $f3->get('REALM'))); } public static function get($f3) { /* If DNS admin is not enabled we need to display the server IP to be used for DNS settings */ if ($f3->get('VDNSADMIN') != '1') { $f3->set('default_ip', $f3->get('SERVER.SERVER_ADDR')); } echo \Template::instance()->render('home.html'); } public static function validateEmail($email) { global $f3; if (preg_match("/^[0-9A-z]([-_.+]?[0-9A-z])*@[0-9A-z]([-.]?[0-9A-z])*\.[A-z]{2,24}$/", $email)) { return true; } else { $messages[] = "$email is not a validly formatted email address."; if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } } public static function validateDomain ($domain) { global $f3; if (preg_match('/^[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,24}$/i', $domain)) { return true; } else { $messages[] = "$domain is not a validly formatted domain name."; if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } } public static function validatePassword($password, $password_confirm) { global $f3; $messages = array(); if($password != $password_confirm) { $messages[] = "Passwords do not match."; } if(strlen($password) < 8) { $messages[] = "Password must be at least 8 characters long."; } if(strlen($password) < 15) { $character_class = 0; if (preg_match('/[[:lower:]]/', $password)) { $character_class++; } if (preg_match('/[[:upper:]]/', $password)) { $character_class++; } if (preg_match('/[[:digit:]]/', $password)) { $character_class++; } if (preg_match('/[[:punct:]]/', $password)) { $character_class++; } if ($character_class < 3) { $messages[] = "Passwords under 15 characters must contain characters from at least three of the following four groups: Lower Case Letters, Upper Case Leters, Numbers, Puncuation/Special Characters. Passwords 15 or more characters long do not have any complexity requirements."; } } if (preg_match('/^[[:punct:]]/', $password)) { $messages[] = "Password may not begin with Puncuation/Special Characters."; } if (!preg_match('/^[[:lower:][:upper:][:digit:][:punct:]]{8,}$/', $password)) { $messages[] = "Password may only contain characters from these four groups: Lower Case Letters, Upper Case Letters, Numbers, Puncuation/Special Characters."; } if (count($messages) > 0) { if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } else { return true; } } public static function validateEmailLocalpart($localpart) { global $f3; $messages = array(); if(strlen($localpart) > 64) { $messages[] = "Email account names (local-part) can not be longer than 64 characters."; } if (!preg_match('/^[[:lower:][:upper:][:digit:]\.\_\-]{1,64}$/', $localpart)) { $messages[] = "Email account names (local-part) can only contain letters, numbers, and the special characters . _ -"; } if (preg_match('/^[\.\_\-]/', $localpart)) { $messages[] = "Email account names (local-part) may not begin with a Special Character."; } if (preg_match('/[\.\_\-]$/', $localpart)) { $messages[] = "Email account names (local-part) may not end with a Special Character."; } if (preg_match('/[\.\_\-]{2,}/', $localpart)) { $messages[] = "Email account names (local-part) may not have consecutive Special Characters."; } if (count($messages) > 0) { if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } else { return true; } } public static function validateEmailStatus($status) { global $f3; $messages = array(); if (is_int($status)) { if ($status == 0 || $status == 1 || $status == 2) { return true; } } $messages[] = "Invalid Status setting."; if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } public static function validateEmailQuota($quota) { global $f3; $messages = array(); if ($quota == "NULL" || (is_int($quota) && $quota > 0)) { return true; } $messages[] = "Invalid Quota ($quota)."; if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } public static function validateEmailFiltering($filtering) { global $f3; $messages = array(); if ($filtering == 0 || $filtering == 1 || $filtering == 2) { return true; } $messages[] = "Invalid Filtering setting."; if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } public static function validateEmailRatelimit($ratelimit) { global $f3; $messages = array(); if ($ratelimit == "NULL" || $ratelimit > 0) { return true; } $messages[] = "Invalid Rate Limit ($ratelimit)."; if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } public static function validateUsername($username) { global $f3; $messages = array(); if(strlen($username) < 3) { $messages[] = "Usernames must be at least 3 characters long."; } if(strlen($username) > 16) { $messages[] = "Usernames can not be longer than 16 characters."; } if (!preg_match('/^[[:lower:][:digit:]\.\_\-]{3,16}$/', $username)) { $messages[] = "Usernames can only contain letters, numbers, and the special characters . _ -"; } if (preg_match('/^[[:digit:]\.\_\-]/', $username)) { $messages[] = "Usernames must begin with an alphabetic character."; } if (preg_match('/[\.\_\-]$/', $username)) { $messages[] = "Usernames may not end with a Special Character."; } if (preg_match('/[\.\_\-]{2,}/', $username)) { $messages[] = "Usernames may not have consecutive Special Characters."; } if (count($messages) > 0) { if ($f3->exists('SESSION.messages')) { $f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages)); } else { $f3->set('SESSION.messages', $messages); } return false; } else { return true; } } public static function verifyVhostDomainExists($domain) { global $f3; exec("/usr/local/bin/vhost-get.sh -d $domain -c", $output, $result_code); if ($result_code == 0) { return TRUE; } else { if (count($output) > 0) { if ($output[0] != "ERROR: $domain not found") { $f3->set('SESSION.messages', $output[0]); } } return FALSE; } } public static function verifyCertificateExists($domain) { global $f3; exec("/usr/local/bin/letsencrypt-get.sh -d $domain -c", $output, $result_code); if ($result_code == 0) { return TRUE; } else { if (count($output) > 0) { if ($output[0] != "ERROR: Certificate for $domain not found") { $f3->set('SESSION.messages', $output[0]); } } return FALSE; } } public static function verifyVmailDomainExists($domain) { global $f3; exec("/usr/local/bin/vmail-domains-get.sh -d $domain -c", $output, $result_code); if ($result_code == 0) { if (count($output) == 0) { return FALSE; } else { // add check for domain row??? return TRUE; } } else { $f3->set('SESSION.messages', "System error checking if email domain exists."); return FALSE; } } public static function verifyDkimExists($domain) { global $f3; exec("/usr/local/bin/vmail-dkim-get.sh -d $domain -c", $output, $result_code); if ($result_code == 0) { return TRUE; } else { if (count($output) > 0) { if ($output[0] != "ERROR: DKIM for $domain does not exist.") { if (count($output) > 0) { $f3->set('SESSION.messages', $output[0]); } } } return FALSE; } } public static function vGet($cmd, $return404 = TRUE) { global $f3; /* execute command */ exec("/usr/local/bin/$cmd", $output, $result_code); /* check for sucessful response */ if ($result_code == 0) { /* intialize array to return */ $tmp_array = array(); /* check for empty result (no data / not found) */ if (count($output) == 0 && $return404) { /* return 404 unless this is disabled by calling function */ $f3->error(404); } elseif (count($output) > 0) { /* format array, first line contains headers / field names */ $headers = str_getcsv($output[0]); /* remove header row from array */ array_shift($output); /* cycle through each response line and convert cvs into array row */ foreach ($output as $k=>$v) { $cvs_array = str_getcsv($v); $tmp_array[$k] = array(); foreach ($cvs_array as $cvsk=>$cvsv) { $tmp_array[$k][$headers[$cvsk]] = $cvsv; } } } else { /* empty response */ return false; } return $tmp_array; } else { /* command resulted in error, check for & set error messages and send 500 response */ if (count($output) > 0) { foreach ($output as $k=>$output_message) { $messages[] = "$output_message"; } } else { $messages[] = "Unknown error."; } $f3->set('SESSION.messages', $messages); $f3->error(500); } } }