From cac9fe4d866db93d390f63902475b81a25337644 Mon Sep 17 00:00:00 2001 From: Dan Hermann Date: Thu, 14 Nov 2019 09:39:28 -0600 Subject: [PATCH] [7.x] Validate monitoring password at parse time (#49083) --- .../exporter/http/HttpExporter.java | 51 ++++++++++++++----- .../exporter/http/HttpExporterTests.java | 20 ++++---- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java index 9c1f09f4534..bb1d42afc67 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java @@ -222,7 +222,45 @@ public class HttpExporter extends Exporter { */ public static final Setting.AffixSetting AUTH_PASSWORD_SETTING = Setting.affixKeySetting("xpack.monitoring.exporters.","auth.password", - (key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered)); + (key) -> Setting.simpleString(key, + new Setting.Validator() { + @Override + public void validate(String password) { + // no password validation that is independent of other settings + } + + @Override + public void validate(String password, Map, Object> settings) { + final String namespace = + HttpExporter.AUTH_PASSWORD_SETTING.getNamespace( + HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(key)); + final String username = + (String) settings.get(AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace)); + + // username is required for any auth + if (Strings.isNullOrEmpty(username)) { + if (Strings.isNullOrEmpty(password) == false) { + throw new IllegalArgumentException( + "[" + AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(namespace).getKey() + "] without [" + + AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace).getKey() + "]"); + } + } + } + + @Override + public Iterator> settings() { + final String namespace = + HttpExporter.AUTH_PASSWORD_SETTING.getNamespace( + HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(key)); + final List> settings = Collections.singletonList( + HttpExporter.AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace)); + return settings.iterator(); + } + + }, + Property.Dynamic, + Property.NodeScope, + Property.Filtered)); /** * The SSL settings. * @@ -626,17 +664,6 @@ public class HttpExporter extends Exporter { final String username = AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings()); final String password = AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings()); - // username is required for any auth - if (Strings.isNullOrEmpty(username)) { - if (Strings.isNullOrEmpty(password) == false) { - throw new SettingsException( - "[" + AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(config.name()).getKey() + "] without [" + - AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(config.name()).getKey() + "]"); - } - // nothing to configure; default situation for most users - return null; - } - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java index 3325c7190b0..52227b780e6 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java @@ -226,17 +226,17 @@ public class HttpExporterTests extends ESTestCase { public void testExporterWithPasswordButNoUsername() { final String expected = "[xpack.monitoring.exporters._http.auth.password] without [xpack.monitoring.exporters._http.auth.username]"; - final Settings.Builder builder = Settings.builder() - .put("xpack.monitoring.exporters._http.type", HttpExporter.TYPE) - .put("xpack.monitoring.exporters._http.host", "localhost:9200") - .put("xpack.monitoring.exporters._http.auth.password", "_pass"); + final String prefix = "xpack.monitoring.exporters._http"; + final Settings settings = Settings.builder() + .put(prefix + ".type", HttpExporter.TYPE) + .put(prefix + ".host", "localhost:9200") + .put(prefix + ".auth.password", "_pass") + .build(); - final Config config = createConfig(builder.build()); - - final SettingsException exception = expectThrows(SettingsException.class, - () -> new HttpExporter(config, sslService, threadContext)); - - assertThat(exception.getMessage(), equalTo(expected)); + final IllegalArgumentException e = expectThrows( + IllegalArgumentException.class, + () -> HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(prefix + ".auth.password").get(settings)); + assertThat(e, hasToString(containsString(expected))); } public void testExporterWithUsernameButNoPassword() {