You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by nv...@apache.org on 2021/09/20 15:58:51 UTC

[cloudstack] branch main updated: server: Add support to encrypt https.keystore.password in server.properties (#5459)

This is an automated email from the ASF dual-hosted git repository.

nvazquez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 20d5bf5  server: Add support to encrypt https.keystore.password in server.properties (#5459)
20d5bf5 is described below

commit 20d5bf55b72427a98f0196c7ceb3f6abdaeea42f
Author: Pearl Dsilva <pe...@gmail.com>
AuthorDate: Mon Sep 20 21:28:27 2021 +0530

    server: Add support to encrypt https.keystore.password in server.properties (#5459)
    
    * Add support to encrypt https.keystore.password in server.properties
    
    * address comments
    
    * address comments
---
 client/conf/server.properties.in                   |  4 ++
 .../java/org/apache/cloudstack/ServerDaemon.java   |  8 ++-
 .../utils/crypt/EncryptionSecretKeyChecker.java    |  6 +--
 .../main/java/com/cloud/utils/db/DbProperties.java |  5 +-
 .../com/cloud/utils/server/ServerProperties.java   | 63 ++++++++++++++++++++++
 .../crypto/EncryptionSecretKeyCheckerTest.java     |  2 +-
 6 files changed, 80 insertions(+), 8 deletions(-)

diff --git a/client/conf/server.properties.in b/client/conf/server.properties.in
index 7846df1..42d98a6 100644
--- a/client/conf/server.properties.in
+++ b/client/conf/server.properties.in
@@ -38,7 +38,11 @@ https.port=8443
 
 # The keystore and manager passwords are assumed to be same.
 https.keystore=/etc/cloudstack/management/cloud.jks
+# If you want to encrypt the password follow the steps mentioned at:
+# http://docs.cloudstack.apache.org/projects/archived-cloudstack-administration/en/latest/management.html?highlight=jasypt#changing-the-database-password
 https.keystore.password=vmops.com
+# If an encrypted password is used, specify the encryption type - valid types: file, env (set environment variable CLOUD_SECRET_KEY), web
+# password.encryption.type=none
 
 # The path to webapp directory
 webapp.dir=/usr/share/cloudstack-management/webapp
diff --git a/client/src/main/java/org/apache/cloudstack/ServerDaemon.java b/client/src/main/java/org/apache/cloudstack/ServerDaemon.java
index b4cbb62..1b8e2f8 100644
--- a/client/src/main/java/org/apache/cloudstack/ServerDaemon.java
+++ b/client/src/main/java/org/apache/cloudstack/ServerDaemon.java
@@ -19,12 +19,15 @@
 package org.apache.cloudstack;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.management.ManagementFactory;
 import java.net.URL;
 import java.util.Properties;
 
 import com.cloud.utils.Pair;
+import com.cloud.utils.server.ServerProperties;
 import org.apache.commons.daemon.Daemon;
 import org.apache.commons.daemon.DaemonContext;
 import org.eclipse.jetty.jmx.MBeanContainer;
@@ -116,7 +119,8 @@ public class ServerDaemon implements Daemon {
         LOG.info("Server configuration file found: " + confFile.getAbsolutePath());
 
         try {
-            final Properties properties = PropertiesUtil.loadFromFile(confFile);
+            InputStream is = new FileInputStream(confFile);
+            final Properties properties = ServerProperties.getServerProperties(is);
             if (properties == null) {
                 return;
             }
@@ -132,7 +136,7 @@ public class ServerDaemon implements Daemon {
             setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));
             setSessionTimeout(Integer.valueOf(properties.getProperty(SESSION_TIMEOUT, "30")));
         } catch (final IOException e) {
-            LOG.warn("Failed to load configuration from server.properties file", e);
+            LOG.warn("Failed to read configuration from server.properties file", e);
         } finally {
             // make sure that at least HTTP is enabled if both of them are set to false (misconfiguration)
             if (!httpEnable && !httpsEnable) {
diff --git a/utils/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChecker.java b/utils/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChecker.java
index 6524987..ef17f7b 100644
--- a/utils/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChecker.java
+++ b/utils/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChecker.java
@@ -55,8 +55,8 @@ public class EncryptionSecretKeyChecker {
         DbProperties.getDbProperties();
     }
 
-    public void check(Properties dbProps) throws IOException {
-        String encryptionType = dbProps.getProperty("db.cloud.encryption.type");
+    public void check(Properties properties, String property) throws IOException {
+        String encryptionType = properties.getProperty(property);
 
         s_logger.debug("Encryption Type: " + encryptionType);
 
@@ -116,7 +116,7 @@ public class EncryptionSecretKeyChecker {
                     throw new CloudRuntimeException("Accept failed on " + port);
                 }
             } catch (IOException ioex) {
-                throw new CloudRuntimeException("Error initializing secret key reciever", ioex);
+                throw new CloudRuntimeException("Error initializing secret key receiver", ioex);
             }
         } else {
             throw new CloudRuntimeException("Invalid encryption type: " + encryptionType);
diff --git a/utils/src/main/java/com/cloud/utils/db/DbProperties.java b/utils/src/main/java/com/cloud/utils/db/DbProperties.java
index 8420614..d99e6c0 100644
--- a/utils/src/main/java/com/cloud/utils/db/DbProperties.java
+++ b/utils/src/main/java/com/cloud/utils/db/DbProperties.java
@@ -39,10 +39,11 @@ public class DbProperties {
 
     private static Properties properties = new Properties();
     private static boolean loaded = false;
+    public static final String dbEncryptionType = "db.cloud.encryption.type";
 
     protected static Properties wrapEncryption(Properties dbProps) throws IOException {
         EncryptionSecretKeyChecker checker = new EncryptionSecretKeyChecker();
-        checker.check(dbProps);
+        checker.check(dbProps, dbEncryptionType);
 
         if (EncryptionSecretKeyChecker.useEncryption()) {
             return dbProps;
@@ -77,7 +78,7 @@ public class DbProperties {
                 }
 
                 EncryptionSecretKeyChecker checker = new EncryptionSecretKeyChecker();
-                checker.check(dbProps);
+                checker.check(dbProps, dbEncryptionType);
 
                 if (EncryptionSecretKeyChecker.useEncryption()) {
                     StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
diff --git a/utils/src/main/java/com/cloud/utils/server/ServerProperties.java b/utils/src/main/java/com/cloud/utils/server/ServerProperties.java
new file mode 100644
index 0000000..4eabc5f
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/server/ServerProperties.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.server;
+
+import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
+import org.jasypt.properties.EncryptableProperties;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class ServerProperties {
+    private static final Logger LOG = Logger.getLogger(ServerProperties.class);
+
+    private static Properties properties = new Properties();
+    private static boolean loaded = false;
+    public static final String passwordEncryptionType = "password.encryption.type";
+
+    public synchronized static Properties getServerProperties(InputStream inputStream) {
+        if (!loaded) {
+            Properties serverProps = new Properties();
+            try {
+                serverProps.load(inputStream);
+
+                EncryptionSecretKeyChecker checker = new EncryptionSecretKeyChecker();
+                checker.check(serverProps, passwordEncryptionType);
+
+                if (EncryptionSecretKeyChecker.useEncryption()) {
+                    StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
+                    EncryptableProperties encrServerProps = new EncryptableProperties(encryptor);
+                    encrServerProps.putAll(serverProps);
+                    serverProps = encrServerProps;
+                }
+            } catch (IOException e) {
+                throw new IllegalStateException("Failed to load server.properties", e);
+            } finally {
+                IOUtils.closeQuietly(inputStream);
+            }
+
+            properties = serverProps;
+            loaded = true;
+        }
+
+        return properties;
+    }
+}
diff --git a/utils/src/test/java/com/cloud/utils/crypto/EncryptionSecretKeyCheckerTest.java b/utils/src/test/java/com/cloud/utils/crypto/EncryptionSecretKeyCheckerTest.java
index 0f3f058..bd92600 100644
--- a/utils/src/test/java/com/cloud/utils/crypto/EncryptionSecretKeyCheckerTest.java
+++ b/utils/src/test/java/com/cloud/utils/crypto/EncryptionSecretKeyCheckerTest.java
@@ -39,7 +39,7 @@ public class EncryptionSecretKeyCheckerTest {
     Assert.assertNotNull(checker);
     Properties properties = DbProperties.getDbProperties();
     properties.setProperty("db.cloud.encryption.type", "file");
-    checker.check(properties);
+    checker.check(properties, DbProperties.dbEncryptionType);
   }
 
 }
\ No newline at end of file