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

Minor fixes (#2199)

* Add rate limit to forget password

Max 1 email / 15 min / user same time length as key remains valid

* Optional download generated SSL certificates / keys 

Closes #2181

* Block access to .xxxx files (Exception for .well-know 

Same rules as PHP-FPM templates!

* Fix #2177 List available php version detection wrong

Closes #2177

* Update permissions RC log

#2173

* Update web/js/pages/list_ssl.js

Co-authored-by: Wojciech Smoliński <wojsmol@wp.pl>

* Add support for B2 download

Co-authored-by: Wojciech Smoliński <wojsmol@wp.pl>
Jaap Marcus 4 лет назад
Родитель
Сommit
9e337987bd

+ 1 - 1
bin/v-add-sys-roundcube

@@ -132,7 +132,7 @@ if [ "$UPDATE" == "no" ]; then
     if [ ! -d  $RC_LOG ];then
         mkdir $RC_LOG
     fi
-    chown www-data:root $RC_LOG
+    chown www-data:www-data $RC_LOG
     chmod 751 $RC_LOG
     
     if [ ! -z "$(echo "$DB_SYSTEM" | grep -w 'mysql')" ]; then

+ 1 - 1
bin/v-get-user-value

@@ -14,7 +14,7 @@
 
 # Argument definition
 user=$1
-key=$(echo "$2"| tr '[:lower:]' '[:upper:]' | sed "s/^/$/")
+key=$(echo "$2"| tr '[:lower:]' '[:upper:]')
 
 # Includes
 # shellcheck source=/etc/hestiacp/hestia.conf

+ 1 - 2
bin/v-restart-web-backend

@@ -50,9 +50,8 @@ if [ "$1" = 'scheduled' ] || [ -z "$1" ] && [ "$SCHEDULED_RESTART" = 'yes' ]; th
 fi
 
 tmpfile=$(mktemp)
-php_versions=$(ls /usr/sbin/php*fpm* | cut -d'/' -f4 | sed 's|php-fpm||')
 # Substitute php-fpm service name formats
-for version in $php_versions; do
+for version in $($BIN/v-list-sys-php plain); do
     v_php="php$version-fpm"
     if [ ! -f "/etc/php/${version}/fpm/pool.d/dummy.conf" ]; then
         cp -f "$HESTIA_INSTALL_DIR/php-fpm/dummy.conf" "/etc/php/${version}/fpm/pool.d/"

+ 8 - 0
bin/v-restore-user

@@ -85,11 +85,19 @@ if [ ! -e "$BACKUP/$backup" ]; then
         ftp_download "$backup"
         downloaded='yes'
     fi
+    if [[ "$BACKUP_SYSTEM" =~ "b2" ]] && [ -z "$downloaded" ]; then
+        b2_download "$backup"
+        downloaded='yes'
+    fi
     if [ -z "$downloaded" ]; then
         check_result "$E_NOTEXIST" "backup file $backup doesn't exist in '${BACKUP}' folder"
     fi
 fi
 
+if [ ! -e "$BACKUP/$backup" ]; then 
+   check_result "$E_NOTEXIST" "backup file $backup doesn't exist in '${BACKUP}' folder"
+fi 
+
 # Checking user existence on the server
 check_user=$(is_object_valid 'user' 'USER' "$user")
 if [ -z "$check_user" ]; then

+ 14 - 0
func/backup.sh

@@ -459,3 +459,17 @@ b2_backup() {
         done
     fi
 }
+
+b2_download() {
+    # Defining backblaze b2 settings
+    source_conf "$HESTIA/conf/b2.backup.conf"
+
+    # Recreate backblaze auth file ~/.b2_account_info (for situation when key was changed in b2.backup.conf)
+    b2 clear-account > /dev/null 2>&1
+    b2 authorize-account $B2_KEYID $B2_KEY > /dev/null 2>&1
+    cd $BACKUP
+    b2 download-file-by-name $BUCKET $user/$1 $1 > /dev/null 2>&1
+    if [ "$?" -ne 0 ]; then
+    check_result "$E_CONNECT" "b2 failed to download $user.$1"
+    fi
+}

+ 4 - 5
install/deb/templates/web/nginx/caching.stpl

@@ -53,11 +53,10 @@ server {
         proxy_pass      https://%ip%:%web_ssl_port%;
     }
 
-    location ~ /\.ht    {return 404;}
-    location ~ /\.svn/  {return 404;}
-    location ~ /\.git/  {return 404;}
-    location ~ /\.hg/   {return 404;}
-    location ~ /\.bzr/  {return 404;}
+    location ~ /\.(?!well-known\/) { 
+       deny all; 
+       return 404;
+    }
 
     proxy_hide_header Upgrade;
 

+ 4 - 5
install/deb/templates/web/nginx/caching.tpl

@@ -48,11 +48,10 @@ server {
         proxy_pass      http://%ip%:%web_port%;
     }
 
-    location ~ /\.ht    {return 404;}
-    location ~ /\.svn/  {return 404;}
-    location ~ /\.git/  {return 404;}
-    location ~ /\.hg/   {return 404;}
-    location ~ /\.bzr/  {return 404;}
+    location ~ /\.(?!well-known\/) { 
+       deny all; 
+       return 404;
+    }
 
     include %home%/%user%/conf/web/%domain%/nginx.conf_*;
 }

+ 4 - 5
install/deb/templates/web/nginx/default.stpl

@@ -33,11 +33,10 @@ server {
         proxy_pass      https://%ip%:%web_ssl_port%;
     }
 
-    location ~ /\.ht    {return 404;}
-    location ~ /\.svn/  {return 404;}
-    location ~ /\.git/  {return 404;}
-    location ~ /\.hg/   {return 404;}
-    location ~ /\.bzr/  {return 404;}
+    location ~ /\.(?!well-known\/) { 
+       deny all; 
+       return 404;
+    }
 
     proxy_hide_header Upgrade;
 

+ 4 - 5
install/deb/templates/web/nginx/default.tpl

@@ -28,11 +28,10 @@ server {
         proxy_pass      http://%ip%:%web_port%;
     }
 
-    location ~ /\.ht    {return 404;}
-    location ~ /\.svn/  {return 404;}
-    location ~ /\.git/  {return 404;}
-    location ~ /\.hg/   {return 404;}
-    location ~ /\.bzr/  {return 404;}
+    location ~ /\.(?!well-known\/) { 
+       deny all; 
+       return 404;
+    }
 
     include %home%/%user%/conf/web/%domain%/nginx.conf_*;
 }

+ 4 - 5
install/deb/templates/web/nginx/hosting.stpl

@@ -33,11 +33,10 @@ server {
         proxy_pass      https://%ip%:%web_ssl_port%;
     }
 
-    location ~ /\.ht    {return 404;}
-    location ~ /\.svn/  {return 404;}
-    location ~ /\.git/  {return 404;}
-    location ~ /\.hg/   {return 404;}
-    location ~ /\.bzr/  {return 404;}
+    location ~ /\.(?!well-known\/) { 
+       deny all; 
+       return 404;
+    }
 
     disable_symlinks if_not_owner from=%docroot%;
 

+ 4 - 5
install/deb/templates/web/nginx/hosting.tpl

@@ -28,11 +28,10 @@ server {
         proxy_pass      http://%ip%:%web_port%;
     }
 
-    location ~ /\.ht    {return 404;}
-    location ~ /\.svn/  {return 404;}
-    location ~ /\.git/  {return 404;}
-    location ~ /\.hg/   {return 404;}
-    location ~ /\.bzr/  {return 404;}
+    location ~ /\.(?!well-known\/) { 
+       deny all; 
+       return 404;
+    }
 
     disable_symlinks if_not_owner from=%docroot%;
 

+ 5 - 0
install/upgrade/versions/1.4.18.sh

@@ -42,4 +42,9 @@ if [ -L "/var/log/hestia" ]; then
     cp $HESTIA/log/* /var/log/hestia
     rm -rf $HESTIA/log/
    ln -s /var/log/hestia $HESTIA/log
+fi
+
+if [ -d "/var/log/roundcube" ]; then 
+   chown www-data:root /var/log/roundcube
+   chmod 751 /var/log/roundcube
 fi

+ 30 - 0
web/js/pages/list_ssl.js

@@ -0,0 +1,30 @@
+function saveTextToBlob ( file, element ){
+    text = document.getElementById(element).value;
+    var textFileAsBlob = new Blob([text], {type:'text/plain'}); 
+    var downloadLink = document.createElement("a");
+    downloadLink.download = file;
+    downloadLink.innerHTML = "Download File";
+    if (window.webkitURL != null)
+    {
+        // Chrome allows the link to be clicked
+        // without actually adding it to the DOM.
+        downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
+    }
+    else
+    {
+        // Firefox requires the link to be added to the DOM
+        // before it can be clicked.
+        downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
+        downloadLink.onclick = destroyClickedElement;
+        downloadLink.style.display = "none";
+        document.body.appendChild(downloadLink);
+    }
+
+    downloadLink.click();
+    return false;
+}
+
+function destroyClickedElement(event)
+{
+    document.body.removeChild(event.target);
+}

+ 37 - 30
web/reset/index.php

@@ -26,38 +26,45 @@ if ((!empty($_POST['user'])) && (empty($_POST['code']))) {
     exec($cmd." ".$v_user." json", $output, $return_var);
     if ($return_var == 0) {
         $data = json_decode(implode('', $output), true);
-        if ($email == $data[$user]['CONTACT']) {
-            $rkey = substr(password_hash("", PASSWORD_DEFAULT), 8, 12);
-            $hash = password_hash($rkey, PASSWORD_DEFAULT);
-            $v_rkey = tempnam("/tmp", "vst");
-            $fp = fopen($v_rkey, "w");
-            fwrite($fp, $hash."\n");
-            fclose($fp);
-            exec(HESTIA_CMD . "v-change-user-rkey ".$v_user." ".$v_rkey."", $output, $return_var);
-            unset($output);
-            unlink($v_rkey);
-            $name = $data[$user]['NAME'];
-            $contact = $data[$user]['CONTACT'];
-            $to = $data[$user]['CONTACT'];
-            $subject = sprintf(_('MAIL_RESET_SUBJECT'), date("Y-m-d H:i:s"));
-            $hostname = exec('hostname');
-            $from = "noreply@".$hostname;
-            $from_name = _('Hestia Control Panel');
-            if (!empty($name)) {
-                $mailtext = sprintf(_('GREETINGS_GORDON'), $name);
-            } else {
-                $mailtext = _('GREETINGS');
-            }
-            if (in_array(str_replace(':'.$_SERVER['SERVER_PORT'], '.conf', $_SERVER['HTTP_HOST']), array_merge(scandir('/etc/nginx/conf.d'), scandir('/etc/nginx/conf.d/domains'), scandir('/etc/apache2/conf.d/domains'), scandir('/etc/apache2/conf.d')))) {
-                $mailtext .= sprintf(_('PASSWORD_RESET_REQUEST'), $_SERVER['HTTP_HOST'], $user, $rkey, $_SERVER['HTTP_HOST'], $user, $rkey);
-                if (!empty($rkey)) {
-                    send_email($to, $subject, $mailtext, $from, $from_name, $data[$user]['NAME']);
+        unset($output);
+        exec(HESTIA_CMD . "v-get-user-value ".$v_user." RKEYEXP", $output, $return_var);
+        $rkeyexp = json_decode(implode('', $output), true);
+        if ($rkeyexp === null || $rkeyexp < time() - 900) {
+            if ($email == $data[$user]['CONTACT']) {
+                $rkey = substr(password_hash("", PASSWORD_DEFAULT), 8, 12);
+                $hash = password_hash($rkey, PASSWORD_DEFAULT);
+                $v_rkey = tempnam("/tmp", "vst");
+                $fp = fopen($v_rkey, "w");
+                fwrite($fp, $hash."\n");
+                fclose($fp);
+                exec(HESTIA_CMD . "v-change-user-rkey ".$v_user." ".$v_rkey."", $output, $return_var);
+                unset($output);
+                unlink($v_rkey);
+                $name = $data[$user]['NAME'];
+                $contact = $data[$user]['CONTACT'];
+                $to = $data[$user]['CONTACT'];
+                $subject = sprintf(_('MAIL_RESET_SUBJECT'), date("Y-m-d H:i:s"));
+                $hostname = exec('hostname');
+                $from = "noreply@".$hostname;
+                $from_name = _('Hestia Control Panel');
+                if (!empty($name)) {
+                    $mailtext = sprintf(_('GREETINGS_GORDON'), $name);
+                } else {
+                    $mailtext = _('GREETINGS');
+                }
+                if (in_array(str_replace(':'.$_SERVER['SERVER_PORT'], '.conf', $_SERVER['HTTP_HOST']), array_merge(scandir('/etc/nginx/conf.d'), scandir('/etc/nginx/conf.d/domains'), scandir('/etc/apache2/conf.d/domains'), scandir('/etc/apache2/conf.d')))) {
+                    $mailtext .= sprintf(_('PASSWORD_RESET_REQUEST'), $_SERVER['HTTP_HOST'], $user, $rkey, $_SERVER['HTTP_HOST'], $user, $rkey);
+                    if (!empty($rkey)) {
+                        send_email($to, $subject, $mailtext, $from, $from_name, $data[$user]['NAME']);
+                    }
+                    header("Location: /reset/?action=code&user=".$_POST['user']);
+                    exit;
+                } else {
+                    $ERROR = "<a class=\"error\">"._('Invalid host domain')."</a>";
                 }
-                header("Location: /reset/?action=code&user=".$_POST['user']);
-                exit;
-            } else {
-                $ERROR = "<a class=\"error\">"._('Invalid host domain')."</a>";
             }
+        } else {
+            $ERROR = "<a class=\"error\">"._('Please wait 15 minutes before sending a new request')."</a>";
         }
     }
     unset($output);

+ 6 - 6
web/templates/pages/list_ssl.html

@@ -50,32 +50,32 @@
 						</tr>
 						</tr>
 						<tr>
-							<td class="vst-text" style="padding: 12px 0 0 0;"><?=_('SSL Certificate');?>
+							<td class="vst-text" style="padding: 12px 0 0 0;"><?=_('SSL Certificate');?> <a href="javascript:saveTextToBlob('<?php echo $v_domain;?>.crt', 'v_crt');"><i class="fas fa-download"></i></a>
 							</td>
 						</tr>
 						<tr>
 							<td>
-								<textarea size="20" class="vst-textinput" name="v_crt"><?=$v_crt ?> </textarea>
+								<textarea size="20" class="vst-textinput" name="v_crt" id="v_crt"><?=$v_crt ?> </textarea>
 							</td>
 						</tr>
 						<tr>
 							<td class="vst-text" style="padding: 12px 0 0 0;">
-								<?=_('SSL Key');?>
+								<?=_('SSL Key');?> <a href="javascript:saveTextToBlob('<?php echo $v_domain;?>.key', 'v_key');"><i class="fas fa-download"></i></a>
 							</td>
 						</tr>
 						<tr>
 							<td>
-								<textarea size="20" class="vst-textinput" name="v_key"><?=$v_key ?> </textarea>
+								<textarea size="20" class="vst-textinput" name="v_key" id="v_key"><?=$v_key ?> </textarea>
 							</td>
 						</tr>
 						<tr>
 							<td class="vst-text" style="padding: 24px 0 0 0;">
-								<?=_('SSL CSR');?>
+								<?=_('SSL CSR');?> <a href="javascript:saveTextToBlob('<?php echo $v_domain;?>.csr', 'v_crt');"><i class="fas fa-download"></i></a>
 							</td>
 						</tr>
 						<tr>
 							<td>
-								<textarea size="20" class="vst-textinput" name="v_csr"><?=$v_csr ?> </textarea>
+								<textarea size="20" class="vst-textinput" name="v_csr" id="v_csr"><?=$v_csr ?> </textarea>
 							</td>
 						</tr>
 					</table>