Skip to content

Commit

Permalink
0005790: Failed to decrypt node password from lost secret key in
Browse files Browse the repository at this point in the history
keystore
  • Loading branch information
erilong committed Apr 14, 2023
1 parent 014042b commit a7068d3
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 4 deletions.
Expand Up @@ -28,6 +28,7 @@
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.UnrecoverableKeyException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
Expand Down Expand Up @@ -56,6 +57,7 @@
import org.jumpmind.symmetric.common.Constants;
import org.jumpmind.symmetric.common.ParameterConstants;
import org.jumpmind.symmetric.common.TableConstants;
import org.jumpmind.symmetric.config.INodeIdCreator;
import org.jumpmind.symmetric.db.ISoftwareUpgradeListener;
import org.jumpmind.symmetric.db.ISymmetricDialect;
import org.jumpmind.symmetric.ext.ISymmetricEngineLifecycle;
Expand All @@ -70,6 +72,7 @@
import org.jumpmind.symmetric.model.ProcessInfo;
import org.jumpmind.symmetric.model.ProcessInfo.ProcessStatus;
import org.jumpmind.symmetric.model.RemoteNodeStatuses;
import org.jumpmind.symmetric.security.INodePasswordFilter;
import org.jumpmind.symmetric.service.IAcknowledgeService;
import org.jumpmind.symmetric.service.IBandwidthService;
import org.jumpmind.symmetric.service.IClusterService;
Expand Down Expand Up @@ -141,6 +144,7 @@
import org.jumpmind.symmetric.transport.TransportManagerFactory;
import org.jumpmind.symmetric.util.PropertiesUtil;
import org.jumpmind.util.AppUtils;
import org.jumpmind.util.ExceptionUtils;
import org.jumpmind.util.FormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -613,7 +617,7 @@ public synchronized boolean start(boolean startJobs) {
setup();
if (isConfigured()) {
Node node = nodeService.findIdentity();
checkSystemIntegrity(node);
node = checkSystemIntegrity(node);
isInitialized = true;
if (node != null) {
log.info(
Expand Down Expand Up @@ -682,7 +686,7 @@ public synchronized boolean start(boolean startJobs) {
return started;
}

protected void checkSystemIntegrity(Node node) {
protected Node checkSystemIntegrity(Node node) {
if (node != null && (!node.getExternalId().equals(getParameterService().getExternalId())
|| !node.getNodeGroupId().equals(getParameterService().getNodeGroupId()))) {
if (parameterService.is(ParameterConstants.NODE_COPY_MODE_ENABLED, false)) {
Expand All @@ -705,6 +709,53 @@ protected void checkSystemIntegrity(Node node) {
node != null ? node.getNodeId() : "null", ParameterConstants.INITIAL_LOAD_USE_EXTRACT_JOB,
useExtractJob, ParameterConstants.STREAM_TO_FILE_ENABLED, streamToFile));
}
INodePasswordFilter filter = extensionService.getExtensionPoint(INodePasswordFilter.class);
if (filter != null) {
log.info("Testing keystore integrity");
try {
securityService.encrypt(ParameterConstants.EXTERNAL_ID);
} catch (Exception e) {
if (ExceptionUtils.is(e, UnrecoverableKeyException.class)) {
throw new SymmetricException("Failed to open keystore because keystore password is wrong. "
+ "Check javax.net.ssl.keyStorePassword in conf/sym_service.conf and bin/setenv.", e);
}
throw e;
}
log.info("Testing node security integrity");
Map<String, NodeSecurity> nodeSecurities = nodeService.findAllNodeSecurity(false);
List<NodeSecurity> badNodeSecurities = new ArrayList<NodeSecurity>();
for (NodeSecurity nodeSecurity : nodeSecurities.values()) {
if (StringUtils.isBlank(nodeSecurity.getNodePassword())) {
badNodeSecurities.add(nodeSecurity);
}
}
if (badNodeSecurities.size() > 0) {
if (parameterService.is(ParameterConstants.CLUSTER_LOCKING_ENABLED)) {
throw new IllegalStateException("Unable to decrypt " + badNodeSecurities.size()
+ " node security rows. Copy the security/keystore file from a working node in the cluster.");
} else if (parameterService.isRegistrationServer()) {
log.error("Found {} bad node securities. Attempting to re-open registration to fix them.", badNodeSecurities.size());
String myNodeId = nodeService.findIdentityNodeId();
for (NodeSecurity nodeSecurity : badNodeSecurities) {
if (nodeSecurity.getNodeId().equals(myNodeId)) {
log.info("Re-generating my node password");
String password = extensionService.getExtensionPoint(INodeIdCreator.class).generatePassword(node);
nodeSecurity.setNodePassword(password);
nodeService.updateNodeSecurity(nodeSecurity);
} else {
registrationService.reOpenRegistration(nodeSecurity.getNodeId());
}
}
} else {
log.error(
"Found {} bad node securities. Removing identity and attempting re-registration to fix them. You may need to approve the registration request.",
badNodeSecurities.size());
nodeService.deleteIdentity();
node = null;
}
}
}
return node;
}

public String getEngineDescription(String msg) {
Expand Down
Expand Up @@ -233,7 +233,12 @@ protected Properties getJavaMailProperties(TypedProperties typedProp) {

protected String decryptPassword(String password) {
if (password != null && password.startsWith(SecurityConstants.PREFIX_ENC)) {
return securityService.decrypt(password.substring(SecurityConstants.PREFIX_ENC.length()));
try {
return securityService.decrypt(password.substring(SecurityConstants.PREFIX_ENC.length()));
} catch (Exception e) {
throw new IllegalStateException(
"Failed to decrypt the mail server password. Please re-enter the password on the Configure -> Mail Server screen", e);
}
}
return password;
}
Expand Down
Expand Up @@ -91,7 +91,12 @@ public static ResettableBasicDataSource create(TypedProperties properties,
dataSource.setUrl(properties.get(BasicDataSourcePropertyConstants.DB_POOL_URL, null));
String user = properties.get(BasicDataSourcePropertyConstants.DB_POOL_USER, "");
if (user != null && user.startsWith(SecurityConstants.PREFIX_ENC)) {
user = securityService.decrypt(user.substring(SecurityConstants.PREFIX_ENC.length()));
try {
user = securityService.decrypt(user.substring(SecurityConstants.PREFIX_ENC.length()));
} catch (Exception ex) {
throw new IllegalStateException("Failed to decrypt the database user from your engine properties file stored under the "
+ BasicDataSourcePropertyConstants.DB_POOL_USER + " property. Please re-encrypt your user", ex);
}
}
dataSource.setUsername(user);
String password = properties.get(BasicDataSourcePropertyConstants.DB_POOL_PASSWORD, "");
Expand Down
12 changes: 12 additions & 0 deletions symmetric-util/src/main/java/org/jumpmind/util/ExceptionUtils.java
Expand Up @@ -49,4 +49,16 @@ public static Throwable getRootCause(Throwable ex) {
}
return cause;
}

public static boolean is(Exception e, Class<?>... exceptions) {
if (e != null) {
Throwable cause = getRootCause(e);
for (Class<?> ex : exceptions) {
if (ex.isInstance(e) || ex.isInstance(cause)) {
return true;
}
}
}
return false;
}
}

0 comments on commit a7068d3

Please sign in to comment.