Skip to content

Commit 7ad8178

Browse files
committed
avoid writing the keystore if no changes were made
1 parent 7178846 commit 7ad8178

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

server/src/com/mirth/connect/server/controllers/DefaultConfigurationController.java

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
import javax.net.ssl.SSLSocketFactory;
5454
import javax.xml.parsers.DocumentBuilderFactory;
5555

56-
import com.mirth.connect.client.core.BrandingConstants;
5756
import org.apache.commons.codec.binary.Base64;
5857
import org.apache.commons.collections4.CollectionUtils;
5958
import org.apache.commons.collections4.MapUtils;
@@ -63,6 +62,7 @@
6362
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
6463
import org.apache.commons.configuration2.ex.ConfigurationException;
6564
import org.apache.commons.dbutils.DbUtils;
65+
import org.apache.commons.io.IOUtils;
6666
import org.apache.commons.lang3.ArrayUtils;
6767
import org.apache.commons.lang3.BooleanUtils;
6868
import org.apache.commons.lang3.StringUtils;
@@ -75,7 +75,6 @@
7575
import org.apache.ibatis.session.SqlSessionManager;
7676
import org.apache.logging.log4j.LogManager;
7777
import org.apache.logging.log4j.Logger;
78-
import org.bouncycastle.asn1.ASN1Sequence;
7978
import org.bouncycastle.asn1.x500.X500Name;
8079
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
8180
import org.bouncycastle.asn1.x509.BasicConstraints;
@@ -94,6 +93,7 @@
9493
import com.mirth.commons.encryption.Encryptor;
9594
import com.mirth.commons.encryption.KeyEncryptor;
9695
import com.mirth.commons.encryption.Output;
96+
import com.mirth.connect.client.core.BrandingConstants;
9797
import com.mirth.connect.client.core.ControllerException;
9898
import com.mirth.connect.client.core.PropertiesConfigurationUtil;
9999
import com.mirth.connect.donkey.model.DatabaseConstants;
@@ -463,7 +463,7 @@ public void initialize() {
463463
} catch (Exception e) {
464464
logger.error("Failed to initialize configuration controller", e);
465465
} finally {
466-
ResourceUtil.closeResourceQuietly(versionPropertiesStream);
466+
IOUtils.closeQuietly(versionPropertiesStream);
467467
}
468468
}
469469

@@ -1234,6 +1234,8 @@ public void initializeSecuritySettings() {
12341234
keyStore = KeyStore.getInstance(mirthConfig.getString("keystore.type", "JCEKS"));
12351235
}
12361236

1237+
boolean dirtiedKeystore = false;
1238+
12371239
if (keyStoreFile.exists()) {
12381240
keyStoreFileIs = new FileInputStream(keyStoreFile);
12391241
keyStore.load(keyStoreFileIs, keyStorePassword);
@@ -1256,20 +1258,23 @@ public void initializeSecuritySettings() {
12561258
}
12571259

12581260
keyStore.load(null, keyStorePassword);
1261+
dirtiedKeystore = true;
12591262
logger.debug("keystore file not found, created new one");
12601263
}
12611264

1262-
configureEncryption(provider, keyStore, keyPassword);
1263-
generateDefaultCertificate(provider, keyStore, keyPassword);
1265+
dirtiedKeystore |= configureEncryption(provider, keyStore, keyPassword);
1266+
dirtiedKeystore |= generateDefaultCertificate(provider, keyStore, keyPassword);
12641267

1265-
// write the keystore back to the file
1266-
fos = new FileOutputStream(keyStoreFile);
1267-
keyStore.store(fos, keyStorePassword);
1268+
// only re-write the keystore if it was changed
1269+
if(dirtiedKeystore) {
1270+
fos = new FileOutputStream(keyStoreFile);
1271+
keyStore.store(fos, keyStorePassword);
1272+
}
12681273
} catch (Exception e) {
12691274
logger.error("Could not initialize security settings.", e);
12701275
} finally {
1271-
ResourceUtil.closeResourceQuietly(keyStoreFileIs);
1272-
ResourceUtil.closeResourceQuietly(fos);
1276+
IOUtils.closeQuietly(keyStoreFileIs);
1277+
IOUtils.closeQuietly(fos);
12731278
}
12741279
}
12751280

@@ -1352,7 +1357,7 @@ private void saveMirthConfig() throws FileNotFoundException, ConfigurationExcept
13521357
try {
13531358
PropertiesConfigurationUtil.saveTo(mirthConfig, os);
13541359
} finally {
1355-
ResourceUtil.closeResourceQuietly(os);
1360+
IOUtils.closeQuietly(os);
13561361
}
13571362
}
13581363

@@ -1433,8 +1438,8 @@ public void migrateKeystore() {
14331438
} catch (Exception e) {
14341439
logger.error("Error migrating encryption key from database to keystore.", e);
14351440
} finally {
1436-
ResourceUtil.closeResourceQuietly(mirthPropsIs);
1437-
ResourceUtil.closeResourceQuietly(keyStoreOuputStream);
1441+
IOUtils.closeQuietly(mirthPropsIs);
1442+
IOUtils.closeQuietly(keyStoreOuputStream);
14381443
}
14391444
}
14401445

@@ -1446,17 +1451,15 @@ public void updatePropertiesConfiguration(PropertiesConfiguration config) {
14461451
/**
14471452
* Instantiates the encryptor and digester using the configuration properties. If the properties
14481453
* are not found, reasonable defaults are used.
1449-
*
1450-
* @param provider
1451-
* The provider to use (ex. BC)
1452-
* @param keyStore
1453-
* The keystore from which to load the secret encryption key
1454-
* @param keyPassword
1455-
* The secret key password
1454+
*
1455+
* @param provider The provider to use (ex. BC)
1456+
* @param keyStore The keystore from which to load the secret encryption key
1457+
* @param keyPassword The secret key password
14561458
* @throws Exception
14571459
*/
1458-
private void configureEncryption(Provider provider, KeyStore keyStore, char[] keyPassword) throws Exception {
1460+
private boolean configureEncryption(Provider provider, KeyStore keyStore, char[] keyPassword) throws Exception {
14591461
SecretKey secretKey = null;
1462+
boolean dirtiedKeystore = false;
14601463

14611464
if (!keyStore.containsAlias(SECRET_KEY_ALIAS)) {
14621465
logger.debug("encryption key not found, generating new one");
@@ -1465,6 +1468,7 @@ private void configureEncryption(Provider provider, KeyStore keyStore, char[] ke
14651468
secretKey = keyGenerator.generateKey();
14661469
KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(secretKey);
14671470
keyStore.setEntry(SECRET_KEY_ALIAS, entry, new KeyStore.PasswordProtection(keyPassword));
1471+
dirtiedKeystore = true;
14681472
} else {
14691473
logger.debug("found encryption key in keystore");
14701474
secretKey = (SecretKey) keyStore.getKey(SECRET_KEY_ALIAS, keyPassword);
@@ -1509,15 +1513,18 @@ private void configureEncryption(Provider provider, KeyStore keyStore, char[] ke
15091513
);
15101514
// @formatter:on
15111515
}
1516+
1517+
return dirtiedKeystore;
15121518
}
15131519

15141520
/**
15151521
* Checks for an existing certificate to use for secure communication between the server and
15161522
* client. If no certficate exists, this will generate a new one.
15171523
*
15181524
*/
1519-
private void generateDefaultCertificate(Provider provider, KeyStore keyStore, char[] keyPassword) throws Exception {
1525+
private boolean generateDefaultCertificate(Provider provider, KeyStore keyStore, char[] keyPassword) throws Exception {
15201526
final String certificateAlias = "mirthconnect";
1527+
boolean dirtiedKeystore = false;
15211528

15221529
if (!keyStore.containsAlias(certificateAlias)) {
15231530
// Common CA and SSL cert attributes
@@ -1555,9 +1562,12 @@ private void generateDefaultCertificate(Provider provider, KeyStore keyStore, ch
15551562
// add the generated SSL cert to the keystore using the key password
15561563
keyStore.setKeyEntry(certificateAlias, sslKeyPair.getPrivate(), keyPassword, new Certificate[] {
15571564
sslCert });
1565+
dirtiedKeystore = true;
15581566
} else {
15591567
logger.debug("found certificate in keystore");
15601568
}
1569+
1570+
return dirtiedKeystore;
15611571
}
15621572

15631573
private boolean isDatabaseRunning() {

server/src/com/mirth/connect/server/util/ResourceUtil.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ public static InputStream getResourceStream(Class<?> clazz, String resourceName)
4444
return is;
4545
}
4646

47+
/**
48+
* Close a Closeable resource quietly. Trap and ignore any exceptions thrown when calling close()
49+
*
50+
* @deprecated import org.apache.commons.io.IOUtils does this and is already on the classpath. Further deprecated by try-with-resources since Java 7
51+
* @param resource the Closeable object to try and close
52+
*/
53+
@Deprecated
4754
public static void closeResourceQuietly(Closeable resource) {
4855
if (resource != null) {
4956
try {

0 commit comments

Comments
 (0)