From 6ddcf0bdaacd04605173b2bc663f8ddd21f5e19c Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Fri, 11 Apr 2025 14:52:22 -0700 Subject: [PATCH 1/3] Use terminal reader in keystore add command 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 --- .../keystore/AddStringKeyStoreCommand.java | 9 ++---- .../AddStringKeyStoreCommandTests.java | 30 ++++++------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java b/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java index a7ea6dcf7ce74..64dce2fe92003 100644 --- a/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java +++ b/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java @@ -19,12 +19,12 @@ 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.io.Reader; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; @@ -47,11 +47,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 settings = arguments.values(options); @@ -64,7 +59,7 @@ protected void executeCommand(Terminal terminal, OptionSet options, Environment final Closeable closeable; final CheckedFunction 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; diff --git a/distribution/tools/keystore-cli/src/test/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommandTests.java b/distribution/tools/keystore-cli/src/test/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommandTests.java index 412624be1d506..1b368a7c38e0e 100644 --- a/distribution/tools/keystore-cli/src/test/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommandTests.java +++ b/distribution/tools/keystore-cli/src/test/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommandTests.java @@ -18,18 +18,13 @@ 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 @@ protected Command newCommand() { protected Environment createEnv(OptionSet options, ProcessInfo processInfo) throws UserException { return env; } - - @Override - InputStream getStdin() { - return input; - } }; } @@ -167,7 +157,7 @@ public void testStdinShort() throws Exception { 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 void testStdinLong() throws Exception { 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 void testStdinNoInput() throws Exception { 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 void testStdinInputWithLineBreaks() throws Exception { 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 void testStdinInputWithCarriageReturn() throws Exception { 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 void testStdinWithMultipleValues() throws Exception { 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 void testAddUtf8String() throws Exception { 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 void testAddToUnprotectedKeystore() throws Exception { execute("foo"); assertSecureString("foo", "bar", password); } - - void setInput(String inputStr) { - input = new ByteArrayInputStream(inputStr.getBytes(StandardCharsets.UTF_8)); - } } From 878622430bb1efd85b6bcec6d7ec70c1dc123dd2 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Fri, 11 Apr 2025 14:54:23 -0700 Subject: [PATCH 2/3] Update docs/changelog/126729.yaml --- docs/changelog/126729.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 docs/changelog/126729.yaml diff --git a/docs/changelog/126729.yaml b/docs/changelog/126729.yaml new file mode 100644 index 0000000000000..0a5e296e4c250 --- /dev/null +++ b/docs/changelog/126729.yaml @@ -0,0 +1,6 @@ +pr: 126729 +summary: Use terminal reader in keystore add command +area: Infra/CLI +type: bug +issues: + - 98115 From 7b10cd8c9631b3e4b666b11b440f6a91e4e1e54b Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Fri, 11 Apr 2025 22:03:05 +0000 Subject: [PATCH 3/3] [CI] Auto commit changes from spotless --- .../elasticsearch/cli/keystore/AddStringKeyStoreCommand.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java b/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java index 64dce2fe92003..7d89879958dba 100644 --- a/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java +++ b/distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddStringKeyStoreCommand.java @@ -22,10 +22,7 @@ import java.io.CharArrayWriter; import java.io.Closeable; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.Reader; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List;