Jelajahi Sumber

Add Control Panel UI for Per-Domain Mail SSL

Kristan Kenney 7 tahun lalu
induk
melakukan
a417434c65

+ 180 - 0
web/edit/mail/index.php

@@ -39,6 +39,25 @@ if ((!empty($_GET['domain'])) && (empty($_GET['account'])))  {
     } else {
         $v_status =  'active';
     }
+    
+    $v_ssl = $data[$v_domain]['SSL'];
+    if (!empty($v_ssl)) {
+        exec (HESTIA_CMD."v-list-mail-domain-ssl ".$user." '".$v_domain."' json", $output, $return_var);
+        $ssl_str = json_decode(implode('', $output), true);
+        unset($output);
+        $v_ssl_crt = $ssl_str[$v_domain]['CRT'];
+        $v_ssl_key = $ssl_str[$v_domain]['KEY'];
+        $v_ssl_ca = $ssl_str[$v_domain]['CA'];
+        $v_ssl_subject = $ssl_str[$v_domain]['SUBJECT'];
+        $v_ssl_aliases = $ssl_str[$v_domain]['ALIASES'];
+        $v_ssl_not_before = $ssl_str[$v_domain]['NOT_BEFORE'];
+        $v_ssl_not_after = $ssl_str[$v_domain]['NOT_AFTER'];
+        $v_ssl_signature = $ssl_str[$v_domain]['SIGNATURE'];
+        $v_ssl_pub_key = $ssl_str[$v_domain]['PUB_KEY'];
+        $v_ssl_issuer = $ssl_str[$v_domain]['ISSUER'];
+    }
+    $v_letsencrypt = $data[$v_domain]['LETSENCRYPT'];
+    if (empty($v_letsencrypt)) $v_letsencrypt = 'no';
 }
 
 // List mail account
@@ -164,6 +183,167 @@ if ((!empty($_POST['save'])) && (!empty($_GET['domain'])) && (empty($_GET['accou
         check_return_code($return_var,$output);
         unset($output);
     }
+    
+    // Change SSL certificate
+    if (( $v_letsencrypt == 'no' ) && (empty($_POST['v_letsencrypt'])) && ( $v_ssl == 'yes' ) && (!empty($_POST['v_ssl'])) && (empty($_SESSION['error_msg']))) {
+        if (( $v_ssl_crt != str_replace("\r\n", "\n",  $_POST['v_ssl_crt'])) || ( $v_ssl_key != str_replace("\r\n", "\n",  $_POST['v_ssl_key'])) || ( $v_ssl_ca != str_replace("\r\n", "\n",  $_POST['v_ssl_ca']))) {
+            exec ('mktemp -d', $mktemp_output, $return_var);
+            $tmpdir = $mktemp_output[0];
+
+            // Certificate
+            if (!empty($_POST['v_ssl_crt'])) {
+                $fp = fopen($tmpdir."/".$_POST['v_domain'].".crt", 'w');
+                fwrite($fp, str_replace("\r\n", "\n",  $_POST['v_ssl_crt']));
+                fwrite($fp, "\n");
+                fclose($fp);
+            }
+
+            // Key
+            if (!empty($_POST['v_ssl_key'])) {
+                $fp = fopen($tmpdir."/".$_POST['v_domain'].".key", 'w');
+                fwrite($fp, str_replace("\r\n", "\n", $_POST['v_ssl_key']));
+                fwrite($fp, "\n");
+                fclose($fp);
+            }
+
+            // CA
+            if (!empty($_POST['v_ssl_ca'])) {
+                $fp = fopen($tmpdir."/".$_POST['v_domain'].".ca", 'w');
+                fwrite($fp, str_replace("\r\n", "\n", $_POST['v_ssl_ca']));
+                fwrite($fp, "\n");
+                fclose($fp);
+            }
+
+            exec (HESTIA_CMD."v-change-mail-domain-sslcert ".$user." ".$v_domain." ".$tmpdir." 'no'", $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);
+            $restart_web = 'yes';
+            $restart_proxy = 'yes';
+
+            exec (HESTIA_CMD."v-list-mail-domain-ssl ".$user." '".$v_domain."' json", $output, $return_var);
+            $ssl_str = json_decode(implode('', $output), true);
+            unset($output);
+            $v_ssl_crt = $ssl_str[$v_domain]['CRT'];
+            $v_ssl_key = $ssl_str[$v_domain]['KEY'];
+            $v_ssl_ca = $ssl_str[$v_domain]['CA'];
+            $v_ssl_subject = $ssl_str[$v_domain]['SUBJECT'];
+            $v_ssl_aliases = $ssl_str[$v_domain]['ALIASES'];
+            $v_ssl_not_before = $ssl_str[$v_domain]['NOT_BEFORE'];
+            $v_ssl_not_after = $ssl_str[$v_domain]['NOT_AFTER'];
+            $v_ssl_signature = $ssl_str[$v_domain]['SIGNATURE'];
+            $v_ssl_pub_key = $ssl_str[$v_domain]['PUB_KEY'];
+            $v_ssl_issuer = $ssl_str[$v_domain]['ISSUER'];
+
+            // Cleanup certificate tempfiles
+            if (!empty($_POST['v_ssl_crt'])) unlink($tmpdir."/".$_POST['v_domain'].".crt");
+            if (!empty($_POST['v_ssl_key'])) unlink($tmpdir."/".$_POST['v_domain'].".key");
+            if (!empty($_POST['v_ssl_ca']))  unlink($tmpdir."/".$_POST['v_domain'].".ca");
+            rmdir($tmpdir);
+        }
+    }
+
+    // Delete Lets Encrypt support
+    if (( $v_letsencrypt == 'yes' ) && (empty($_POST['v_letsencrypt'])) && (empty($_SESSION['error_msg']))) {
+        exec (HESTIA_CMD."v-delete-letsencrypt-mail-domain ".$user." ".$v_domain." 'no'", $output, $return_var);
+        check_return_code($return_var,$output);
+        unset($output);
+        $v_ssl_crt = '';
+        $v_ssl_key = '';
+        $v_ssl_ca = '';
+        $v_letsencrypt = 'no';
+        $v_letsencrypt_deleted = 'yes';
+        $v_ssl = 'no';
+        $restart_mail = 'yes';
+    }
+
+    // Delete SSL certificate
+    if (( $v_ssl == 'yes' ) && (empty($_POST['v_ssl'])) && (empty($_SESSION['error_msg']))) {
+        exec (HESTIA_CMD."v-delete-mail-domain-ssl ".$v_username." ".$v_domain." 'no'", $output, $return_var);
+        check_return_code($return_var,$output);
+        unset($output);
+        $v_ssl_crt = '';
+        $v_ssl_key = '';
+        $v_ssl_ca = '';
+        $v_ssl = 'no';
+        $restart_mail = 'yes';
+    }
+
+    // Add Lets Encrypt support
+    if ((!empty($_POST['v_ssl'])) && ( $v_letsencrypt == 'no' ) && (!empty($_POST['v_letsencrypt'])) && empty($_SESSION['error_msg'])) {
+        $l_aliases = 'mail.' . $v_domain;
+        exec (HESTIA_CMD."v-add-letsencrypt-mail-domain ".$user." ".$v_domain." '".$l_aliases."' 'no'", $output, $return_var);
+        check_return_code($return_var,$output);
+        unset($output);
+        $v_letsencrypt = 'yes';
+        $v_ssl = 'yes';
+        $restart_mail = 'yes';
+     }
+
+     // Add SSL certificate
+     if (( $v_ssl == 'no' ) && (!empty($_POST['v_ssl']))  && (empty($v_letsencrypt_deleted)) && (empty($_SESSION['error_msg']))) {
+        if (empty($_POST['v_ssl_crt'])) $errors[] = 'ssl certificate';
+        if (empty($_POST['v_ssl_key'])) $errors[] = 'ssl key';
+        if (!empty($errors[0])) {
+            foreach ($errors as $i => $error) {
+                if ( $i == 0 ) {
+                    $error_msg = $error;
+                } else {
+                    $error_msg = $error_msg.", ".$error;
+                }
+            }
+            $_SESSION['error_msg'] = __('Field "%s" can not be blank.',$error_msg);
+        } else {
+            exec ('mktemp -d', $mktemp_output, $return_var);
+            $tmpdir = $mktemp_output[0];
+
+            // Certificate
+            if (!empty($_POST['v_ssl_crt'])) {
+                $fp = fopen($tmpdir."/".$_POST['v_domain'].".crt", 'w');
+                fwrite($fp, str_replace("\r\n", "\n", $_POST['v_ssl_crt']));
+                fclose($fp);
+            }
+
+            // Key
+            if (!empty($_POST['v_ssl_key'])) {
+                $fp = fopen($tmpdir."/".$_POST['v_domain'].".key", 'w');
+                fwrite($fp, str_replace("\r\n", "\n", $_POST['v_ssl_key']));
+                fclose($fp);
+            }
+
+            // CA
+            if (!empty($_POST['v_ssl_ca'])) {
+                $fp = fopen($tmpdir."/".$_POST['v_domain'].".ca", 'w');
+                fwrite($fp, str_replace("\r\n", "\n", $_POST['v_ssl_ca']));
+                fclose($fp);
+            }
+            exec (HESTIA_CMD."v-add-mail-domain-ssl ".$user." ".$v_domain." ".$tmpdir." 'no'", $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);
+            $v_ssl = 'yes';
+            $restart_web = 'yes';
+            $restart_proxy = 'yes';
+
+            exec (HESTIA_CMD."v-list-mail-domain-ssl ".$user." '".$v_domain."' json", $output, $return_var);
+            $ssl_str = json_decode(implode('', $output), true);
+            unset($output);
+            $v_ssl_crt = $ssl_str[$_POST['v_domain']]['CRT'];
+            $v_ssl_key = $ssl_str[$_POST['v_domain']]['KEY'];
+            $v_ssl_ca = $ssl_str[$_POST['v_domain']]['CA'];
+            $v_ssl_subject = $ssl_str[$_POST['v_domain']]['SUBJECT'];
+            $v_ssl_aliases = $ssl_str[$_POST['v_domain']]['ALIASES'];
+            $v_ssl_not_before = $ssl_str[$_POST['v_domain']]['NOT_BEFORE'];
+            $v_ssl_not_after = $ssl_str[$_POST['v_domain']]['NOT_AFTER'];
+            $v_ssl_signature = $ssl_str[$_POST['v_domain']]['SIGNATURE'];
+            $v_ssl_pub_key = $ssl_str[$_POST['v_domain']]['PUB_KEY'];
+            $v_ssl_issuer = $ssl_str[$_POST['v_domain']]['ISSUER'];
+
+            // Cleanup certificate tempfiles
+            if (!empty($_POST['v_ssl_crt'])) unlink($tmpdir."/".$_POST['v_domain'].".crt");
+            if (!empty($_POST['v_ssl_key'])) unlink($tmpdir."/".$_POST['v_domain'].".key");
+            if (!empty($_POST['v_ssl_ca'])) unlink($tmpdir."/".$_POST['v_domain'].".ca");
+            rmdir($tmpdir);
+        }
+    }
 
     // Set success message
     if (empty($_SESSION['error_msg'])) {

+ 115 - 0
web/templates/admin/edit_mail.html

@@ -81,6 +81,121 @@
                                     <label><input type="checkbox" size="20" class="vst-checkbox" name="v_dkim" <?php if ($v_dkim == 'yes') echo "checked=yes"; ?>> <?php print __('DKIM Support');?></label>
                                 </td>
                             </tr>
+                            <tr>
+                                <td class="vst-text step-top">
+                                    <label><input type="checkbox" size="20" class="vst-checkbox" name="v_ssl" <?php if ($v_ssl == 'yes') echo "checked=yes" ?> onclick="javascript:elementHideShow('ssltable');"> <?php print __('SSL Support');?></label>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td class="step-left">
+                                    <table style="display:<?php if ($v_ssl == 'no' ) { echo 'none';} else {echo 'block';}?> ;" id="ssltable">
+                                        <tr>
+                                            <td class="input-label vst-text">
+                                                <label><input type="checkbox" size="20" class="vst-checkbox" name="v_letsencrypt" <?php if($v_letsencrypt == 'yes' || $v_letencrypt == 'on') echo "checked=yes" ?> onclick="App.Actions.WEB.toggle_letsencrypt(this)"> <?php print __('Lets Encrypt Support');?></label>
+                                            </td>
+                                        </tr>
+                                      
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print __('SSL Certificate');?>
+                                                <span id="generate-csr"> / <a class="generate" target="_blank" href="/generate/ssl/?domain=<?=$v_domain?>"><?=__('Generate CSR')?></a></span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <textarea size="20" class="vst-textinput" name="v_ssl_crt"><?=htmlentities(trim($v_ssl_crt, "'"))?></textarea>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print __('SSL Key');?>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <textarea size="20" class="vst-textinput" name="v_ssl_key"><?=htmlentities(trim($v_ssl_key, "'"))?></textarea>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print __('SSL Certificate Authority / Intermediate');?> <span class="optional">(<?php print __('optional');?>)</span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <textarea size="20" class="vst-textinput" name="v_ssl_ca"><?=htmlentities(trim($v_ssl_ca, "'"))?></textarea>
+                                            </td>
+                                        </tr>
+                                        <?
+                                        if ($v_ssl != 'no' ) { ?>
+                                            <tr>
+                                                <td>
+                                                    <table class="additional-info">
+                                                        <tr>
+                                                            <td>
+                                                                <?=__('SUBJECT')?>:
+                                                            </td>
+                                                            <td class="details">
+                                                                <?=$v_ssl_subject?>
+                                                            </td>
+                                                        </tr>
+                                                        <? if($v_ssl_aliases){?>
+                                                            <tr>
+                                                                <td>
+                                                                    <?=__('ALIASES')?>:
+                                                                </td>
+                                                                <td class="details">
+                                                                    <?=$v_ssl_aliases?>
+                                                                </td>
+                                                            </tr>
+                                                        <? } ?>
+                                                        <tr>
+                                                            <td>
+                                                                <?=__('NOT_BEFORE')?>:
+                                                            </td>
+                                                            <td class="details">
+                                                                <?=$v_ssl_not_before?>
+                                                            </td>
+                                                        </tr>
+                                                        <tr>
+                                                            <td>
+                                                                <?=__('NOT_AFTER')?>:
+                                                            </td>
+                                                            <td class="details">
+                                                                <?=$v_ssl_not_after?>
+                                                            </td>
+                                                        </tr>
+                                                        <tr>
+                                                            <td>
+                                                                <?=__('SIGNATURE')?>:
+                                                            </td>
+                                                            <td class="details">
+                                                                <?=$v_ssl_signature?>
+                                                            </td>
+                                                        </tr>
+                                                        <tr>
+                                                            <td>
+                                                                <?=__('PUB_KEY')?>:
+                                                            </td>
+                                                            <td class="details">
+                                                                <?=$v_ssl_pub_key?>
+                                                            </td>
+                                                        </tr>
+                                                        <tr>
+                                                            <td>
+                                                                <?=__('ISSUER')?>
+                                                            </td>
+                                                            <td class="details">
+                                                                <?=$v_ssl_issuer?>
+                                                            </td>
+                                                        </tr>
+                                                    </table>
+                                                </td>
+                                            </tr>
+                                        <? } // if ssl is enabled ?>
+                                    </table>
+                                </td>
+                            </tr>
                         </table>
                         <table class="data-col2">
                             <tr>

+ 1 - 1
web/templates/admin/edit_mail_acc.html

@@ -205,7 +205,7 @@
                         </tr>
                         <?
                             list($http_host, $port) = explode(':', $_SERVER["HTTP_HOST"].":");
-                            $webmail = "http://".$http_host."/webmail/";
+                            $webmail = "http://mail.".$http_host."/";
                             if (!empty($_SESSION['MAIL_URL'])) $webmail = $_SESSION['MAIL_URL'];
                         ?>
                         <tr>

+ 26 - 8
web/templates/admin/list_mail.html

@@ -14,7 +14,7 @@
               <td class="step-right">
                 <?
                   list($http_host, $port) = explode(':', $_SERVER["HTTP_HOST"].":");
-                  $webmail = "http://".$http_host."/webmail/";
+                  $webmail = "http://mail.".$http_host."/";
                   if (!empty($_SESSION['MAIL_URL'])) $webmail = $_SESSION['MAIL_URL'];
                 ?>
                 <a class="vst" href="<?=$webmail?>" target="_blank"><?=__('open webmail')?> <i></i></a>
@@ -67,19 +67,21 @@
           
                 <div class="l-unit__col l-unit__col--right step-top table-header">
                   <div style="margin-bottom: 40px;">
-                      <div class="clearfix l-unit__stat-col--left wide-3"><b><?php print __('Domain');?></b></div>
-                      <div class="clearfix l-unit__stat-col--left text-center"><b><?php print __('Accounts');?></b></div>
-                      <div class="clearfix l-unit__stat-col--left text-center"><b><?php print __('Disk');?></b></div>
+                      <div class="clearfix l-unit__stat-col--left wide-2"><b><?php print __('Domain');?></b></div>
+                      <div class="clearfix l-unit__stat-col--left text-center compact"><b><?php print __('Accounts');?></b></div>
+                      <div class="clearfix l-unit__stat-col--left text-center compact"><b><?php print __('Disk');?></b></div>
+                      <div class="clearfix l-unit__stat-col--left text-center compact-3"><b><?php print __('Webmail');?></b></div>
                       <div class="clearfix l-unit__stat-col--left text-center compact-3"><b><?php print __('Antivirus');?></b></div>
                       <div class="clearfix l-unit__stat-col--left text-center compact-3"><b><?php print __('AntiSpam');?></b></div>
                       <div class="clearfix l-unit__stat-col--left text-center compact-3"><b><?php print __('DKIM');?></b></div>
+                      <div class="clearfix l-unit__stat-col--left text-center compact-3"><b><?php print __('SSL');?></b></div>
                   </div>
                 </div>
               </div>
 
       <?
         list($http_host, $port) = explode(':', $_SERVER["HTTP_HOST"].":");
-        $webmail = "http://".$http_host."/webmail/";
+        $webmail = "http://mail.".$http_host."/";
         if (!empty($_SESSION['MAIL_URL'])) $webmail = $_SESSION['MAIL_URL'];
 
         foreach ($data as $key => $value) {
@@ -144,17 +146,25 @@ sort-accounts="<?=$data[$key]['ACCOUNTS']?>" sort-star="<? if($_SESSION['favouri
                       <input id="check<?php echo $i ?>" class="ch-toggle" type="checkbox" name="domain[]" value="<?php echo $key ?>">
                       <label for="check<?php echo $i ?>" class="check-label"></label>
                     </div>
-                  <div class="clearfix l-unit__stat-col--left wide-3"><b><?=$key?></b></div>
-                  <div class="clearfix l-unit__stat-col--left text-center"><b>
+                  <div class="clearfix l-unit__stat-col--left wide-2"><b><?=$key?></b></div>
+                  <div class="clearfix l-unit__stat-col--left text-center compact"><b>
                     <? if($data[$key]['ACCOUNTS']) { echo '<span>'.$data[$key]['ACCOUNTS'].'</span>'; ?>
                     <? } else {?>
                       <span>0</span>
                     <? } ?>
                     </b>
                   </div>
-                  <div class="clearfix l-unit__stat-col--left text-center"><b>
+                  <div class="clearfix l-unit__stat-col--left text-center compact"><b>
                     <?=humanize_usage_size($data[$key]['U_DISK'])?></b> <span class="text-small"><?=humanize_usage_measure($data[$key]['U_DISK'])?></span>
                   </div>
+                  <div class="clearfix l-unit__stat-col--left text-center compact-3"><b>
+                    <? if($data[$key]['WEBMAIL'] == 'no'){ ?>
+                      <i class="fas fa-minus-circle"></i>
+                    <? } else {?>
+                      <i class="fas fa-check-circle status-icon-green"></i>
+                    <? } ?>
+                  </b>
+                 </div>
                   <div class="clearfix l-unit__stat-col--left text-center compact-3"><b>
                       <? if($data[$key]['ANTIVIRUS'] == 'no'){ ?>
                         <i class="fas fa-times-circle" style="color: red;"></i>
@@ -179,6 +189,14 @@ sort-accounts="<?=$data[$key]['ACCOUNTS']?>" sort-star="<? if($_SESSION['favouri
                       <? } ?>
                     </b>
                   </div>
+                  <div class="clearfix l-unit__stat-col--left text-center compact-3"><b>
+                      <? if($data[$key]['SSL'] == 'no'){ ?>
+                        <i class="fas fa-times-circle" style="color: red;"></i>
+                      <? } else {?>
+                        <i class="fas fa-check-circle status-icon-green"></i>
+                      <? } ?>
+                    </b>
+                  </div>
               </div>
             </div>
         <!-- /.l-unit__col -->

+ 3 - 0
web/templates/admin/list_mail_acc.html

@@ -56,6 +56,9 @@
     <div class="l-separator"></div>
     <!-- /.l-separator -->
     <div class="l-center units animated fadeIn">
+        <div class="l-unit header">
+            <div class="subtitle"><?=__('Listing')?>  <?=htmlentities($_GET['domain'])?></div>
+        </div>
         <div class="l-unit header">
             <div class="l-unit__col l-unit__col--left clearfix">
               <div class="text-center jump-small-top"></div>