Просмотр исходного кода

Enable / Disable via WebGUI
Disable API with die() instead removing it as update would enable api again.
Minor bug fixes in edit/config

Jaap Marcus 5 лет назад
Родитель
Сommit
6b897d2fd3

+ 56 - 0
bin/v-change-sys-api

@@ -0,0 +1,56 @@
+#!/bin/bash
+# info: Enable / Disable API access 
+# options: STATUS 
+# labels: hestia
+#
+# example: v-change-sys-api enable
+#          # Enable API
+#
+# example: v-change-sys-api disable
+#          # Disable API
+#
+# Enabled / Disable API
+
+
+status=$1
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/conf/hestia.conf
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+check_args '1' "$#" "STATUS"
+is_type_valid "enable,disable" "$status"
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+if [ "$status" = "enable" ]; then
+    if [ $API = "no" ]; then
+        if [ ! -f "$HESTIA/web/api/index.php" ]; then
+            wget -q https://raw.githubusercontent.com/hestiacp/hestiacp/release/web/api/index.php -O $HESTIA/web/api/index.php
+        else
+            sed -i 's|die("Error: Disabled");|//die("Error: Disabled");|g' $HESTIA/web/api/index.php
+        fi
+        $HESTIA/bin/v-change-sys-config-value "API" "yes"
+    fi
+else
+    if [ $API = "yes" ]; then
+        $HESTIA/bin/v-change-sys-config-value "API" "no"
+        sed -i 's|//die("Error: Disabled");|die("Error: Disabled");|g' $HESTIA/web/api/index.php
+    fi
+fi
+
+#----------------------------------------------------------#
+#                       Logging                            #
+#----------------------------------------------------------#
+
+log_history "API status has been changed to $status" '' 'admin'
+log_event "$OK" "$ARGUMENTS"

+ 13 - 3
bin/v-list-sys-config

@@ -68,7 +68,9 @@ json_list() {
         "LOGIN_STYLE": "'$LOGIN_STYLE'",
         "INACTIVE_SESSION_TIMEOUT": "'$INACTIVE_SESSION_TIMEOUT'",
         "PHPMYADMIN_KEY": "'$PHPMYADMIN_KEY'",
-        "ENFORCE_SUBDOMAIN_OWNERSHIP": "'$ENFORCE_SUBDOMAIN_OWNERSHIP'"
+        "ENFORCE_SUBDOMAIN_OWNERSHIP": "'$ENFORCE_SUBDOMAIN_OWNERSHIP'",
+        "API": "'$API'",
+        "API_ALLOWED_IP": "'$API_ALLOWED_IP'"
     }
     }'
 }
@@ -151,6 +153,12 @@ shell_list() {
     if [ ! -z "$FILE_MANAGER" ]; then
         echo "File Manager enabled:             $FILE_MANAGER"
     fi
+    if [ ! -z "$API" ]; then
+    echo "API enabled:             $API"
+    echo "Allowed IPS:             $API_ALLOWED_IP"
+    
+    fi
+    
     if [ ! -z "$SMTP_RELAY" ] && [ "$SMTP_RELAY" != 'false' ]; then
 	echo "SMTP Relay enabled:                $SMTP_RELAY"
 	echo "SMTP Relay Server:                 $SMTP_RELAY_HOST"
@@ -175,7 +183,7 @@ plain_list() {
     echo -ne "$FILE_MANAGER\t$REPOSITORY\t$VERSION\t$DEMO_MODE\t$RELEASE_BRANCH\t"
     echo -ne "$SMTP_RELAY_HOST\t$SMTP_RELAY_PORT\t$SMTP_RELAY_USER\t"
     echo -ne "$UPGRADE_SEND_EMAIL\t$UPGRADE_SEND_EMAIL_LOG\t$THEME\t$LANGUAGE\t$BACKUP_GZIP\t"
-    echo -e  "$BACKUP\t$WEBMAIL_ALIAS\t$DB_PMA_URL\t$DB_PGA_URL"
+    echo -e  "$BACKUP\t$WEBMAIL_ALIAS\t$DB_PMA_URL\t$DB_PGA_URL\t$API\t$API_ALLOWED_IP"
 }
 
 
@@ -192,7 +200,7 @@ csv_list() {
     echo -n "'SMTP_RELAY','SMTP_RELAY_HOST','SMTP_RELAY_PORT','SMTP_RELAY_USER',"
     echo -n "'UPGRADE_SEND_EMAIL','UPGRADE_SEND_EMAIL_LOG',"
     echo -n "'THEME', 'LANGUAGE','BACKUP_GZIP','BACKUP','WEBMAIL_ALIAS',"
-    echo -n "'DB_PMA_ALIAS','DB_PGA_ALIAS'"
+    echo -n "'DB_PMA_ALIAS','DB_PGA_ALIAS','API','API_ALLOWED_IP'"
     echo
     echo -n "'$WEB_SYSTEM','$WEB_RGROUPS','$WEB_PORT','$WEB_SSL',"
     echo -n "'$WEB_SSL_PORT','$WEB_BACKEND','$PROXY_SYSTEM','$PROXY_PORT',"
@@ -204,6 +212,8 @@ csv_list() {
     echo -n "'$SMTP_RELAY','$SMTP_RELAY_HOST','$SMTP_RELAY_PORT','$SMTP_RELAY_USER',"
     echo -n "'$UPGRADE_SEND_EMAIL','$UPGRADE_SEND_EMAIL_LOG','$THEME','$LANGUAGE',"
     echo -n "'$BACKUP_GZIP','$BACKUP','$WEBMAIL_ALIAS','$DB_PMA_URL','$DB_PGA_URL'"
+    echo -n "'$API','$API_ALLOWED_IP'"
+    
     echo
 }
 

+ 11 - 1
func/upgrade.sh

@@ -144,11 +144,16 @@ upgrade_health_check() {
         $BIN/v-change-sys-config-value "INACTIVE_SESSION_TIMEOUT" "60"
     fi
 
-    # Inactive session timeout
+    # Enforce Subdomain ownership
     if [ -z "$ENFORCE_SUBDOMAIN_OWNERSHIP" ]; then
         echo "[ ! ] Adding missing variable to hestia.conf: ENFORCE_SUBDOMAIN_OWNERSHIP ('yes')"
         $BIN/v-change-sys-config-value "ENFORCE_SUBDOMAIN_OWNERSHIP" "yes"
     fi    
+    # API Allowed IP
+    if [ -z "$API_ALLOWED_IP" ]; then
+        echo "[ ! ] Adding missing variable to hestia.conf: API_ALLOWED_IP ('')"        
+        $BIN/v-change-sys-config-value "API_ALLOWED_IP" "127.0.0.1"
+    fi  
     
     echo "[ * ] Health check complete. Starting upgrade from $VERSION to $new_version..."
     echo "============================================================================="
@@ -669,6 +674,11 @@ upgrade_rainloop(){
     fi
 }
 
+disable_api(){
+    if [ "API" = "no" ]; then
+        sed -i 's|//die("Error: Disabled");|die("Error: Disabled");|g' $HESTIA/web/api/index.php
+    fi
+}
 upgrade_rebuild_web_templates() {
     if [ "$UPGRADE_UPDATE_WEB_TEMPLATES" = "true" ]; then
         echo "[ ! ] Updating default web domain templates..."

+ 4 - 6
install/hst-install-debian.sh

@@ -1641,13 +1641,11 @@ fi
 #                       Configure API                      #
 #----------------------------------------------------------#
 
-if [ "$api" = 'yes' ]; then
-    echo "API='yes'" >> $HESTIA/conf/hestia.conf
-else
-    rm -r $HESTIA/web/api
-    echo "API='no'" >> $HESTIA/conf/hestia.conf
+echo "API='yes'" >> $HESTIA/conf/hestia.conf
+if [ "$api" != "yes" ]; then
+    $HESTIA/bin/v-change-sys-api disable
 fi
-
+echo "API_ALLOWED_IP='127.0.0.1'" >> $HESTIA/conf/hestia.conf
 
 #----------------------------------------------------------#
 #                   Configure Admin User                   #

+ 4 - 6
install/hst-install-ubuntu.sh

@@ -1666,13 +1666,11 @@ fi
 #                       Configure API                      #
 #----------------------------------------------------------#
 
-if [ "$api" = 'yes' ]; then
-    echo "API='yes'" >> $HESTIA/conf/hestia.conf
-else
-    rm -r $HESTIA/web/api
-    echo "API='no'" >> $HESTIA/conf/hestia.conf
+echo "API='yes'" >> $HESTIA/conf/hestia.conf
+if [ "$api" != "yes" ]; then
+    $HESTIA/bin/v-change-sys-api disable
 fi
-
+echo "API_ALLOWED_IP='127.0.0.1'" >> $HESTIA/conf/hestia.conf
 
 #----------------------------------------------------------#
 #                   Configure Admin User                   #

+ 2 - 0
src/deb/hestia/postinst

@@ -72,6 +72,8 @@ upgrade_roundcube | tee -a $LOG
 # Upgrade Rainloop if applicable
 upgrade_rainloop | tee -a $LOG
 
+# Check disabled API
+disable_api | tee -a $LOG
 # Set new version number in hestia.conf
 upgrade_set_version $new_version
 

+ 30 - 5
web/api/index.php

@@ -1,5 +1,6 @@
 <?php
 define('HESTIA_CMD', '/usr/bin/sudo /usr/local/hestia/bin/');
+//die("Error: Disabled");
 
 function get_real_user_ip(){
     $ip = $_SERVER['REMOTE_ADDR'];
@@ -7,26 +8,50 @@ function get_real_user_ip(){
         $ip = $_SERVER['HTTP_CLIENT_IP'];
     }
     if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
-        $ip =  $_SERVER['HTTP_X_FORWARDED_FOR'];
+        if (filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP)){
+            $ip =  $_SERVER['HTTP_X_FORWARDED_FOR'];
+        }
     }
     if(isset($_SERVER['HTTP_FORWARDED_FOR'])){
-        $ip = $_SERVER['HTTP_FORWARDED_FOR'];
+        if (filter_var($_SERVER['HTTP_FORWARDED_FOR'], FILTER_VALIDATE_IP)){
+            $ip =  $_SERVER['HTTP_FORWARDED_FOR'];
+        }
     }
     if(isset($_SERVER['HTTP_X_FORWARDED'])){
-        $ip = $_SERVER['HTTP_X_FORWARDED'];
+        if (filter_var($_SERVER['HTTP_X_FORWARDED'], FILTER_VALIDATE_IP)){
+            $ip =  $_SERVER['HTTP_X_FORWARDED'];
+        }
     }
     if(isset($_SERVER['HTTP_FORWARDED'])){
-        $ip = $_SERVER['HTTP_FORWARDED'];
+        if (filter_var($_SERVER['HTTP_FORWARDED'], FILTER_VALIDATE_IP)){
+            $ip =  $_SERVER['HTTP_FORWARDED'];
+        }
     }
     if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])){
         if(!empty($_SERVER['HTTP_CF_CONNECTING_IP'])){
-            $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
+            if (filter_var($_SERVER['HTTP_FORWARDED'], FILTER_VALIDATE_IP)){
+                $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
+            }
         }
     }
     return $ip;
 }
 
 function api($hst_hash, $hst_user, $hst_password, $hst_returncode, $hst_cmd, $hst_arg1, $hst_arg2, $hst_arg3, $hst_arg4, $hst_arg5, $hst_arg6, $hst_arg7, $hst_arg8, $hst_arg9){
+    exec (HESTIA_CMD."v-list-sys-config json" , $output, $return_var);
+    $settings = json_decode(implode('', $output), true);
+    unset($output);
+    if( $settings['config']['API'] != 'yes' ){
+        echo 'Error: authentication failed';
+        exit;
+    }
+    if ( $settings['config']['API_ALLOWED_IP'] != '' ){
+        $ip_list = explode(',',$settings['config']['API_ALLOWED_IP']);
+        if ( !in_array(get_real_user_ip(), $ip_list)){
+           echo 'Error: authentication failed';
+           exit; 
+        }
+    }
     //This exists, so native JSON can be used without the repeating the code twice, so future code changes are easier and don't need to be replicated twice
     // Authentication
     if (empty($hst_hash)) {

+ 36 - 5
web/edit/server/index.php

@@ -432,7 +432,8 @@ if (!empty($_POST['save'])) {
 
     // Update send notification setting
     if (empty($_SESSION['error_msg'])) {
-        if ($_POST['v_upgrade_send_notification_email'] != $_SESSION['UPGRADE_SEND_EMAIL']) {
+        if ( $_SESSION['UPGRADE_SEND_EMAIL'] == 'true' ){ $ugrade_send_mail = 'on'; }else{ $ugrade_send_mail = ''; }
+        if ( $_POST['v_upgrade_send_notification_email'] != $ugrade_send_mail ) {
             if ($_POST['v_upgrade_send_notification_email'] == 'on') { $_POST['v_upgrade_send_notification_email'] = 'true'; } else { $_POST['v_upgrade_send_notification_email'] = 'false'; }
             exec (HESTIA_CMD."v-change-sys-config-value UPGRADE_SEND_EMAIL ".escapeshellarg($_POST['v_upgrade_send_notification_email']), $output, $return_var);
             check_return_code($return_var,$output);
@@ -443,7 +444,8 @@ if (!empty($_POST['save'])) {
 
     // Update send log by email setting
     if (empty($_SESSION['error_msg'])) {
-        if ($_POST['v_upgrade_send_email_log'] != $_SESSION['UPGRADE_SEND_EMAIL_LOG']) {
+        if ( $_SESSION['UPGRADE_SEND_EMAIL_LOG'] == 'true' ){ $send_email_log = 'on'; }else{ $send_email_log = ''; }
+        if ( $_POST['v_upgrade_send_email_log'] != $send_email_log ) {
             if ($_POST['v_upgrade_send_email_log'] == 'on') { $_POST['v_upgrade_send_email_log'] = 'true'; } else { $_POST['v_upgrade_send_email_log'] = 'false'; }
             exec (HESTIA_CMD."v-change-sys-config-value UPGRADE_SEND_EMAIL_LOG ".escapeshellarg($_POST['v_upgrade_send_email_log']), $output, $return_var);
             check_return_code($return_var,$output);
@@ -515,7 +517,7 @@ if (!empty($_POST['save'])) {
             unset($output);
             */
             if (empty($_SESSION['error_msg'])) $v_backup_dir = $_POST['v_backup_dir'];
-            $v_backup_adv = 'yes';
+            #$v_backup_adv = 'yes';
         }
     }
     
@@ -673,7 +675,7 @@ if (!empty($_POST['save'])) {
     
     // Change ENFORCE_SUBDOMAIN_OWNERSHIP
     if (empty($_SESSION['error_msg'])) {
-        if ($_POST['v_enforce_subdomain_ownership'] != $_SESSION['v_enforce_subdomain_ownership']) {
+        if ($_POST['v_enforce_subdomain_ownership'] != $_SESSION['ENFORCE_SUBDOMAIN_OWNERSHIP']) {
             exec (HESTIA_CMD."v-change-sys-config-value ENFORCE_SUBDOMAIN_OWNERSHIP ".escapeshellarg($_POST['v_enforce_subdomain_ownership']), $output, $return_var);
             check_return_code($return_var,$output);
             unset($output);
@@ -692,7 +694,36 @@ if (!empty($_POST['save'])) {
             $v_security_adv = 'yes';
         }
     }
-
+    if (empty($_SESSION['error_msg'])) {
+        if ($_POST['v_api'] != $_SESSION['API']) {
+            $api_status = 'disable';
+            if ($_POST['v_api'] == 'yes'){
+                $api_status = 'enable';
+            }
+            exec (HESTIA_CMD."v-change-sys-api ".escapeshellarg($api_status), $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);
+            if (empty($_SESSION['error_msg'])) $v_login_style = $_POST['v_api'];
+            $v_security_adv = 'yes';
+        }
+    }
+    if (empty($_SESSION['error_msg'])) {
+        if ($_POST['v_api_allowed_ip'] != $_SESSION['API_ALLOWED_IP']) {
+            $ips = array();
+            foreach(explode("\n",$_POST['v_api_allowed_ip']) as $ip){ 
+                if(filter_var(trim($ip), FILTER_VALIDATE_IP)){
+                    $ips[] = trim($ip);
+                }
+            }
+            if(implode(',',$ips) != $_SESSION['API_ALLOWED_IP']){
+            exec (HESTIA_CMD."v-change-sys-config-value API_ALLOWED_IP ".escapeshellarg(implode(',',$ips)), $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);
+            if (empty($_SESSION['error_msg'])) $v_login_style = $_POST['v_api_allowed_ip'];
+                $v_security_adv = 'yes';
+            }
+        }
+    }
     // Update SSL certificate
     if ((!empty($_POST['v_ssl_crt'])) && (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']))) {

+ 31 - 2
web/templates/admin/edit_server.html

@@ -669,7 +669,7 @@
                             </tr>
                             <tr>
                                 <td class="vst-text input-label step-left">
-                                    <table style="display:<?php if (empty($v_backup_adv)) echo 'none';?> ;" id="backup">
+                                    <table style="<?php if (empty($v_backup_adv)) echo 'display:none';?> ;" id="backup">
                                         <tr>
                                             <td class="vst-text">
                                                 <?php print _('Local backup') ?>
@@ -964,7 +964,36 @@
                             </tr>
                             <tr>
                                 <td class="vst-text input-label step-left">
-                                    <table style="display:<?php if (empty($v_security_adv)) echo 'none';?> ;" id="security">
+                                    <table style="<?php if (empty($v_security_adv)) echo 'display:none';?> ;" id="security">
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print _('Enable API access');?>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <select class="vst-list" name="v_api">
+                                                    <option value='yes'><?php print _('yes'); ?></option>
+                                                    <option value='no' <?php if($_SESSION['API'] == 'no') echo 'selected' ?> ><?php print _('no'); ?></option>
+                                                </select>
+                                                <br><br>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print _('Allowed IP Addresses for API');?> <span class="optional" style="float:right">1 IP address per line</span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <textarea size="20" class="vst-textinput" name="v_api_allowed_ip"><?php 
+                                                    foreach(explode(',',$_SESSION['API_ALLOWED_IP']) as $ip ){
+                                                        echo $ip."\n";
+                                                    }
+                                                    ?></textarea>
+                                                <br><br>
+                                            </td>
+                                        </tr>
                                         <tr>
                                             <td class="vst-text input-label">
                                                 <?php print _('Login screen style');?>