Support realm validation when Keystore is closed (elastic/x-pack-elasticsearch#3096)
If the KeyStoreWrapper is closed, then we cannot validate secure settings (because we no longer have access to them) The Realm group setting uses the "validate" method to ensure that child settings are correct, but it must ignore secure settings as it might get called after startup (e.g. during a settings diff) Original commit: elastic/x-pack-elasticsearch@b30db6bc62
This commit is contained in:
parent
90a1da82ee
commit
c2ff796fea
|
@ -16,6 +16,7 @@ import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.AbstractScopedSettings;
|
import org.elasticsearch.common.settings.AbstractScopedSettings;
|
||||||
|
import org.elasticsearch.common.settings.SecureSetting;
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.xpack.extensions.XPackExtension;
|
import org.elasticsearch.xpack.extensions.XPackExtension;
|
||||||
|
@ -167,6 +168,11 @@ public class RealmSettings {
|
||||||
// perfectly aligned
|
// perfectly aligned
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't validate secure settings because they might have been cleared already
|
||||||
|
settings = Settings.builder().put(settings, false).build();
|
||||||
|
validSettings.removeIf(s -> s instanceof SecureSetting);
|
||||||
|
|
||||||
Set<Setting<?>> settingSet = new HashSet<>(validSettings);
|
Set<Setting<?>> settingSet = new HashSet<>(validSettings);
|
||||||
settingSet.add(TYPE_SETTING);
|
settingSet.add(TYPE_SETTING);
|
||||||
settingSet.add(ENABLED_SETTING);
|
settingSet.add(ENABLED_SETTING);
|
||||||
|
|
|
@ -11,6 +11,8 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||||
|
import org.elasticsearch.common.settings.SecureSettings;
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
@ -94,6 +96,13 @@ public class RealmSettingsTests extends ESTestCase {
|
||||||
assertError("pki3", realm.build());
|
assertError("pki3", realm.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPkiRealmWithClosedSecurePasswordValidatesSuccessfully() throws Exception {
|
||||||
|
final Settings.Builder builder = pkiRealm("pki4", true);
|
||||||
|
builder.getSecureSettings().close();
|
||||||
|
final Settings settings = builder.build();
|
||||||
|
assertSuccess(settings);
|
||||||
|
}
|
||||||
|
|
||||||
public void testSettingsWithMultipleRealmsValidatesSuccessfully() throws Exception {
|
public void testSettingsWithMultipleRealmsValidatesSuccessfully() throws Exception {
|
||||||
final Settings settings = Settings.builder()
|
final Settings settings = Settings.builder()
|
||||||
.put(fileRealm("file1").build())
|
.put(fileRealm("file1").build())
|
||||||
|
@ -201,7 +210,7 @@ public class RealmSettingsTests extends ESTestCase {
|
||||||
if (useTrustStore) {
|
if (useTrustStore) {
|
||||||
builder.put("truststore.path", randomAlphaOfLengthBetween(8, 32));
|
builder.put("truststore.path", randomAlphaOfLengthBetween(8, 32));
|
||||||
SecuritySettingsSource.addSecureSettings(builder, secureSettings -> {
|
SecuritySettingsSource.addSecureSettings(builder, secureSettings -> {
|
||||||
secureSettings.setString("keystore.secure_password", randomAlphaOfLength(8));
|
secureSettings.setString("truststore.secure_password", randomAlphaOfLength(8));
|
||||||
});
|
});
|
||||||
builder.put("truststore.algorithm", randomAlphaOfLengthBetween(6, 10));
|
builder.put("truststore.algorithm", randomAlphaOfLengthBetween(6, 10));
|
||||||
} else {
|
} else {
|
||||||
|
@ -254,7 +263,29 @@ public class RealmSettingsTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Settings.Builder realm(String name, Settings.Builder settings) {
|
private Settings.Builder realm(String name, Settings.Builder settings) {
|
||||||
return settings.normalizePrefix(realmPrefix(name));
|
final String prefix = realmPrefix(name);
|
||||||
|
final MockSecureSettings secureSettings = normaliseSecureSettingPrefix(prefix, settings.getSecureSettings());
|
||||||
|
final Settings.Builder builder = Settings.builder().put(settings.normalizePrefix(prefix).build(), false);
|
||||||
|
if (secureSettings != null) {
|
||||||
|
builder.setSecureSettings(secureSettings);
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MockSecureSettings normaliseSecureSettingPrefix(String prefix, SecureSettings settings) {
|
||||||
|
if (settings == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (settings instanceof MockSecureSettings) {
|
||||||
|
final MockSecureSettings source = (MockSecureSettings) settings;
|
||||||
|
final MockSecureSettings target = new MockSecureSettings();
|
||||||
|
for (String key : settings.getSettingNames()) {
|
||||||
|
target.setString(prefix + key, source.getString(key).toString());
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Source settings " + settings.getClass() + " is not a " + MockSecureSettings.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String realmPrefix(String name) {
|
private String realmPrefix(String name) {
|
||||||
|
|
Loading…
Reference in New Issue