Use terminal reader in keystore add command (#126729) (#126963)

When reading a string value from stdin the keystore add command
currently looks directly at stdin. However, stdin may also be consumed
while reading the keystore password. This commit changes the add command
to use the reader from the termainl instead of looking at stdin
directly.

closes #98115

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Ryan Ernst 2025-04-17 14:01:34 -07:00 committed by GitHub
parent 11cca8cc39
commit 09a5c67884
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 17 additions and 31 deletions

View file

@ -19,13 +19,10 @@ import org.elasticsearch.common.settings.KeyStoreWrapper;
import org.elasticsearch.core.CheckedFunction;
import org.elasticsearch.env.Environment;
import java.io.BufferedReader;
import java.io.CharArrayWriter;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.io.Reader;
import java.util.Arrays;
import java.util.List;
@ -47,11 +44,6 @@ class AddStringKeyStoreCommand extends BaseKeyStoreCommand {
this.arguments = parser.nonOptions("setting names");
}
// pkg private so tests can manipulate
InputStream getStdin() {
return System.in;
}
@Override
protected void executeCommand(Terminal terminal, OptionSet options, Environment env) throws Exception {
final List<String> settings = arguments.values(options);
@ -64,7 +56,7 @@ class AddStringKeyStoreCommand extends BaseKeyStoreCommand {
final Closeable closeable;
final CheckedFunction<String, char[], IOException> valueSupplier;
if (options.has(stdinOption)) {
final BufferedReader stdinReader = new BufferedReader(new InputStreamReader(getStdin(), StandardCharsets.UTF_8));
final Reader stdinReader = terminal.getReader();
valueSupplier = s -> {
try (CharArrayWriter writer = new CharArrayWriter()) {
int c;

View file

@ -18,18 +18,13 @@ import org.elasticsearch.cli.UserException;
import org.elasticsearch.common.settings.KeyStoreWrapper;
import org.elasticsearch.env.Environment;
import java.io.ByteArrayInputStream;
import java.io.CharArrayWriter;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasToString;
public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
InputStream input;
@Override
protected Command newCommand() {
return new AddStringKeyStoreCommand() {
@ -37,11 +32,6 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
protected Environment createEnv(OptionSet options, ProcessInfo processInfo) throws UserException {
return env;
}
@Override
InputStream getStdin() {
return input;
}
};
}
@ -167,7 +157,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
String password = "keystorepassword";
KeyStoreWrapper.create().save(env.configDir(), password.toCharArray());
terminal.addSecretInput(password);
setInput("secret value 1");
terminal.addSecretInput("secret value 1");
execute("-x", "foo");
assertSecureString("foo", "secret value 1", password);
}
@ -176,7 +166,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
String password = "keystorepassword";
KeyStoreWrapper.create().save(env.configDir(), password.toCharArray());
terminal.addSecretInput(password);
setInput("secret value 2");
terminal.addSecretInput("secret value 2");
execute("--stdin", "foo");
assertSecureString("foo", "secret value 2", password);
}
@ -185,7 +175,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
String password = "keystorepassword";
KeyStoreWrapper.create().save(env.configDir(), password.toCharArray());
terminal.addSecretInput(password);
setInput("");
terminal.addSecretInput("");
execute("-x", "foo");
assertSecureString("foo", "", password);
}
@ -194,7 +184,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
String password = "keystorepassword";
KeyStoreWrapper.create().save(env.configDir(), password.toCharArray());
terminal.addSecretInput(password);
setInput("Typedthisandhitenter\n");
terminal.addSecretInput("Typedthisandhitenter\n");
execute("-x", "foo");
assertSecureString("foo", "Typedthisandhitenter", password);
}
@ -203,7 +193,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
String password = "keystorepassword";
KeyStoreWrapper.create().save(env.configDir(), password.toCharArray());
terminal.addSecretInput(password);
setInput("Typedthisandhitenter\r");
terminal.addSecretInput("Typedthisandhitenter\r");
execute("-x", "foo");
assertSecureString("foo", "Typedthisandhitenter", password);
}
@ -212,7 +202,9 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
final String password = "keystorepassword";
KeyStoreWrapper.create().save(env.configDir(), password.toCharArray());
terminal.addSecretInput(password);
setInput("bar1\nbar2\nbar3");
terminal.addSecretInput("bar1");
terminal.addSecretInput("bar2");
terminal.addSecretInput("bar3");
execute(randomFrom("-x", "--stdin"), "foo1", "foo2", "foo3");
assertSecureString("foo1", "bar1", password);
assertSecureString("foo2", "bar2", password);
@ -228,7 +220,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
for (int i = 0; i < stringSize; i++) {
secretChars.write((char) randomIntBetween(129, 2048));
}
setInput(secretChars.toString());
terminal.addSecretInput(secretChars.toString());
execute("-x", "foo");
assertSecureString("foo", secretChars.toString(), password);
}
@ -265,8 +257,4 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
execute("foo");
assertSecureString("foo", "bar", password);
}
void setInput(String inputStr) {
input = new ByteArrayInputStream(inputStr.getBytes(StandardCharsets.UTF_8));
}
}

View file

@ -0,0 +1,6 @@
pr: 126729
summary: Use terminal reader in keystore add command
area: Infra/CLI
type: bug
issues:
- 98115