From 3e42cbfd7b6c1f3b01f1b2f09ef0c740a8840e88 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 5 Apr 2023 16:02:01 -0500 Subject: [PATCH] Fixes #9556 - Better prompt for input on Password (#9557) * Fixes #9556 - Better prompt for input on Password * Allow blank username (results in no CRYPT output) * Error on blank password during input * Fixing PasswordTest.testCommandLineUsage * Changes from review Signed-off-by: Joakim Erdfelt --- .../eclipse/jetty/util/security/Password.java | 79 ++++++++++++++++--- .../jetty/util/security/PasswordTest.java | 4 +- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java index 2b13ba935105..1da9c8473de8 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java @@ -13,10 +13,14 @@ package org.eclipse.jetty.util.security; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Locale; +import org.eclipse.jetty.util.StringUtil; + /** * Password utility class. * @@ -230,21 +234,76 @@ public static Password getPassword(String realm, String dft, String promptDft) return new Password(passwd); } - public static void main(String[] arg) + public static void main(String[] args) throws IOException { - if (arg.length != 1 && arg.length != 2) + boolean promptArgs = false; + String argUser = null; + String argPassword = null; + + for (String arg: args) + { + if (arg.equals("--prompt")) + { + promptArgs = true; + // ignore any other args + break; + } + + if (argUser == null) + { + argUser = arg; + promptArgs = true; + } + else + { + if (!arg.equals("?")) + promptArgs = false; + argPassword = arg; + } + } + + if (promptArgs) + { + System.out.print("Username"); + if (StringUtil.isNotBlank(argUser)) + System.out.printf("[%s]", argUser); + System.out.print(": "); + + BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); + String inputUser = input.readLine(); + if (StringUtil.isNotBlank(inputUser)) + argUser = inputUser; + + System.out.print("Password: "); + argPassword = input.readLine(); + if (StringUtil.isBlank(argPassword)) + { + System.err.println("ERROR: blank passwords not supported"); + System.exit(1); + } + } + else if (StringUtil.isBlank(argUser)) { - System.err.println("Usage - java " + Password.class.getName() + " [] "); - System.err.println("If the password is ?, the user will be prompted for the password"); + System.err.printf("Usage - java %s [] [] --prompt%n", Password.class.getName()); + System.err.printf("Argument options:%n"); + System.err.printf(" %s%n", Password.class.getName()); + System.err.printf(" No arguments, will show this help%n"); + System.err.printf(" %s %n", Password.class.getName()); + System.err.printf(" username only, will prompt for arguments%n"); + System.err.printf(" %s ?%n", Password.class.getName()); + System.err.printf(" username with question mark password, will prompt for arguments%n"); + System.err.printf(" %s %n", Password.class.getName()); + System.err.printf(" username with password, will produce obfuscation results%n"); + System.err.printf(" %s --prompt%n", Password.class.getName()); + System.err.printf(" will prompt for arguments%n"); System.exit(1); } - String p = arg[arg.length == 1 ? 0 : 1]; - Password pw = new Password(p); - System.err.println(pw.toString()); + + Password pw = new Password(argPassword); System.err.println(obfuscate(pw.toString())); - System.err.println(Credential.MD5.digest(p)); - if (arg.length == 2) - System.err.println(Credential.Crypt.crypt(arg[0], pw.toString())); + System.err.println(Credential.MD5.digest(argPassword)); + if (StringUtil.isNotBlank(argUser)) + System.err.println(Credential.Crypt.crypt(argUser, pw.toString())); System.exit(0); } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java index fee0946cd823..a484ba7757e4 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java @@ -19,6 +19,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.eclipse.jetty.toolchain.test.MavenPaths; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.junit.jupiter.api.Test; @@ -62,7 +63,7 @@ public void testObfuscateUnicode() public void testCommandLineUsage() throws IOException, InterruptedException { ProcessBuilder passwordBuilder = new ProcessBuilder() - .directory(MavenTestingUtils.getTargetDir()) + .directory(MavenPaths.targetDir().toFile()) .command("java", "-cp", MavenTestingUtils.getTargetPath("classes").toString(), Password.class.getName(), @@ -79,7 +80,6 @@ public void testCommandLineUsage() throws IOException, InterruptedException assertThat("Non-error exit code: " + output, exitCode, is(0)); assertThat("Output", output, not(containsString("Exception"))); assertThat("Output", output, allOf( - containsString("password"), containsString("OBF:"), containsString("MD5:"), containsString("CRYPT:")