diff --git a/CHANGELOG.md b/CHANGELOG.md index b12f9c7a32..75b24d1b7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Use isClusterPerm instead of requestedResolved.isLocalAll() to determine if action is a cluster action ([#5445](https://github.com/opensearch-project/security/pull/5445)) * Fix config update with deprecated config types failing in mixed clusters ([#5456](https://github.com/opensearch-project/security/pull/5456)) * Fix usage of jwt_clock_skew_tolerance_seconds in HTTPJwtAuthenticator ([#5506](https://github.com/opensearch-project/security/pull/5506)) +* Always install demo certs if configured with demo certs ([#5517](https://github.com/opensearch-project/security/pull/5517)) ### Refactoring diff --git a/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java b/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java index c1e4b43cd2..a29e0d0137 100644 --- a/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java +++ b/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java @@ -33,6 +33,11 @@ public CertificateGenerator(Installer installer) { public void createDemoCertificates() { for (Certificates cert : Certificates.values()) { String filePath = this.installer.OPENSEARCH_CONF_DIR + File.separator + cert.getFileName(); + File file = new File(filePath); + if (file.exists()) { + System.out.println("File " + filePath + " already exists. Skipping."); + continue; + } try { FileWriter fileWriter = new FileWriter(filePath, StandardCharsets.UTF_8); fileWriter.write(cert.getContent()); diff --git a/src/main/java/org/opensearch/security/tools/democonfig/Installer.java b/src/main/java/org/opensearch/security/tools/democonfig/Installer.java index a56af90d2d..499179a297 100644 --- a/src/main/java/org/opensearch/security/tools/democonfig/Installer.java +++ b/src/main/java/org/opensearch/security/tools/democonfig/Installer.java @@ -41,7 +41,7 @@ public class Installer { private static Installer instance; private static SecuritySettingsConfigurer securitySettingsConfigurer; - private static CertificateGenerator certificateGenerator; + static CertificateGenerator certificateGenerator; boolean assumeyes = false; boolean initsecurity = false; diff --git a/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java b/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java index 46758a0ee5..fd883124c4 100644 --- a/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java +++ b/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java @@ -37,6 +37,7 @@ import org.yaml.snakeyaml.Yaml; import static org.opensearch.security.DefaultObjectMapper.YAML_MAPPER; +import static org.opensearch.security.tools.democonfig.Installer.certificateGenerator; /** * This class updates the security related configuration, as needed. @@ -105,6 +106,59 @@ public void configureSecuritySettings() throws IOException { writeSecurityConfigToOpenSearchYML(); } + boolean isSecurityPluginIsConfiguredWithDemoCerts() { + if (installer.OPENSEARCH_CONF_FILE == null || !new File(installer.OPENSEARCH_CONF_FILE).exists()) { + return false; + } + + try (BufferedReader br = new BufferedReader(new FileReader(installer.OPENSEARCH_CONF_FILE, StandardCharsets.UTF_8))) { + Yaml yaml = new Yaml(); + Map yamlData = yaml.load(br); + if (yamlData == null) return false; + + String[] requiredSettings = { + "plugins.security.ssl.transport.pemcert_filepath", + "plugins.security.ssl.transport.pemkey_filepath", + "plugins.security.ssl.transport.pemtrustedcas_filepath", + "plugins.security.ssl.http.pemcert_filepath", + "plugins.security.ssl.http.pemkey_filepath", + "plugins.security.ssl.http.pemtrustedcas_filepath" }; + + String[] expectedValues = { "esnode.pem", "esnode-key.pem", "root-ca.pem", "esnode.pem", "esnode-key.pem", "root-ca.pem" }; + + for (int i = 0; i < requiredSettings.length; i++) { + String value = getNestedValue(yamlData, requiredSettings[i]); + if (!expectedValues[i].equals(value)) { + return false; + } + } + return true; + } catch (IOException e) { + return false; + } + } + + @SuppressWarnings("unchecked") + private String getNestedValue(Map yamlData, String key) { + // Check for flattened key first + if (yamlData.containsKey(key)) { + Object value = yamlData.get(key); + return value instanceof String ? (String) value : null; + } + + // Check for nested structure + String[] parts = key.split("\\."); + Object current = yamlData; + for (String part : parts) { + if (current instanceof Map) { + current = ((Map) current).get(part); + } else { + return null; + } + } + return current instanceof String ? (String) current : null; + } + /** * Checks if security plugin is already configured. If so, the script execution will exit. */ @@ -119,6 +173,9 @@ void checkIfSecurityPluginIsAlreadyConfigured() { // Check for flat keys for (String key : yamlData.keySet()) { if (key.startsWith("plugins.security")) { + if (isSecurityPluginIsConfiguredWithDemoCerts()) { + certificateGenerator.createDemoCertificates(); + } System.out.println(installer.OPENSEARCH_CONF_FILE + " seems to be already configured for Security. Quit."); installer.getExitHandler().exit(installer.skip_updates); } @@ -128,6 +185,9 @@ void checkIfSecurityPluginIsAlreadyConfigured() { Map plugins = (Map) yamlData.get("plugins"); for (String key : plugins.keySet()) { if (key.startsWith("security")) { + if (isSecurityPluginIsConfiguredWithDemoCerts()) { + certificateGenerator.createDemoCertificates(); + } System.out.println(installer.OPENSEARCH_CONF_FILE + " seems to be already configured for Security. Quit."); installer.getExitHandler().exit(installer.skip_updates); }