Skip to content

Commit 20d5bf5

Browse files
authored
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
1 parent ca870df commit 20d5bf5

6 files changed

Lines changed: 80 additions & 8 deletions

File tree

client/conf/server.properties.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ https.port=8443
3838

3939
# The keystore and manager passwords are assumed to be same.
4040
https.keystore=/etc/cloudstack/management/cloud.jks
41+
# If you want to encrypt the password follow the steps mentioned at:
42+
# http://docs.cloudstack.apache.org/projects/archived-cloudstack-administration/en/latest/management.html?highlight=jasypt#changing-the-database-password
4143
https.keystore.password=vmops.com
44+
# If an encrypted password is used, specify the encryption type - valid types: file, env (set environment variable CLOUD_SECRET_KEY), web
45+
# password.encryption.type=none
4246

4347
# The path to webapp directory
4448
webapp.dir=/usr/share/cloudstack-management/webapp

client/src/main/java/org/apache/cloudstack/ServerDaemon.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
package org.apache.cloudstack;
2020

2121
import java.io.File;
22+
import java.io.FileInputStream;
2223
import java.io.IOException;
24+
import java.io.InputStream;
2325
import java.lang.management.ManagementFactory;
2426
import java.net.URL;
2527
import java.util.Properties;
2628

2729
import com.cloud.utils.Pair;
30+
import com.cloud.utils.server.ServerProperties;
2831
import org.apache.commons.daemon.Daemon;
2932
import org.apache.commons.daemon.DaemonContext;
3033
import org.eclipse.jetty.jmx.MBeanContainer;
@@ -116,7 +119,8 @@ public void init(final DaemonContext context) {
116119
LOG.info("Server configuration file found: " + confFile.getAbsolutePath());
117120

118121
try {
119-
final Properties properties = PropertiesUtil.loadFromFile(confFile);
122+
InputStream is = new FileInputStream(confFile);
123+
final Properties properties = ServerProperties.getServerProperties(is);
120124
if (properties == null) {
121125
return;
122126
}
@@ -132,7 +136,7 @@ public void init(final DaemonContext context) {
132136
setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));
133137
setSessionTimeout(Integer.valueOf(properties.getProperty(SESSION_TIMEOUT, "30")));
134138
} catch (final IOException e) {
135-
LOG.warn("Failed to load configuration from server.properties file", e);
139+
LOG.warn("Failed to read configuration from server.properties file", e);
136140
} finally {
137141
// make sure that at least HTTP is enabled if both of them are set to false (misconfiguration)
138142
if (!httpEnable && !httpsEnable) {

utils/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChecker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ public void init() {
5555
DbProperties.getDbProperties();
5656
}
5757

58-
public void check(Properties dbProps) throws IOException {
59-
String encryptionType = dbProps.getProperty("db.cloud.encryption.type");
58+
public void check(Properties properties, String property) throws IOException {
59+
String encryptionType = properties.getProperty(property);
6060

6161
s_logger.debug("Encryption Type: " + encryptionType);
6262

@@ -116,7 +116,7 @@ public void check(Properties dbProps) throws IOException {
116116
throw new CloudRuntimeException("Accept failed on " + port);
117117
}
118118
} catch (IOException ioex) {
119-
throw new CloudRuntimeException("Error initializing secret key reciever", ioex);
119+
throw new CloudRuntimeException("Error initializing secret key receiver", ioex);
120120
}
121121
} else {
122122
throw new CloudRuntimeException("Invalid encryption type: " + encryptionType);

utils/src/main/java/com/cloud/utils/db/DbProperties.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ public class DbProperties {
3939

4040
private static Properties properties = new Properties();
4141
private static boolean loaded = false;
42+
public static final String dbEncryptionType = "db.cloud.encryption.type";
4243

4344
protected static Properties wrapEncryption(Properties dbProps) throws IOException {
4445
EncryptionSecretKeyChecker checker = new EncryptionSecretKeyChecker();
45-
checker.check(dbProps);
46+
checker.check(dbProps, dbEncryptionType);
4647

4748
if (EncryptionSecretKeyChecker.useEncryption()) {
4849
return dbProps;
@@ -77,7 +78,7 @@ public synchronized static Properties getDbProperties() {
7778
}
7879

7980
EncryptionSecretKeyChecker checker = new EncryptionSecretKeyChecker();
80-
checker.check(dbProps);
81+
checker.check(dbProps, dbEncryptionType);
8182

8283
if (EncryptionSecretKeyChecker.useEncryption()) {
8384
StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.utils.server;
18+
19+
import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
20+
import org.apache.commons.io.IOUtils;
21+
import org.apache.log4j.Logger;
22+
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
23+
import org.jasypt.properties.EncryptableProperties;
24+
25+
import java.io.IOException;
26+
import java.io.InputStream;
27+
import java.util.Properties;
28+
29+
public class ServerProperties {
30+
private static final Logger LOG = Logger.getLogger(ServerProperties.class);
31+
32+
private static Properties properties = new Properties();
33+
private static boolean loaded = false;
34+
public static final String passwordEncryptionType = "password.encryption.type";
35+
36+
public synchronized static Properties getServerProperties(InputStream inputStream) {
37+
if (!loaded) {
38+
Properties serverProps = new Properties();
39+
try {
40+
serverProps.load(inputStream);
41+
42+
EncryptionSecretKeyChecker checker = new EncryptionSecretKeyChecker();
43+
checker.check(serverProps, passwordEncryptionType);
44+
45+
if (EncryptionSecretKeyChecker.useEncryption()) {
46+
StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
47+
EncryptableProperties encrServerProps = new EncryptableProperties(encryptor);
48+
encrServerProps.putAll(serverProps);
49+
serverProps = encrServerProps;
50+
}
51+
} catch (IOException e) {
52+
throw new IllegalStateException("Failed to load server.properties", e);
53+
} finally {
54+
IOUtils.closeQuietly(inputStream);
55+
}
56+
57+
properties = serverProps;
58+
loaded = true;
59+
}
60+
61+
return properties;
62+
}
63+
}

utils/src/test/java/com/cloud/utils/crypto/EncryptionSecretKeyCheckerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void testKeyFileDoesNotExists() throws IOException, URISyntaxException {
3939
Assert.assertNotNull(checker);
4040
Properties properties = DbProperties.getDbProperties();
4141
properties.setProperty("db.cloud.encryption.type", "file");
42-
checker.check(properties);
42+
checker.check(properties, DbProperties.dbEncryptionType);
4343
}
4444

4545
}

0 commit comments

Comments
 (0)