Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate monitoring password at parse time #47740

Merged
merged 8 commits into from
Nov 13, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,45 @@ public Iterator<Setting<?>> settings() {
*/
public static final Setting.AffixSetting<String> 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<String>() {
@Override
public void validate(String password) {

Copy link
Contributor

@jakelandis jakelandis Oct 14, 2019

Choose a reason for hiding this comment

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

Can you add a comment to why this is empty ?

edit: i mean a comment in the code :)

}

@Override
public void validate(String password, Map<Setting<?>, Object> settings) {
Copy link
Member

Choose a reason for hiding this comment

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

Don't we need similar validation in AUTH_USERNAME_SETTING? Otherwise we could have username exist but no password?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rjernst, that validation was added in #47821.

Copy link
Member

Choose a reason for hiding this comment

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

Ah ok, thanks. i guess this PR is out of date with master?

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 SettingsException(
"[" + AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(namespace).getKey() + "] without [" +
Copy link
Contributor

Choose a reason for hiding this comment

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

should the test assert this message is in the error too ?

Copy link
Contributor

Choose a reason for hiding this comment

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

NMVD I see it now .. it already did. sorry for the noise.

AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace).getKey() + "]");
}
}
}

@Override
public Iterator<Setting<?>> settings() {
final String namespace =
HttpExporter.AUTH_PASSWORD_SETTING.getNamespace(
HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(key));
final List<Setting<?>> settings = List.of(
HttpExporter.AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace));
return settings.iterator();
}

},
Property.Dynamic,
Property.NodeScope,
Property.Filtered));
/**
* The SSL settings.
*
Expand Down Expand Up @@ -574,17 +612,6 @@ private static CredentialsProvider createCredentialsProvider(final Config config
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));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,17 +225,23 @@ public void testExporterWithEmptyHeaders() {
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 Config config = createConfig(builder.build());
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 SettingsException exception = expectThrows(SettingsException.class,
() -> new HttpExporter(config, sslService, threadContext));
final IllegalArgumentException e = expectThrows(
IllegalArgumentException.class,
() -> HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(prefix + ".auth.password").get(settings));
assertThat(
e,
hasToString(
containsString("Failed to parse value [_pass] for setting [xpack.monitoring.exporters._http.auth.password]")));
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, I just realized this will place a password in the log file. Can you log an enhancement to help prevent this ?


assertThat(exception.getMessage(), equalTo(expected));
assertThat(e.getCause(), instanceOf(SettingsException.class));
assertThat(e.getCause(), hasToString(containsString(expected)));
}

public void testExporterWithUnknownBlacklistedClusterAlerts() {
Expand Down