diff --git a/install.sh b/install.sh
index a19c44e..1f9028b 100755
--- a/install.sh
+++ b/install.sh
@@ -14,3 +14,4 @@ rm -r /srv/www/html/panel/f3/.git
find /srv/www/html/panel -type d -exec chmod 755 {} +
find /srv/www/html/panel -type f -exec chmod 644 {} +
chown -R vpanel:vpanel /srv/www/html/panel
+
diff --git a/panel/classes/Panel.php b/panel/classes/Panel.php
index 11afc45..8bfa8e2 100644
--- a/panel/classes/Panel.php
+++ b/panel/classes/Panel.php
@@ -95,7 +95,7 @@ class Panel {
}
- public static function validateEmailPassword($password, $password_confirm) {
+ public static function validatePassword($password, $password_confirm) {
global $f3;
@@ -303,6 +303,136 @@ class Panel {
}
+ 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;
diff --git a/panel/classes/Panel/Cert.php b/panel/classes/Panel/Cert.php
new file mode 100644
index 0000000..f1371c9
--- /dev/null
+++ b/panel/classes/Panel/Cert.php
@@ -0,0 +1,31 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel;
+
+class Cert extends \Panel {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ if ($f3->exists('SESSION.domain')) {
+
+ /* set base path for vhost links */
+ if ($f3->get('NAV.mapping') == 'cert') {
+ $f3->set('NAV.certbase', preg_replace('/\/$/', '', $f3->get('BASE')));
+ } elseif ($f3->get('NAV.mapping') == 'vpanel') {
+ $f3->set('NAV.certbase', preg_replace('/\/$/', '', $f3->get('BASE') . '/Certs/' . $f3->get('SESSION.cert')));
+ }
+
+ }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Cert/Certs.php b/panel/classes/Panel/Cert/Certs.php
new file mode 100644
index 0000000..3db73a8
--- /dev/null
+++ b/panel/classes/Panel/Cert/Certs.php
@@ -0,0 +1,92 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Cert;
+
+class Certs extends \Panel\Cert {
+
+ /* use this to make query */
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ if ($f3->exists('PARAMS.cert')) {
+ $cert = $f3->get('PARAMS.cert');
+ if ($cert_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -d $cert -c", FALSE))) {
+ $f3->set('cert_array', $cert_array[0]);
+ }
+ } else {
+ if ($certs_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -c", FALSE))) {
+ $f3->set('certs_array', $certs_array);
+ }
+ }
+
+ }
+
+ static function get($f3) {
+
+ if ($f3->exists('PARAMS.cert')) {
+
+ $cert_array = $f3->get('cert_array');
+ /* remove time from creation date */
+ $start = $cert_array['start'];
+ $start_array = explode(' ', $start);
+ unset($start_array[2]);
+ $start = implode(' ', $start_array);
+ $cert_array['start'] = $start;
+ /* remove time from expiration date */
+ $end = $cert_array['end'];
+ $end_array = explode(' ', $end);
+ unset($end_array[2]);
+ $end = implode(' ', $end_array);
+ $cert_array['end'] = $end;
+ /* remove main cert name from alternatives */
+ // $common = $cert_array['common'];
+ $alternative = $cert_array['alternative'];
+ // $alternative = preg_replace("/^$common/", '', $alternative);
+ // $alternative = trim($alternative);
+ $alternative = preg_replace('/ /', '
', $alternative);
+ $cert_array['alternative'] = $alternative;
+ $f3->set('cert_array', $cert_array);
+
+ $cert = $f3->get('PARAMS.cert');
+ $f3->set('page_header', "Certificate Details for $cert");
+ echo \Template::instance()->render('cert/certs-cert.html');
+
+ } else {
+
+ $certs_array = $f3->get('certs_array');
+ if (is_array($certs_array) && count($certs_array) > 0) {
+ foreach ($certs_array as $k=>$cert_array) {
+ /* remove time from expiration date */
+ $end = $cert_array['end'];
+ $end_array = explode(' ', $end);
+ unset($end_array[2]);
+ $end = implode(' ', $end_array);
+ $cert_array['end'] = $end;
+ /* remove main cert name from alternatives */
+ // $common = $cert_array['common'];
+ $alternative = $cert_array['alternative'];
+ // $alternative = preg_replace("/^$common/", '', $alternative);
+ // $alternative = trim($alternative);
+ $alternative = preg_replace('/ /', '
', $alternative);
+ $cert_array['alternative'] = $alternative;
+ $certs_array[$k] = $cert_array;
+ }
+ $f3->set('certs_array', $certs_array);
+ }
+
+ $f3->set('page_header', "Certificates");
+ echo \Template::instance()->render('cert/certs.html');
+
+ }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Cert/CertsAdd.php b/panel/classes/Panel/Cert/CertsAdd.php
new file mode 100644
index 0000000..e415536
--- /dev/null
+++ b/panel/classes/Panel/Cert/CertsAdd.php
@@ -0,0 +1,69 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Cert;
+
+class CertsAdd extends \Panel\Cert {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ }
+
+ static function get($f3) {
+
+ if ($f3->exists('PARAMS.cert')) {
+ $domain = $f3->get('PARAMS.cert');
+ if ($f3->call('\Panel::validateDomain', $domain)) {
+ if ($certdomain_dns = dns_get_record("$domain", DNS_A)) {
+ if ($certdomain_dns[0]['ip'] == $_SERVER['SERVER_ADDR']) {
+ if (is_dir('/var/tmp/letsencrypt/')) {
+ if (is_writable('/var/tmp/letsencrypt/')) {
+ touch("/var/tmp/letsencrypt/$domain");
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "A background job to create a Security Certificate for $domain has been started.";
+ $messages[] = "It can take a few seconds, up to one minute, for this job to complete.";
+ $messages[] = "Wait few seconds and then reload this page to check for the new Security Certificate.";
+ $f3->set('SESSION.messages', $messages);
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "System error with Security Certificate system.";
+ $messages[] = "Please try again later.";
+ $f3->set('SESSION.messages', $messages);
+ }
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "System error with Security Certificate system.";
+ $messages[] = "Please try again later.";
+ $f3->set('SESSION.messages', $messages);
+ }
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "DNS for $domain does not point to this server IP.";
+ $messages[] = "Please update DNS and try again.";
+ $f3->set('SESSION.messages', $messages);
+ }
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "Error verifying DNS, try again later.";
+ $f3->set('SESSION.messages', $messages);
+ }
+ }
+ parse_str($f3->get('QUERY'), $output);
+ if (isset($output['r'])) {
+ $f3->reroute($output['r']);
+ }
+
+ }
+ /* default reroute as fallback */
+ $f3->reroute('/');
+ }
+
+}
diff --git a/panel/classes/Panel/Cert/CertsDelete.php b/panel/classes/Panel/Cert/CertsDelete.php
new file mode 100644
index 0000000..6653c27
--- /dev/null
+++ b/panel/classes/Panel/Cert/CertsDelete.php
@@ -0,0 +1,70 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Cert;
+
+class CertsDelete extends \Panel\Cert {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ }
+
+ static function get($f3) {
+
+ $messages = $f3->get('SESSION.messages');
+
+ if ($f3->exists('PARAMS.cert')) {
+ $domain = $f3->get('PARAMS.cert');
+ if ($f3->call('\Panel::validateDomain', $domain)) {
+ if ($f3->call('\Panel::verifyCertificateExists', $domain)) {
+
+ /* delete the cert */
+ $f3->call('\Panel::vGet', array("letsencrypt-delete.sh -d $domain -r", FALSE));
+
+ /* check for and delete dovecot config */
+ if (preg_match('/^mail\./i', $domain)) {
+ $mxdomain = preg_replace('/^mail\./i', '', $f3->get('HOST'));
+ $f3->call('\Panel::vGet', array("vmail-dovecot-disable.sh -d $mxdomain", FALSE));
+ }
+
+ /* delete apache config (vhost or webmail) */
+ if (is_link("/etc/apache2/sites-enabled/$domain.conf")) {
+ $f3->call('\Panel::vGet', array("vhost-disable.sh -d $domain", FALSE));
+ }
+
+ $messages[] = "The Security Certificate and related configs for $domain have been deleted.";
+
+ } else {
+
+ $messages[] = "Security Certificate for $domain not found.";
+
+ }
+
+ } else {
+
+ $messages[] = "Invalid domain name ($domain).";
+
+ }
+
+ }
+
+ /* reroute user to page the originated from */
+ parse_str($f3->get('QUERY'), $output);
+ if (isset($output['r'])) {
+ $f3->reroute($output['r']);
+ } else {
+ /* default reroute as fallback */
+ $f3->reroute('/');
+ }
+
+ }
+
+}
diff --git a/panel/classes/Panel/MySQL.php b/panel/classes/Panel/MySQL.php
new file mode 100644
index 0000000..251baa1
--- /dev/null
+++ b/panel/classes/Panel/MySQL.php
@@ -0,0 +1,20 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel;
+
+class MySQL extends \Panel {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ }
+
+}
diff --git a/panel/classes/Panel/MySQL/Databases.php b/panel/classes/Panel/MySQL/Databases.php
new file mode 100644
index 0000000..c4011e4
--- /dev/null
+++ b/panel/classes/Panel/MySQL/Databases.php
@@ -0,0 +1,27 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\MySQL;
+
+class Databases extends \Panel\MySQL {
+
+ /* use this to make query */
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ }
+
+ static function get($f3) {
+
+ echo \Template::instance()->render('mysql/databases.html');
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vhost/Users.php b/panel/classes/Panel/Vhost/Users.php
new file mode 100644
index 0000000..61bf938
--- /dev/null
+++ b/panel/classes/Panel/Vhost/Users.php
@@ -0,0 +1,62 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vhost;
+
+class Users extends \Panel\Vhost {
+
+ /* use this to make query */
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ if ($f3->exists('PARAMS.username')) {
+ $username = $f3->get('PARAMS.username');
+ if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
+ if ($users_array[0]['passwd'] == "") {
+ $users_array[0]['passwd'] = '(unavailable)';
+ }
+ $f3->set('users_array', $users_array[0]);
+ if ($vhosts_array = $f3->call('\Panel::vGet', array("vhost-get.sh -u $username -c", FALSE))) {
+ $f3->set('vhosts_array', $vhosts_array);
+ }
+ }
+ } else {
+ if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -c", FALSE))) {
+ if (is_array($users_array) && count($users_array) > 0) {
+ foreach ($users_array as $k=>$user_array) {
+ if ($user_array['passwd'] == "") {
+ $users_array[$k]['passwd'] = '(unavailable)';
+ }
+ }
+ $f3->set('users_array', $users_array);
+ }
+ }
+ }
+
+ }
+
+ static function get($f3) {
+
+ if ($f3->exists('PARAMS.username')) {
+
+ $username = $f3->get('PARAMS.username');
+ $f3->set('page_header', "User Details");
+ echo \Template::instance()->render('vhost/users-user.html');
+
+ } else {
+
+ $f3->set('page_header', "Users");
+ echo \Template::instance()->render('vhost/users.html');
+
+ }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vhost/UsersAdd.php b/panel/classes/Panel/Vhost/UsersAdd.php
new file mode 100644
index 0000000..b2c034a
--- /dev/null
+++ b/panel/classes/Panel/Vhost/UsersAdd.php
@@ -0,0 +1,90 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vhost;
+
+class UsersAdd extends \Panel\Vhost {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ /* get system defaults for new users */
+ $user = array();
+ $user['username'] = '';
+ $user['password'] = '';
+ $user['password_confirm'] = '';
+ if ($f3->get('JAILUSER') == '1') {
+ $user['jailuser'] = 1;
+ } else {
+ $user['jailuser'] = 0;
+ }
+ $user['fpmmax'] = $f3->get('FPMMAX');
+ if ($f3->get('WRITEUSERINFO') == '1') {
+ $user['writeuserinfo'] = 1;
+ } else {
+ $user['writeuserinfo'] = 0;
+ }
+ if ($f3->get('SHOWWRITEINFO') == '1') {
+ $user['showwriteinfo'] = 1;
+ } else {
+ $user['showwriteinfo'] = 0;
+ }
+ $f3->set('user', $user);
+
+ }
+
+ static function get($f3) {
+
+ echo \Template::instance()->render('vhost/users-add.html');
+
+ }
+
+ function post($f3) {
+
+ extract($_POST);
+
+ /* force username to be all lower case */
+ $username = strtolower($username);
+ $f3->call('\Panel::validateUsername', $username);
+ /* only validate password if one was submitted, otherwise script will generate random password */
+ if ($password != '' || $password_confirm != '') {
+ $f3->call('\Panel::validatePassword', array($password, $password_confirm));
+ }
+
+ /* check for validation errors */
+ if ($f3->exists('SESSION.messages')) {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "Please make changes and re-submit the form to try again.";
+ $f3->set('SESSION.messages', $messages);
+ $f3->set('user', $_POST);
+ $f3->call('\Panel\Vhost\UsersAdd::get', $f3);
+ } else {
+ $domain = $f3->get('PARAMS.domain');
+ if ($password != '') {
+ $password = "-p " . escapeshellarg($password);
+ }
+ exec("/usr/local/bin/vhost-user-add.sh -u $username -x $fpmmax $password -w $writeuserinfo", $output, $result_code);
+ if ($result_code == 0) {
+ $messages[] = "Success: User $username added.";
+ if ($jailuser == 1) {
+ exec("/usr/local/bin/vhost-user-jail.sh -u $username >/dev/null 2>/dev/null &", $output, $result_code);
+ $messages[] = "Note: User is being jailed. Setting up the jail environment takes about a minute to complete and is run in the background now.";
+ }
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Users");
+ } else {
+ $messages[] = "Error adding user.";
+ $f3->set('SESSION.messages', $messages);
+ $f3->call('\Panel\Vhost\UsersAdd::get', $f3);
+ }
+ }
+ }
+
+}
diff --git a/panel/classes/Panel/Vhost/UsersDelete.php b/panel/classes/Panel/Vhost/UsersDelete.php
new file mode 100644
index 0000000..8a011ad
--- /dev/null
+++ b/panel/classes/Panel/Vhost/UsersDelete.php
@@ -0,0 +1,52 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vhost;
+
+class UsersDelete extends \Panel\Vhost {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ /* verify user exists */
+
+ }
+
+ static function get($f3) {
+
+ $f3->set('confirm', 'true');
+ echo \Template::instance()->render('vhost/users-delete.html');
+
+ }
+
+ function post($f3) {
+
+ /* run delete command here */
+ $username = $f3->get('PARAMS.username');
+ $messages = array();
+ $output = system("/usr/local/bin/vhost-user-del.sh -u $username", $result_code);
+ if ($result_code == 0) {
+ $messages[] = "User '$username' has been deleted.";
+ } else {
+ $messages[] = "Error deleting user '$username'.";
+ $messages[] = $output;
+ }
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Users");
+// $mapping = $f3->get('NAV.mapping');
+// if ($mapping == 'vmail') {
+// $f3->reroute("/Users");
+// } else {
+// $f3->reroute("/Email/$domain/Accounts");
+// }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vhost/UsersEdit.php b/panel/classes/Panel/Vhost/UsersEdit.php
new file mode 100644
index 0000000..68194c7
--- /dev/null
+++ b/panel/classes/Panel/Vhost/UsersEdit.php
@@ -0,0 +1,150 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vhost;
+
+class UsersEdit extends \Panel\Vhost {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+ $username = $f3->get('PARAMS.username');
+ if ($user_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
+ if ($user_array[0]['passwd'] == "") {
+ $user_array[0]['passwd'] = '(unavailable)';
+ }
+ $f3->set('user_array', $user_array[0]);
+ }
+
+ }
+
+ static public function get($f3) {
+
+ if ($f3->exists('PARAMS.username')) {
+
+ $username = $f3->get('PARAMS.username');
+ $f3->set('page_header', "Edit User: $username");
+ echo \Template::instance()->render('vhost/users-edit.html');
+
+ } else {
+
+ $f3->set('page_header', "Users");
+ echo \Template::instance()->render('vhost/users.html');
+
+ }
+
+ }
+
+ function post($f3) {
+
+ $username = $f3->get('PARAMS.username');
+ $action = $_POST['action'];
+
+ if ($action == 'password') {
+ $password = $_POST['password'];
+ $password_confirm = $_POST['password_confirm'];
+ $f3->call('\Panel::validatePassword', array($password, $password_confirm));
+ /* check for validation errors */
+ if ($f3->exists('SESSION.messages')) {
+ $messages = $f3->get('SESSION.messages');
+ } else {
+ $password = escapeshellarg($password);
+ if ($f3->get('WRITEUSERINFO') == '1') {
+ exec("/usr/local/bin/vhost-user-mod.sh -u $username -p $password -w", $output, $result_code);
+ } else {
+ exec("/usr/local/bin/vhost-user-mod.sh -u $username -p $password", $output, $result_code);
+ }
+ if ($result_code == 0) {
+ $messages[] = "Success: Password for $username updated.";
+ } else {
+ $messages[] = "Error updating password.";
+ }
+ }
+ } elseif ($action == 'jail') {
+ exec("/usr/local/bin/vhost-user-jail.sh -u $username >/dev/null 2>/dev/null &", $output, $result_code);
+ $messages[] = "User is being jailed. Note: Setting up the jail environment takes about a minute to complete and is run in the background now.";
+ $f3->reroute("/Users/$username");
+ } elseif ($action == 'fpmmax') {
+ $fpmmax = $_POST['fpmmax'];
+ exec("/usr/local/bin/vhost-user-mod.sh -u $username -x $fpmmax", $output, $result_code);
+ if ($result_code == 0) {
+ $messages[] = "Success: PHP Workers updated.";
+ } else {
+ $messages[] = "Error updating PHP Workers.";
+ }
+ } else {
+ $messages[] = "Unkown edit action.";
+ }
+
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Users/$username");
+
+
+ // /* run mod command here */
+ // $mbox = $f3->get('PARAMS.mbox');
+ // $domain = $f3->get('PARAMS.domain');
+ // $mbox_array = $_POST;
+ // $f3->set('mbox_array', $mbox_array);
+ // foreach ($mbox_array as $k=>$v) {
+ // if (strtolower($v) == 'unlimited') {
+ // $mbox_array[$k] = 'NULL';
+ // }
+ // }
+ // extract($mbox_array);
+ //
+ // if ($password != '') {
+ // $f3->call('\Panel::validatePassword', array($password, $password_confirm));
+ // }
+ // settype($status, "integer");
+ // $f3->call('\Panel::validateEmailStatus', $status);
+ // if (strtolower($quota == 'unlimited') || strtolower($quota == 'null')) {
+ // $quota = "NULL";
+ // } else {
+ // settype($quota, "integer");
+ // }
+ // $f3->call('\Panel::validateEmailQuota', $quota);
+ // if (strtolower($ratelimit == 'unlimited') || strtolower($ratelimit == 'null')) {
+ // $ratelimit = "NULL";
+ // }
+ // $f3->call('\Panel::validateEmailRatelimit', $ratelimit);
+ // $f3->call('\Panel::validateEmailFiltering', $filter);
+ //
+ // /* check for validation errors */
+ // if ($f3->exists('SESSION.messages')) {
+ // $messages = $f3->get('SESSION.messages');
+ // $messages[] = "Please make changes and re-submit the form to try again.";
+ // $f3->set('SESSION.messages', $messages);
+ // $f3->call('\Panel\Vmail\MboxesEdit::get', $f3);
+ // } else {
+ // if ($password != '') {
+ // $password = escapeshellarg($password);
+ // $pword_cmd = "-p $password";
+ // } else {
+ // $pword_cmd = '';
+ // }
+ // exec("/usr/local/bin/vmail-mboxes-mod.sh -e $mbox@$domain $pword_cmd -q $quota -r $ratelimit -s $status -j $filter", $output, $result_code);
+ // if ($result_code == 0) {
+ // $messages[] = "Success: Email account $mbox@$domain updated.";
+ // $f3->set('SESSION.messages', $messages);
+ // $mapping = $f3->get('NAV.mapping');
+ // if ($mapping == 'vmail') {
+ // $f3->reroute("/Accounts/$mbox");
+ // } else {
+ // $f3->reroute("/Email/$domain/Accounts/$mbox");
+ // }
+ // } else {
+ // $messages[] = "Error.";
+ // $f3->set('SESSION.messages', $messages);
+ // $f3->call('\Panel\Vmail\MboxesEdit::get', $f3);
+ // }
+ // }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vhost/Vhosts.php b/panel/classes/Panel/Vhost/Vhosts.php
index 1dc7b23..212e264 100644
--- a/panel/classes/Panel/Vhost/Vhosts.php
+++ b/panel/classes/Panel/Vhost/Vhosts.php
@@ -20,6 +20,39 @@ class Vhosts extends \Panel\Vhost {
$vhost = $f3->get('PARAMS.vhost');
if ($vhost_array = $f3->call('\Panel::vGet', array("vhost-get.sh -d $vhost -c", FALSE))) {
$f3->set('vhost_array', $vhost_array[0]);
+ /* get cert info */
+ if ($f3->call('\Panel::verifyCertificateExists', $vhost)) {
+ if ($cert_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -d $vhost -c", FALSE))) {
+ $cert_array = $cert_array[0];
+ /* remove time from expiration date */
+ $end = $cert_array['end'];
+ $end_array = explode(' ', $end);
+ unset($end_array[2]);
+ $end = implode(' ', $end_array);
+ $cert_array['end'] = $end;
+ /* add line breaks */
+ $common = $cert_array['common'];
+ $alternative = $cert_array['alternative'];
+ $alternative = preg_replace('/ /', '
', $alternative);
+ $cert_array['alternative'] = $alternative;
+ $f3->set('cert_array', $cert_array);
+ }
+ }
+ /* get user info */
+ $username = $vhost_array[0]['username'];
+ if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
+ if ($users_array[0]['passwd'] == "") {
+ $users_array[0]['passwd'] = '(unavailable)';
+ }
+ $f3->set('users_array', $users_array[0]);
+ }
+ /* get mysql db info */
+ if ($mysqlinfo_array = $f3->call('\Panel::vGet', array("vhost-mysql-db-get.sh -d $vhost -c", FALSE))) {
+ $f3->set('mysqlinfo_array', $mysqlinfo_array[0]);
+ } else {
+ $mysqlinfo_array = array('(unknown)', '(unknown)', '(unknown)', '(unknown)');
+ $f3->set('mysqlinfo_array', $mysqlinfo_array);
+ }
}
} else {
if ($vhosts_array = $f3->call('\Panel::vGet', array("vhost-get.sh -c", FALSE))) {
@@ -41,7 +74,7 @@ class Vhosts extends \Panel\Vhost {
$f3->set('vhost_array', $vhost_array);
$vhost = $f3->get('PARAMS.vhost');
- $f3->set('page_header', "Website Hosting for $vhost");
+ $f3->set('page_header', "Details for $vhost");
echo \Template::instance()->render('vhost/vhosts-vhost.html');
} else {
diff --git a/panel/classes/Panel/Vhost/VhostsAdd.php b/panel/classes/Panel/Vhost/VhostsAdd.php
index ef90961..c84ed0b 100644
--- a/panel/classes/Panel/Vhost/VhostsAdd.php
+++ b/panel/classes/Panel/Vhost/VhostsAdd.php
@@ -15,9 +15,26 @@ class VhostsAdd extends \Panel\Vhost {
parent::beforeRoute($f3);
-// /* get vm_domains defaults for "add new" form */
-// $vm_domains_defaults = $f3->call('\Panel::vGet', array("vmail-defaults-get.sh -c", FALSE));
-// $f3->set('vm_domains_defaults', $vm_domains_defaults[0]);
+ /* get system defaults for new websites */
+ $deploy = array();
+ $deploy['username'] = '';
+ if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -c", FALSE))) {
+ $deploy['users_array'] = $users_array;
+ } else {
+ $deploy['users_array'] = array();
+ }
+
+ if ($f3->get('WRITEUSERINFO') == '1') {
+ $deploy['writeuserinfo'] = 1;
+ } else {
+ $deploy['writeuserinfo'] = 0;
+ }
+ if ($f3->get('SHOWWRITEINFO') == '1') {
+ $deploy['showwriteinfo'] = 1;
+ } else {
+ $deploy['showwriteinfo'] = 0;
+ }
+ $f3->set('deploy', $deploy);
}
@@ -34,93 +51,61 @@ class VhostsAdd extends \Panel\Vhost {
$messages = array();
/* validate domain */
- if (preg_match('/^[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,24}$/i', strtolower($_POST['domain']))) {
- // strip www
- $domain = strtolower($_POST['domain']);
- } else {
- $messages[] = "Invalid domain name.";
- }
-
- /* validate status */
- if ($_POST['status'] != 0 && $_POST['status'] != 1) {
- $messages[] = "Invalid 'Status'.";
- } else {
- $status = $_POST['status'];
- }
-
- /* validate mbox_limit */
- if (strtolower($_POST['mbox_limit']) == 'unlimited' || strtolower($_POST['mbox_limit'] == 'null')) {
- $mbox_limit = "NULL";
- } elseif (is_numeric($_POST['mbox_limit'])) {
- /* make sure mbox_limit is a possitive integer */
- $mbox_limit = abs(intval($_POST['mbox_limit']));
- if ($mbox_limit < 1) {
- echo "Mailbox Limit must be a positive number or \"Unlimited\".\n";
- $messages[] = "Mailbox Limit must be a positive number or \"Unlimited\".";
- }
- } else {
- $messages[] = "Mailbox Limit must be a positive number or \"Unlimited\".";
- }
-
- /* validate mbox_quota_default */
- if (strtolower($_POST['mbox_quota_default']) == 'unlimited' || strtolower($_POST['mbox_quota_default'] == 'null')) {
- $mbox_quota_default = "NULL";
- } elseif (is_numeric($_POST['mbox_quota_default'])) {
- /* make sure mbox_quota_default is a possitive integer */
- $mbox_quota_default = abs(intval($_POST['mbox_quota_default']));
- if ($mbox_quota_default < 1) {
- echo "Default Quota must be a positive number or \"Unlimited\".\n";
- $messages[] = "Default Quota must be a positive number or \"Unlimited\".";
- }
- } else {
- $messages[] = "Default Quota must be a positive number or \"Unlimited\".";
- }
-
- /* validate mbox_ratelimit_default */
- if (strtolower($_POST['mbox_ratelimit_default']) == 'unlimited' || strtolower($_POST['mbox_ratelimit_default'] == 'null')) {
- $mbox_ratelimit_default = "NULL";
- } elseif (is_numeric($_POST['mbox_ratelimit_default'])) {
- /* make sure mbox_ratelimit_default is a possitive integer */
- $mbox_ratelimit_default = abs(intval($_POST['mbox_ratelimit_default']));
- if ($mbox_ratelimit_default < 1) {
- $messages[] = "Default Rate Limit must be a positive number or \"Unlimited\".";
- }
- } else {
- $messages[] = "Default Rate Limit must be a positive number or \"Unlimited\".";
- }
-
- /* check for validation errors */
- if (count($messages) > 0) {
- $messages[] = "Please re-submit the form to try again.";
- $f3->set('SESSION.messages', $messages);
- $f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
- } else {
- /* check if vmail domain already exists */
- $domain_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -d $domain -c", FALSE));
- if (count($domain_array) == 0) {
- /* add email domain */
- exec("/usr/local/bin/vmail-domains-add.sh -d $domain -l $mbox_limit -q $mbox_quota_default -r $mbox_ratelimit_default -s $status", $output, $result_code);
- if ($result_code == 0) {
- $messages[] = "Email Domain $domain has been added.";
- $f3->set('SESSION.messages', $messages);
- $f3->reroute("/Email/$domain");
- } else {
- if (count($output) > 0) {
- foreach ($output as $k=>$output_message) {
- $messages[] = "$output_message";
- }
- } else {
- $messages[] = "Unknown error adding Email Domain $domain.";
- }
- $f3->set('SESSION.messages', $messages);
- $f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
- }
- } else {
- $messages[] = "Email Domain '$domain' already exists.";
+ $domain = strtolower($_POST['domain']);
+ $domain = preg_replace('/^www\./', '', $domain);
+ if ($f3->call('\Panel::validateDomain', $domain)) {
+ if ($f3->call('\Panel::verifyVhostDomainExists', $domain)) {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "$domain already exists on this server.";
$f3->set('SESSION.messages', $messages);
- $f3->reroute("/Email/$domain");
+ $f3->reroute("/Websites/Add");
+ } else {
+ $cmd = "/usr/local/bin/vhost-deploy.sh -d $domain";
+ }
+ } else {
+ $f3->reroute("/Websites/Add");
+ }
+
+ /* validate username & set related options */
+ $username = strtolower($_POST['username']);
+ if ($f3->get('JAILUSER') == '1') {
+ $jailuser = 1;
+ } else {
+ $jailuser = 0;
+ }
+ if ($username == '') {
+ $cmd = "$cmd -j $jailuser";
+ } else {
+ if ($f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
+ $cmd = "$cmd -u $username";
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "Error validating username $username.";
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Websites/Add");
}
}
+
+ if ($f3->get('WRITEUSERINFO') == '1') {
+ $writeuserinfo = 1;
+ } else {
+ $writeuserinfo = 0;
+ }
+ $cmd = "$cmd -w $writeuserinfo";
+ exec("$cmd", $output, $result_code);
+ if ($result_code == 0) {
+ $messages[] = "Success: Website $domain added.";
+ if ($username == '' && $jailuser == 1) {
+ $messages[] = "Note: New user is being jailed. Setting up the jail environment takes about a minute to complete and is being run in the background now.";
+ }
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Websites");
+ } else {
+ $messages[] = "Error adding website.";
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Websites/Add");
+ }
+
}
}
diff --git a/panel/classes/Panel/Vhost/VhostsDelete.php b/panel/classes/Panel/Vhost/VhostsDelete.php
new file mode 100644
index 0000000..21f2bef
--- /dev/null
+++ b/panel/classes/Panel/Vhost/VhostsDelete.php
@@ -0,0 +1,52 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vhost;
+
+class VhostsDelete extends \Panel\Vhost {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ /* verify user exists */
+
+ }
+
+ static function get($f3) {
+
+ $f3->set('confirm', 'true');
+ echo \Template::instance()->render('vhost/vhosts-delete.html');
+
+ }
+
+ function post($f3) {
+
+ /* run delete command here */
+ $domain = $f3->get('PARAMS.vhost');
+ $messages = array();
+ $output = system("/usr/local/bin/vhost-destroy.sh -d $domain", $result_code);
+ if ($result_code == 0) {
+ $messages[] = "Website '$domain' has been deleted.";
+ } else {
+ $messages[] = "Error deleting website '$domain'.";
+ $messages[] = $output;
+ }
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Websites");
+// $mapping = $f3->get('NAV.mapping');
+// if ($mapping == 'vmail') {
+// $f3->reroute("/Users");
+// } else {
+// $f3->reroute("/Email/$domain/Accounts");
+// }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vhost/VhostsDisable.php b/panel/classes/Panel/Vhost/VhostsDisable.php
new file mode 100644
index 0000000..2d9a21d
--- /dev/null
+++ b/panel/classes/Panel/Vhost/VhostsDisable.php
@@ -0,0 +1,47 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vhost;
+
+class VhostsDisable extends \Panel\Vhost {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ /* verify user exists */
+
+ }
+
+ static function get($f3) {
+
+ /* run delete command here */
+ $domain = $f3->get('PARAMS.vhost');
+ $messages = array();
+ $output = system("/usr/local/bin/vhost-disable.sh -d $domain", $result_code);
+ if ($result_code == 0) {
+ $messages[] = "Website '$domain' has been disabled.";
+ $messages[] = "NOTICE: Nothing has been deleted and the site can be re-enabled at any time.";
+ } else {
+ $messages[] = "Error disabling website '$domain'.";
+ $messages[] = $output;
+ }
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Websites/$domain");
+// $mapping = $f3->get('NAV.mapping');
+// if ($mapping == 'vmail') {
+// $f3->reroute("/Users");
+// } else {
+// $f3->reroute("/Email/$domain/Accounts");
+// }
+
+ }
+
+
+}
diff --git a/panel/classes/Panel/Vhost/VhostsEnable.php b/panel/classes/Panel/Vhost/VhostsEnable.php
new file mode 100644
index 0000000..8bdd376
--- /dev/null
+++ b/panel/classes/Panel/Vhost/VhostsEnable.php
@@ -0,0 +1,37 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vhost;
+
+class VhostsEnable extends \Panel\Vhost {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ }
+
+ static function get($f3) {
+
+ /* run enable command here */
+ $domain = $f3->get('PARAMS.vhost');
+ $messages = array();
+ $output = system("/usr/local/bin/vhost-enable.sh -d $domain", $result_code);
+ if ($result_code == 0) {
+ $messages[] = "Website '$domain' has been enabled.";
+ } else {
+ $messages[] = "Error enabling website '$domain'.";
+ $messages[] = $output;
+ }
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute("/Websites/$domain");
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vmail/Dkim.php b/panel/classes/Panel/Vmail/Dkim.php
new file mode 100644
index 0000000..2c43caf
--- /dev/null
+++ b/panel/classes/Panel/Vmail/Dkim.php
@@ -0,0 +1,66 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vmail;
+
+class Dkim extends \Panel\Vmail {
+
+ /* use this to make query */
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ if ($f3->exists('PARAMS.domain')) {
+ $domain = $f3->get('PARAMS.domain');
+ $dkim_array = array();
+ if ($f3->call('\Panel::verifyDkimExists', $domain)) {
+ if ($dkim_array = $f3->call('\Panel::vGet', array("vmail-dkim-get.sh -d $domain -c", FALSE))) {
+ $dkim_array = $dkim_array[0];
+ $dkim_array['dns']['host'] = $dkim_array['selector'] . "._domainkey.$domain";
+ if ($dns_txt_records = dns_get_record($dkim_array['dns']['host'], DNS_TXT)) {
+ $dkim_array['dns']['status'] = "Verified";
+ } else {
+ $dkim_array['dns']['status'] = "Update";
+ }
+ } else {
+ $dkim_array['dns']['status'] = "Error";
+ }
+ } else {
+ $dkim_array['dns']['status'] = "Create";
+ }
+ $f3->set('dkim_array', $dkim_array);
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "Domain not set, must specify domain for DKIM info.";
+ $f3->set('SESSION.messages', $messages);
+ $f3->reroute('/');
+ }
+
+ }
+
+ static function get($f3) {
+
+ if ($f3->exists('PARAMS.domain')) {
+
+ $domain = $f3->get('PARAMS.domain');
+ $f3->set('page_header', "DKIM Details for $domain");
+
+ } else {
+
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "Domain not set, must specify domain for DKIM info.";
+ $f3->set('SESSION.messages', $messages);
+
+ }
+
+ echo \Template::instance()->render('vmail/dkim.html');
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vmail/DkimAdd.php b/panel/classes/Panel/Vmail/DkimAdd.php
new file mode 100644
index 0000000..eeea02b
--- /dev/null
+++ b/panel/classes/Panel/Vmail/DkimAdd.php
@@ -0,0 +1,60 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vmail;
+
+class DkimAdd extends \Panel\Vmail {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ }
+
+ static function get($f3) {
+
+ if ($f3->exists('PARAMS.domain')) {
+ $domain = $f3->get('PARAMS.domain');
+ if ($f3->call('\Panel::validateDomain', $domain)) {
+ if ($f3->call('\Panel::verifyVmailDomainExists', $domain)) {
+ if ($f3->call('\Panel::verifyDkimExists', $domain)) {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "DKIM for $domain already exists.";
+ $f3->set('SESSION.messages', $messages);
+ } else {
+ exec("/usr/local/bin/vmail-dkim-add.sh -d $domain", $output, $result_code);
+ $messages = $f3->get('SESSION.messages');
+ if ($result_code == 0) {
+ $messages[] = "DKIM for $domain has been added.";
+ } else {
+ $messages[] = "ERROR: adding DKIM for $domain failed.";
+ }
+ $f3->set('SESSION.messages', $messages);
+ }
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "ERROR: $domain is not configured for email on this server.";
+ $f3->set('SESSION.messages', $messages);
+ }
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "ERROR: Invalid domain: $domain.";
+ $f3->set('SESSION.messages', $messages);
+ }
+ }
+ parse_str($f3->get('QUERY'), $output);
+ if (isset($output['r'])) {
+ $f3->reroute($output['r']);
+ } else {
+ $f3->reroute('/');
+ }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vmail/DkimDelete.php b/panel/classes/Panel/Vmail/DkimDelete.php
new file mode 100644
index 0000000..f440381
--- /dev/null
+++ b/panel/classes/Panel/Vmail/DkimDelete.php
@@ -0,0 +1,61 @@
+
+ * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+ */
+
+namespace Panel\Vmail;
+
+class DkimDelete extends \Panel\Vmail {
+
+ function beforeRoute($f3) {
+
+ parent::beforeRoute($f3);
+
+ }
+
+ static function get($f3) {
+
+ $f3->set('confirm', 'true');
+ echo \Template::instance()->render('vmail/dkim-delete.html');
+
+ }
+
+ static function post($f3) {
+
+ if ($f3->exists('PARAMS.domain')) {
+ $domain = $f3->get('PARAMS.domain');
+ if ($f3->call('\Panel::validateDomain', $domain)) {
+ if ($f3->call('\Panel::verifyDkimExists', $domain)) {
+ /* delete the dkim keys */
+ exec("/usr/local/bin/vmail-dkim-del.sh -d $domain", $output, $result_code);
+ $messages = $f3->get('SESSION.messages');
+ if ($result_code == 0) {
+ $messages[] = "DKIM keys for $domain have been deleted.";
+ $messages[] = "Note that you probably want to delete the associated DNS record now too.";
+ } else {
+ $messages[] = "Error deleting DKIM keys for $domain.";
+ }
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "DKIM keys for $domain not found.";
+ }
+ } else {
+ $messages = $f3->get('SESSION.messages');
+ $messages[] = "Invalid domain name ($domain).";
+ }
+ }
+ $f3->set('SESSION.messages', $messages);
+ $mapping = $f3->get('NAV.mapping');
+ if ($mapping == 'vmail') {
+ $f3->reroute("/");
+ } else {
+ $f3->reroute("/Email/$domain");
+ }
+
+ }
+
+}
diff --git a/panel/classes/Panel/Vmail/Domains.php b/panel/classes/Panel/Vmail/Domains.php
index d752ae3..96275b6 100644
--- a/panel/classes/Panel/Vmail/Domains.php
+++ b/panel/classes/Panel/Vmail/Domains.php
@@ -19,15 +19,132 @@ class Domains extends \Panel\Vmail {
$domain = $f3->get('PARAMS.domain');
if ($domain_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -d $domain -c", FALSE))) {
$f3->set('domain_array', $domain_array[0]);
+ /* get cert info */
+ $mxdomain = "mail.$domain";
+ if ($f3->call('\Panel::verifyCertificateExists', $mxdomain)) {
+ if ($cert_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -d $mxdomain -c", FALSE))) {
+ $cert_array = $cert_array[0];
+ /* remove time from expiration date */
+ $end = $cert_array['end'];
+ $end_array = explode(' ', $end);
+ unset($end_array[2]);
+ $end = implode(' ', $end_array);
+ $cert_array['end'] = $end;
+ /* add line breaks */
+ $common = $cert_array['common'];
+ $alternative = $cert_array['alternative'];
+ $alternative = preg_replace('/ /', '
', $alternative);
+ $cert_array['alternative'] = $alternative;
+ $f3->set('cert_array', $cert_array);
+ }
+ }
+ /* get dns info */
+ $dnsinfo = array();
+ $dnsinfo['verified_count'] = 0;
+ $dnsinfo['server_addr'] = $_SERVER['SERVER_ADDR'];
+ # A record
+ $dnsinfo['a']['color'] = "red";
+ if ($certdomain_dns = dns_get_record("$mxdomain", DNS_A)) {
+ if ($certdomain_dns[0]['ip'] == $dnsinfo['server_addr']) {
+ $dnsinfo['a']['status'] = "Verified";
+ $dnsinfo['a']['color'] = "black";
+ $dnsinfo['verified_count']++;
+ } else {
+ $dnsinfo['a']['status'] = "Update";
+ }
+ } else {
+ $dnsinfo['a']['status'] = "Create";
+ }
+ # MX record
+ $dnsinfo['mx']['color'] = "red";
+ if (getmxrr($domain, $mx)) {
+ if (in_array($mxdomain, $mx)) {
+ $dnsinfo['mx']['status'] = "Verified";
+ $dnsinfo['mx']['color'] = "black";
+ $dnsinfo['verified_count']++;
+ } else {
+ $dnsinfo['mx']['status'] = "Update";
+ }
+ } else {
+ $dnsinfo['mx']['status'] = "Create";
+ }
+ # SPF (TXT) record
+ $dnsinfo['spf']['status'] = "Create";
+ $dnsinfo['spf']['color'] = "red";
+ if ($dns_txt_records = dns_get_record("$domain", DNS_TXT)) {
+ foreach ($dns_txt_records as $k=>$dns_txt_record) {
+ if (str_starts_with($dns_txt_record['txt'], 'v=spf1')) {
+ $dnsinfo['spf']['status'] = "Update";
+ if (str_contains($dns_txt_record['txt'], ' mx ')) {
+ $dnsinfo['spf']['status'] = "Verified";
+ $dnsinfo['spf']['color'] = "black";
+ $dnsinfo['verified_count']++;
+ }
+ }
+ }
+ }
+ # DKIM
+ $dnsinfo['dkim']['color'] = "red";
+ if ($f3->call('\Panel::verifyDkimExists', $domain)) {
+ if ($dkim_array = $f3->call('\Panel::vGet', array("vmail-dkim-get.sh -d $domain -c", FALSE))) {
+ $dkim_hostname = $dkim_array[0]['selector'] . "._domainkey.$domain";
+ if ($dns_txt_records = dns_get_record($dkim_hostname, DNS_TXT)) {
+ $dnsinfo['dkim']['status'] = "Verified";
+ $dnsinfo['dkim']['color'] = "black";
+ $dnsinfo['verified_count']++;
+ } else {
+ $dnsinfo['dkim']['status'] = "Update";
+ $dnsinfo['dkim']['selector'] = $dkim_array[0]['selector'];
+ $dnsinfo['dkim']['dkim'] = $dkim_array[0]['dkim'];
+ }
+ } else {
+ $dnsinfo['dkim']['status'] = "Error";
+ }
+ } else {
+ $dnsinfo['dkim']['status'] = "Create";
+ }
+
+ if ($dnsinfo['verified_count'] == 4) {
+ $dnsinfo['status'] = 'Verified';
+ } else {
+ $dnsinfo['status'] = 'Update';
+ }
+
+ $f3->set('dnsinfo', $dnsinfo);
+
}
} else {
if ($domains_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -c", FALSE))) {
$f3->set('domains_array', $domains_array);
}
}
-
}
+ // $dnsinfo['mx']['status'] = ready/update/none
+ // $dnsinfo['spf']['status'] = ready/update/none
+ // $dnsinfo['spf']['data'] = current_record
+ // $dnsinfo['dkim']['status'] = ready/update/none
+ // $dnsinfo['dkim']['selector'] =
+ // $dnsinfo['dkim']['data'] =
+
+ // dns_a gethostbyname()
+ // dns_mx getmxrr() / dns_get_mx()
+ // dns_spf checkdnsrr() / dns_check_record()
+ // dns_dkim
+ // # domain does not have cert yet, check DNS
+ // $dns_a_record = $_SERVER['SERVER_ADDR'];
+ // if ($certdomain_dns = dns_get_record("$certdomain", DNS_A)) {
+ // if ($certdomain_dns[0]['ip'] == $dns_a_record) {
+ // $dns_status = "ready";
+ // } else {
+ // $dns_status = "update";
+ // }
+ // } else {
+ // $dns_status = "none";
+ // }
+ // $f3->set('dns_a_record', $dns_a_record);
+ // $f3->set('dns_status', $dns_status);
+
static function get($f3) {
if ($f3->exists('PARAMS.domain')) {
diff --git a/panel/classes/Panel/Vmail/DomainsAdd.php b/panel/classes/Panel/Vmail/DomainsAdd.php
index 55cf616..64fac1d 100644
--- a/panel/classes/Panel/Vmail/DomainsAdd.php
+++ b/panel/classes/Panel/Vmail/DomainsAdd.php
@@ -34,10 +34,13 @@ class DomainsAdd extends \Panel\Vmail {
$messages = array();
/* validate domain */
- if (preg_match('/^[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,24}$/i', strtolower($_POST['domain']))) {
- $domain = strtolower($_POST['domain']);
- } else {
- $messages[] = "Invalid domain name.";
+ $domain = strtolower($_POST['domain']);
+ $domain = preg_replace('/^mail\./', '', $domain);
+ $domain = preg_replace('/^www\./', '', $domain);
+ if ($f3->call('\Panel::validateDomain', $domain)) {
+ if ($f3->call('\Panel::verifyVmailDomainExists', $domain)) {
+ $messages[] = "Email Domain '$domain' already exists.";
+ }
}
/* validate status */
@@ -94,32 +97,23 @@ class DomainsAdd extends \Panel\Vmail {
$f3->set('SESSION.messages', $messages);
$f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
} else {
- /* check if vmail domain already exists */
- $domain_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -d $domain -c", FALSE));
- if (count($domain_array) == 0) {
- /* add email domain */
- exec("/usr/local/bin/vmail-domains-add.sh -d $domain -l $mbox_limit -q $mbox_quota_default -r $mbox_ratelimit_default -s $status", $output, $result_code);
- if ($result_code == 0) {
- $messages[] = "Email Domain $domain has been added.";
- $f3->set('SESSION.messages', $messages);
- $f3->reroute("/Email/$domain");
- } else {
- if (count($output) > 0) {
- foreach ($output as $k=>$output_message) {
- $messages[] = "$output_message";
- }
- } else {
- $messages[] = "Unknown error adding Email Domain $domain.";
- }
- $f3->set('SESSION.messages', $messages);
- $f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
- }
- } else {
- $messages[] = "Email Domain '$domain' already exists.";
+ /* add email domain */
+ exec("/usr/local/bin/vmail-domains-add.sh -d $domain -l $mbox_limit -q $mbox_quota_default -r $mbox_ratelimit_default -s $status", $output, $result_code);
+ if ($result_code == 0) {
+ $messages[] = "Email Domain $domain has been added.";
$f3->set('SESSION.messages', $messages);
$f3->reroute("/Email/$domain");
+ } else {
+ if (count($output) > 0) {
+ foreach ($output as $k=>$output_message) {
+ $messages[] = "$output_message";
+ }
+ } else {
+ $messages[] = "Unknown error adding Email Domain $domain.";
+ }
+ $f3->set('SESSION.messages', $messages);
+ $f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
}
}
}
-
}
diff --git a/panel/classes/Panel/Vmail/MboxesAdd.php b/panel/classes/Panel/Vmail/MboxesAdd.php
index 30cab53..39ccdb2 100644
--- a/panel/classes/Panel/Vmail/MboxesAdd.php
+++ b/panel/classes/Panel/Vmail/MboxesAdd.php
@@ -58,7 +58,7 @@ class MboxesAdd extends \Panel\Vmail {
extract($_POST);
$f3->call('\Panel::validateEmailLocalpart', $localpart);
- $f3->call('\Panel::validateEmailPassword', array($password, $password_confirm));
+ $f3->call('\Panel::validatePassword', array($password, $password_confirm));
settype($status, "integer");
$f3->call('\Panel::validateEmailStatus', $status);
if (strtolower($quota == 'unlimited') || strtolower($quota == 'null')) {
diff --git a/panel/classes/Panel/Vmail/MboxesEdit.php b/panel/classes/Panel/Vmail/MboxesEdit.php
index edec05a..11de74c 100644
--- a/panel/classes/Panel/Vmail/MboxesEdit.php
+++ b/panel/classes/Panel/Vmail/MboxesEdit.php
@@ -62,7 +62,7 @@ class MboxesEdit extends \Panel\Vmail {
extract($mbox_array);
if ($password != '') {
- $f3->call('\Panel::validateEmailPassword', array($password, $password_confirm));
+ $f3->call('\Panel::validatePassword', array($password, $password_confirm));
}
settype($status, "integer");
$f3->call('\Panel::validateEmailStatus', $status);
diff --git a/panel/config/config.ini b/panel/config/config.ini
index af814f4..7ccd7ad 100644
--- a/panel/config/config.ini
+++ b/panel/config/config.ini
@@ -16,6 +16,15 @@ LICENSE=GPL-3.0
LICENSEURL=https://www.gnu.org/licenses/gpl-3.0.txt
CASELESS=FALSE
CACHE=TRUE
-; session lifetime in seconds
+; Session lifetime in seconds
TIMEOUT=900
+; Remote IP address that is automatically logged in without auth
ADMINIP=
+; Jail new users by default. 1 = Yes, blank or 0 = No
+JAILUSER=1
+; PHP-FPM pm.max_children. Recommended range 2-12 on Shared Server
+FPMMAX=4
+; Write user info to /home/username/.passwd. 1 = Yes, blank or 0 = No
+WRITEUSERINFO=1
+; Show "Write User Info" & "Write DB Info" options. If no then just use defaults above without giving users the option to change. 1 = Yes, blank or 0 = No
+SHOWWRITEINFO=0
diff --git a/panel/config/maps-vpanel.ini b/panel/config/maps-vpanel.ini
index 61106c9..bebb7cb 100644
--- a/panel/config/maps-vpanel.ini
+++ b/panel/config/maps-vpanel.ini
@@ -30,6 +30,9 @@
/Email/@domain/Accounts/@mbox/Forwarding/Add [sync] = Panel\Vmail\ForwardsAdd
/Email/@domain/Accounts/@mbox/Forwarding/Edit [sync] = Panel\Vmail\ForwardsEdit
/Email/@domain/Accounts/@mbox/Forwarding/Delete [sync] = Panel\Vmail\ForwardsDelete
+/Email/@domain/Dkim [sync] = Panel\Vmail\Dkim
+/Email/@domain/Dkim/Add [sync] = Panel\Vmail\DkimAdd
+/Email/@domain/Dkim/Delete [sync] = Panel\Vmail\DkimDelete
/Email/@domain/Aliases [sync] = Panel\Vmail\Aliases
/Email/@domain/Aliases/@alias [sync] = Panel\Vmail\Aliases
/Email/@domain/Autoresponders [sync] = Panel\Vmail\Autoresponders
@@ -38,16 +41,17 @@
/Websites [sync] = Panel\Vhost\Vhosts
/Websites/Add [sync] = Panel\Vhost\VhostsAdd
/Websites/@vhost [sync] = Panel\Vhost\Vhosts
-/Websites/@vhost/Edit [sync] = Panel\Vhost\VhostsEdit
+/Websites/@vhost/Disable [sync] = Panel\Vhost\VhostsDisable
+/Websites/@vhost/Enable [sync] = Panel\Vhost\VhostsEnable
/Websites/@vhost/Delete [sync] = Panel\Vhost\VhostsDelete
-/Websites/@vhost/Databases [sync] = Panel\Vhost\Databases
-/Websites/@vhost/Databases/Add [sync] = Panel\Vhost\DatabasesAdd
-/Websites/@vhost/Databases/Delete [sync] = Panel\Vhost\DatabasesDelete
-/Websites/@vhost/Databases/Users [sync] = Panel\Vhost\DatabasesUsers
-/Websites/@vhost/Databases/Users/Add [sync] = Panel\Vhost\DatabasesUsersAdd
-/Websites/@vhost/Databases/Users/Edit [sync] = Panel\Vhost\DatabasesUsersEdit
-/Websites/@vhost/Databases/Users/Delete [sync] = Panel\Vhost\DatabasesUsersDelete
+; /Websites/@vhost/Databases [sync] = Panel\Vhost\Databases
+; /Websites/@vhost/Databases/Add [sync] = Panel\Vhost\DatabasesAdd
+; /Websites/@vhost/Databases/Delete [sync] = Panel\Vhost\DatabasesDelete
+; /Websites/@vhost/Databases/Users [sync] = Panel\Vhost\DatabasesUsers
+; /Websites/@vhost/Databases/Users/Add [sync] = Panel\Vhost\DatabasesUsersAdd
+; /Websites/@vhost/Databases/Users/Edit [sync] = Panel\Vhost\DatabasesUsersEdit
+; /Websites/@vhost/Databases/Users/Delete [sync] = Panel\Vhost\DatabasesUsersDelete
/Websites/Redirects [sync] = Panel\Vhost\Redirects
/Websites/Redirects/Add [sync] = Panel\Vhost\RedirectsAdd
@@ -70,6 +74,14 @@
; System users (ssh, websites)
/Users [sync] = Panel\Vhost\Users
/Users/Add [sync] = Panel\Vhost\UsersAdd
-/Users/@user [sync] = Panel\Vhost\Users
-/Users/@user/Edit [sync] = Panel\Vhost\UsersEdit
-/Users/@user/Delete [sync] = Panel\Vhost\UsersDelete
+/Users/@username [sync] = Panel\Vhost\Users
+/Users/@username/Edit [sync] = Panel\Vhost\UsersEdit
+/Users/@username/Delete [sync] = Panel\Vhost\UsersDelete
+
+/Certs [sync] = Panel\Cert\Certs
+/Certs/@cert [sync] = Panel\Cert\Certs
+/Certs/@cert/Add [sync] = Panel\Cert\CertsAdd
+/Certs/@cert/Delete [sync] = Panel\Cert\CertsDelete
+
+/Databases [sync] = Panel\MySQL\Databases
+
diff --git a/panel/ui/cert/certs-cert.html b/panel/ui/cert/certs-cert.html
new file mode 100644
index 0000000..5494673
--- /dev/null
+++ b/panel/ui/cert/certs-cert.html
@@ -0,0 +1,40 @@
+
Certificate | +Expiration | +Secured Hostnames | +Action | +
---|---|---|---|
{{ @cert_array.common }} | +{{ @cert_array.end }} | +{{ @cert_array.alternative | raw }} | +Delete | +
Certificate | +Expiration | +Secured Hostnames | +
---|---|---|
{{ @cert_array.common }} | +{{ @cert_array.end }} | +{{ @cert_array.alternative | raw }} | +
+ Certificate is the name of the configuration and is normally the primary domain secured.
+ Expiration is the date the certificate expires. Certificates are automatically renewed 30 days before expiration.
+ Secured Hostnames is the full list of domain names secured by the certificate.
+
There are no security certificates on this server.
+
+Username is the system username that a website can be installed under. It will be used for SFTP & SSH access. Mixed case usernames are converted to all lower case.
+Password must be at least 8 characters with 12 or more being highly recommended.
+Passwords under 15 characters must contain characters from at least three of the following four groups:
+Lower Case Letters, Uppler Case Leters, Numbers, Puncuation/Special Characters.
+Passwords 15 or more characters long do not have any complexity requirements.
+Jail determines if the user will be "jailed". This is recommended on a Shared Server. Once a user is Jailed it can't be undone by these admins.
+
+
+
+
+ + ++ +
+ + + ++
+ + +Username | +Password | +Jailed | +PHP Workers | +Action | +
---|---|---|---|---|
{{ @users_array.username }} | +{{ @users_array.passwd }} | +{{ @users_array.jailed }} | +{{ @users_array.fpmmax }} | +Edit Delete | +
Website | +Username | +Status | +Action | +
---|---|---|---|
{{ @vhost_domain.virtualhost }} | +{{ @vhost_domain.username }} | +{{ @vhost_domain.status }} | +Disable Delete | +
Username | +Password | +Jailed | +PHP Workers | +
---|---|---|---|
{{ @userinfo.username }} | +{{ @userinfo.passwd }} | +{{ @userinfo.jailed }} | +{{ @userinfo.fpmmax }} | +
+ Select a Username name above for more details and options.
+ Username is the system username that owns the website files.
+
+ Password is the unencrypted password for the user, if available. Scroll over field to reveal password.
+ Jailed is a flag indicating if the user is jailed.
+ PHP Workers is maximum number of PHP processes that this user can have running at one time.
+
There are no website system users on this server.
+