Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;

public final class ExternalOpenSearchSink extends AuditLogSink {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
import org.opensearch.security.support.ConfigConstants;
import org.opensearch.security.support.PemKeyReader;

import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;

public class WebhookSink extends AuditLogSink {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@
import org.ldaptive.ssl.SslConfig;
import org.ldaptive.ssl.ThreadLocalTLSSocketFactory;

import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;

public class LDAPAuthorizationBackend implements AuthorizationBackend {

Expand Down Expand Up @@ -300,7 +300,7 @@ private static Connection getConnection0(
configureSSL(config, settings, configPath);

final String bindDn = settings.get(ConfigConstants.LDAP_BIND_DN, null);
final String password = settings.get(ConfigConstants.LDAP_PASSWORD, null);
final String password = ConfigConstants.LDAP_PASSWORD.getSetting(settings, null);

if (isDebugEnabled) {
log.debug("bindDn {}, password {}", bindDn, password != null && password.length() > 0 ? "****" : "<not set>");
Expand Down Expand Up @@ -564,13 +564,13 @@ private static void configureSSL(final ConnectionConfig config, final Settings s
}

PrivateKey authenticationKey = PemKeyReader.loadKeyFromStream(
settings.get(ConfigConstants.LDAPS_PEMKEY_PASSWORD),
ConfigConstants.LDAPS_PEMKEY_PASSWORD.getSetting(settings),
PemKeyReader.resolveStream(ConfigConstants.LDAPS_PEMKEY_CONTENT, settings)
);

if (authenticationKey == null) {
authenticationKey = PemKeyReader.loadKeyFromFile(
settings.get(ConfigConstants.LDAPS_PEMKEY_PASSWORD),
ConfigConstants.LDAPS_PEMKEY_PASSWORD.getSetting(settings),
PemKeyReader.resolve(ConfigConstants.LDAPS_PEMKEY_FILEPATH, settings, configPath, enableClientAuth)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

package org.opensearch.security.auth.ldap.util;

import org.opensearch.security.setting.SecurableLegacySetting;

public final class ConfigConstants {

public static final String LDAP_AUTHC_USERBASE = "userbase";
Expand Down Expand Up @@ -40,7 +42,6 @@ public final class ConfigConstants {

public static final String LDAP_HOSTS = "hosts";
public static final String LDAP_BIND_DN = "bind_dn";
public static final String LDAP_PASSWORD = "password";
public static final String LDAP_FAKE_LOGIN_ENABLED = "fakelogin_enabled";
public static final String LDAP_SEARCH_ALL_BASES = "search_all_bases";

Expand All @@ -64,7 +65,6 @@ public final class ConfigConstants {

public static final String LDAPS_PEMKEY_FILEPATH = "pemkey_filepath";
public static final String LDAPS_PEMKEY_CONTENT = "pemkey_content";
public static final String LDAPS_PEMKEY_PASSWORD = "pemkey_password";
public static final String LDAPS_PEMCERT_FILEPATH = "pemcert_filepath";
public static final String LDAPS_PEMCERT_CONTENT = "pemcert_content";
public static final String LDAPS_PEMTRUSTEDCAS_FILEPATH = "pemtrustedcas_filepath";
Expand Down Expand Up @@ -93,6 +93,10 @@ public final class ConfigConstants {
public static final String LDAP_POOL_PRUNING_PERIOD = "pool.pruning_period";
public static final String LDAP_POOL_IDLE_TIME = "pool.idle_time";

// legacy unsecure and secure settings
public static final SecurableLegacySetting LDAP_PASSWORD = new SecurableLegacySetting("password");
public static final SecurableLegacySetting LDAPS_PEMKEY_PASSWORD = new SecurableLegacySetting("pemkey_password");

private ConfigConstants() {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ private ConnectionInitializer getConnectionInitializer() {
BindConnectionInitializer result = new BindConnectionInitializer();

String bindDn = settings.get(ConfigConstants.LDAP_BIND_DN, null);
String password = settings.get(ConfigConstants.LDAP_PASSWORD, null);
String password = ConfigConstants.LDAP_PASSWORD.getSetting(settings);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the complete name of the secure setting for LDAP passwords?

In the security plugin, you can configure more than one LDAP authentication domain. This can then also have different passwords. If I get this right, we won't be able to configure more than one LDAP domain with different passwords, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AuthenticationBackend settings are created from a subset of the properties here:

So it should allow for each individual backend to have it's own secure value. But examining the above only the settings from the index are used - there are no secure settings subset created and used when configuring the settings object for the backend.

Also a misunderstanding on my part renders this whole PR void, as the settings are centralized in an index, not pulled from a yaml on each node. We could allow for pulling the secure settings from the keystore by amending the above to subset and inject secure settings when creating the Settings for each backend, but then you'd almost certainly run into issues where the admin would have to remember to update the keystore on every node when secure values are set, and when changed (also leading to confusion if those keystores are not in sync - where auth make work against one node, but fail against another).

I'm leaning towards withdrawing this PR in light of the above, unless anyone has any ideas on a way forward?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chriswhite199 I remember taking a look a few months ago when looking at #4004 and believe it will take some changes in OpenSearch core.

I'll take another look into what's required for the security config to support reading from the keystore and reply back ASAP. (It may take a few days).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is the direction the PR should take (in relation to #4004):

  • Amend the securityadmin script to allow for the passwords / secret settings to be sourced from the opensearch keystore (or config.yaml for legacy reasons)
  • securityadmin still stores the secrets in the .opendistro-security index

My original intent of this PR is to avoid having passwords in cleartext config files on the filesystem (currently an admin has to remember to remove the config.yaml or redact the passwords after syncing).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is a good idea to file an RFC about this.

We also have the trouble that there is not only securityadmin, but - optionally - the REST API can be also used to change/retrieve the config.yml configuration.


if (password != null && password.length() == 0) {
password = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.setting;

import java.util.Optional;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.opensearch.common.settings.SecureSetting;
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Settings;
import org.opensearch.core.common.settings.SecureString;

/**
* Wrapper for legacy settings that support a secure variant located in the Keystore.
* <p>
* Secure name is the insecure name with "_secure" appended to it.
*/
public class SecurableLegacySetting {
Comment on lines +24 to +29
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused about the word "legacy" here. Could you please elaborate what "legacy settings" are?

private static final Logger LOG = LogManager.getLogger(SecurableLegacySetting.class);

public static final String SECURE_SUFFIX = "_secure";

public final String insecurePropertyName;

public final String propertyName;

public final String defaultValue;

public SecurableLegacySetting(String insecurePropertyName) {
this(insecurePropertyName, null);
}

public SecurableLegacySetting(String insecurePropertyName, String defaultValue) {
this(insecurePropertyName, String.format("%s%s", insecurePropertyName, SECURE_SUFFIX), defaultValue);
}

public SecurableLegacySetting(String insecurePropertyName, String propertyName, String defaultValue) {
super();
this.insecurePropertyName = insecurePropertyName;
this.propertyName = propertyName;
this.defaultValue = defaultValue;
}

public Setting<SecureString> asSetting() {
final Setting<SecureString> fallback = new InsecureFallbackStringSetting(this.insecurePropertyName, this.propertyName);
return SecureSetting.secureString(this.propertyName, fallback);
}

public Setting<SecureString> asInsecureSetting() {
return new InsecureFallbackStringSetting(this.insecurePropertyName, this.propertyName);
}

public String getSetting(Settings settings) {
return this.getSetting(settings, this.defaultValue);
}

public String getSetting(Settings settings, String defaultValue) {
return Optional.of(this.asSetting().get(settings)).filter(ss -> ss.length() > 0).map(SecureString::toString).orElse(defaultValue);
}

/**
* Alternative to InsecureStringSetting, which doesn't raise an exception if allow_insecure_settings is false, but
* instead log.WARNs the violation. This is to appease a potential cyclic dependency between commons-utils
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. For my curiosity, how did you discover this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't remember now, but setting allow_insecure_settings and defining the property as secure would raise an exception - hence the original implementation crafted two properties - password and password_secure to not break existing installations.

If you look at the original review for #2296, @peternied and I were discussing the integration test issues related to this - hopefully that comment can help you here

*/
private static class InsecureFallbackStringSetting extends Setting<SecureString> {
private final String name;
private final String secureName;

private InsecureFallbackStringSetting(String name, String secureName) {
super(name, "", s -> new SecureString(s.toCharArray()), Property.Deprecated, Property.Filtered, Property.NodeScope);
this.name = name;
this.secureName = secureName;
}

public SecureString get(Settings settings) {
if (this.exists(settings)) {
LOG.warn(
"Setting [{}] has a secure counterpart [{}] which should be used instead. Allowing use of {} for legacy setups",
this.name,
this.secureName,
this.name
);
}

return super.get(settings);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,18 @@
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.SupportedCipherSuiteFilter;

import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_HTTP_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_HTTP_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_HTTP_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_HTTP_TRUSTSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_HTTP_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_HTTP_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_HTTP_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_HTTP_TRUSTSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_KEYPASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_PASSWORD;
import static org.opensearch.security.ssl.SecureSSLSettings.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD;

public class DefaultSecurityKeyStore implements SecurityKeyStore {

Expand Down
140 changes: 51 additions & 89 deletions src/main/java/org/opensearch/security/ssl/SecureSSLSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,115 +16,77 @@

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.opensearch.common.settings.SecureSetting;
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Settings;
import org.opensearch.core.common.settings.SecureString;
import org.opensearch.security.setting.SecurableLegacySetting;

import static org.opensearch.security.ssl.util.SSLConfigConstants.DEFAULT_STORE_PASSWORD;

/**
* Container for secured settings (passwords for certs, keystores) and the now deprecated original settings
*/
public final class SecureSSLSettings {
private static final Logger LOG = LogManager.getLogger(SecureSSLSettings.class);

public static final String SECURE_SUFFIX = "_secure";
private static final String PREFIX = "plugins.security.ssl";
private static final String HTTP_PREFIX = PREFIX + ".http";
private static final String TRANSPORT_PREFIX = PREFIX + ".transport";

public enum SSLSetting {
// http settings
SECURITY_SSL_HTTP_PEMKEY_PASSWORD(HTTP_PREFIX + ".pemkey_password"),
SECURITY_SSL_HTTP_KEYSTORE_PASSWORD(HTTP_PREFIX + ".keystore_password"),
SECURITY_SSL_HTTP_KEYSTORE_KEYPASSWORD(HTTP_PREFIX + ".keystore_keypassword"),
SECURITY_SSL_HTTP_TRUSTSTORE_PASSWORD(HTTP_PREFIX + ".truststore_password", DEFAULT_STORE_PASSWORD),

// transport settings
SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD(TRANSPORT_PREFIX + ".pemkey_password"),
SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_PASSWORD(TRANSPORT_PREFIX + ".server.pemkey_password"),
SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_PASSWORD(TRANSPORT_PREFIX + ".client.pemkey_password"),
SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD(TRANSPORT_PREFIX + ".keystore_password"),
SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD(TRANSPORT_PREFIX + ".keystore_keypassword"),
SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_KEYPASSWORD(TRANSPORT_PREFIX + ".server.keystore_keypassword"),
SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_KEYPASSWORD(TRANSPORT_PREFIX + ".client.keystore_keypassword"),
SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD(TRANSPORT_PREFIX + ".truststore_password", DEFAULT_STORE_PASSWORD);

SSLSetting(String insecurePropertyName) {
this(insecurePropertyName, null);
}

SSLSetting(String insecurePropertyName, String defaultValue) {
this.insecurePropertyName = insecurePropertyName;
this.propertyName = String.format("%s%s", this.insecurePropertyName, SECURE_SUFFIX);
this.defaultValue = defaultValue;
}

public final String insecurePropertyName;

public final String propertyName;

public final String defaultValue;

public Setting<SecureString> asSetting() {
return SecureSetting.secureString(this.propertyName, new InsecureFallbackStringSetting(this.insecurePropertyName));
}

public Setting<SecureString> asInsecureSetting() {
return new InsecureFallbackStringSetting(this.insecurePropertyName);
}

public String getSetting(Settings settings) {
return this.getSetting(settings, this.defaultValue);
}

public String getSetting(Settings settings, String defaultValue) {
return Optional.of(this.asSetting().get(settings))
.filter(ss -> ss.length() > 0)
.map(SecureString::toString)
.orElse(defaultValue);
}
}
// http settings
public final static SecurableLegacySetting SECURITY_SSL_HTTP_PEMKEY_PASSWORD = new SecurableLegacySetting(
HTTP_PREFIX + ".pemkey_password"
);
public final static SecurableLegacySetting SECURITY_SSL_HTTP_KEYSTORE_PASSWORD = new SecurableLegacySetting(
HTTP_PREFIX + ".keystore_password"
);
public final static SecurableLegacySetting SECURITY_SSL_HTTP_KEYSTORE_KEYPASSWORD = new SecurableLegacySetting(
HTTP_PREFIX + ".keystore_keypassword"
);
public final static SecurableLegacySetting SECURITY_SSL_HTTP_TRUSTSTORE_PASSWORD = new SecurableLegacySetting(
HTTP_PREFIX + ".truststore_password",
DEFAULT_STORE_PASSWORD
);

// transport settings
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".pemkey_password"
);
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_PASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".server.pemkey_password"
);
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_PASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".client.pemkey_password"
);
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".keystore_password"
);
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".keystore_keypassword"
);
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_KEYPASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".server.keystore_keypassword"
);
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_KEYPASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".client.keystore_keypassword"
);
public final static SecurableLegacySetting SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD = new SecurableLegacySetting(
TRANSPORT_PREFIX + ".truststore_password",
DEFAULT_STORE_PASSWORD
);

private SecureSSLSettings() {}

public static List<Setting<?>> getSecureSettings() {
return Arrays.stream(SSLSetting.values())
return Arrays.stream(SecureSSLSettings.class.getDeclaredFields())
.filter(field -> SecurableLegacySetting.class.isAssignableFrom(field.getType()))
.map(field -> {
try {
return (SecurableLegacySetting) field.get(null);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unable to access field: " + field.getName(), e);

Check warning on line 86 in src/main/java/org/opensearch/security/ssl/SecureSSLSettings.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/security/ssl/SecureSSLSettings.java#L85-L86

Added lines #L85 - L86 were not covered by tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be SettingsException

Comment on lines +80 to +86
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a while to understand this until I figured out that you are using reflection to retrieve static members (as a replacement for enum.values()).

As this is solution is maybe a bit non-obvious, I would recommend to add a comment somewhere to explain the approach.

Another question: With the SecurityManager, this would needed to be wrapped in a doPrivileged() block in order to be able to do reflection. With the new security manager replacement, did this need go away?

}
})
.flatMap(setting -> Stream.of(setting.asSetting(), setting.asInsecureSetting()))
.collect(Collectors.toList());
}

/**
* Alternative to InsecureStringSetting, which doesn't raise an exception if allow_insecure_settings is false, but
* instead log.WARNs the violation. This is to appease a potential cyclic dependency between commons-utils
*/
private static class InsecureFallbackStringSetting extends Setting<SecureString> {
private final String name;

private InsecureFallbackStringSetting(String name) {
super(name, "", s -> new SecureString(s.toCharArray()), Property.Deprecated, Property.Filtered, Property.NodeScope);
this.name = name;
}

public SecureString get(Settings settings) {
if (this.exists(settings)) {
LOG.warn(
"Setting [{}] has a secure counterpart [{}{}] which should be used instead - allowing for legacy SSL setups",
this.name,
this.name,
SECURE_SUFFIX
);
}

return super.get(settings);
}
}
}
Loading
Loading