You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "arturobernalg (via GitHub)" <gi...@apache.org> on 2026/10/17 06:51:02 UTC

[PR] Read the password to encrypt from the standard input when there is no console (fix #10230) [maven]

arturobernalg opened a new pull request, #13589:
URL: https://github.com/apache/maven/pull/13589

   ## What and why
   
   `mvn --encrypt-master-password` and `mvn --encrypt-password` read the password with `System.console()`. When the streams are redirected there is no console, the password stayed `null`, and the command printed an empty `{}`, which makes it unusable from another program (#10230, MNG-8398). I could reproduce it on 3.9.16: `echo myMasterPassword | mvn --encrypt-master-password` prints `{}`.
   
   ## How
   
   A new `MavenCli.readPassword` reads the password from the console and, when there is none, from the first line of the standard input. When no password can be read, or it is empty, the command now fails with `No password was provided` instead of encrypting nothing. The standard input is not closed.
   
   This is for 3.10.x. Maven 4 does not have these options any more, it has `mvnenc`.
   
   ## Tests
   
   `MavenCliTest` covers reading from a redirected input and the missing and empty cases. The console path cannot be mocked, because `java.io.Console` is final. I also built the distribution of this branch: `echo myMasterPassword | mvn --encrypt-master-password` prints the encrypted `{...}` value, and with an empty input it fails with the new message. `maven-embedder` and its dependencies pass (45 tests) and spotless is clean. I did not run the integration tests.
   
   ---
   
   To make clear that you license your contribution under
   the [Apache License Version 2.0, January 2004](https://www.apache.org/licenses/LICENSE-2.0)
   check one of the following:
   
   - [x] I hereby declare this contribution to be licensed under the [Apache License Version 2.0, January 2004](https://www.apache.org/licenses/LICENSE-2.0)
   - [x] I hereby declare that I have filed an [Apache Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Read the password to encrypt from the standard input when there is no console (fix #10230) [maven]

Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg commented on PR #13589:
URL: https://github.com/apache/maven/pull/13589#issuecomment-6232750137

   Switched the decoding of the redirected input to UTF-8 in 09a406b, so it no longer depends on the locale, and added a test with non-ASCII characters (`MavenCliTest#testReadPasswordFromRedirectedInputIsDecodedAsUtf8`). `MavenCliTest` passes.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Read the password to encrypt from the standard input when there is no console (fix #10230) [maven]

Posted by "gnodet-bot (via GitHub)" <gi...@apache.org>.
gnodet-bot commented on code in PR #13589:
URL: https://github.com/apache/maven/pull/13589#discussion_r4302179964


##########
maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java:
##########
@@ -1013,6 +1016,40 @@ private List<File> parseExtClasspath(CliRequest cliRequest) {
         return jars;
     }
 
+    /**
+     * Reads a password from the console and, when there is none because the streams are redirected, from the first
+     * line of the given input.
+     *
+     * @param console the console, or {@code null} if the streams are redirected
+     * @param in the input to read the first line from when there is no console
+     * @param prompt the prompt shown by the console; it is not shown when the password is read from the input, as
+     *               the caller is then not interactive and the prompt would only pollute its output
+     * @return the password, never empty
+     * @throws IOException if the input cannot be read
+     * @throws IllegalStateException if no password could be read, so that an empty one is not encrypted
+     */
+    static String readPassword(Console console, InputStream in, String prompt) throws IOException {
+        String password;
+        if (console != null) {
+            char[] chars = console.readPassword(prompt);
+            password = (chars == null) ? null : String.copyValueOf(chars);
+
+            if (chars != null) {
+                // Sun/Oracle advises to empty the char array
+                java.util.Arrays.fill(chars, ' ');
+            }
+        } else {
+            // do not close the reader, that would close the standard input
+            password = new BufferedReader(new InputStreamReader(in, Charset.defaultCharset())).readLine();

Review Comment:
   `Charset.defaultCharset()` makes the stdin decoding locale-dependent. On a system whose default charset is not UTF-8 (e.g. Windows with Cp1252, or ISO-8859-1 locales), a piped password containing non-ASCII characters would be decoded incorrectly. The test encodes its input with `StandardCharsets.UTF_8` (see the test file, line 88), so the mismatch would not be caught on non-UTF-8 systems. Since `StandardCharsets.UTF_8` is already imported, use it here for consistency and portability.
   
   ```suggestion
               password = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)).readLine();
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Read the password to encrypt from the standard input when there is no console (fix #10230) [maven]

Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg commented on PR #13589:
URL: https://github.com/apache/maven/pull/13589#issuecomment-6232144622

   Both points addressed in 76af3a4. The Javadoc of `readPassword` now has `@param`, `@return` and `@throws` tags, and says that the prompt is not shown when the password is read from the input. I left it unshown on purpose: that case is a non-interactive caller, for example `echo secret | mvn --encrypt-master-password`, and a prompt would only add noise to its output.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Read the password to encrypt from the standard input when there is no console (fix #10230) [maven]

Posted by "cstamas (via GitHub)" <gi...@apache.org>.
cstamas merged PR #13589:
URL: https://github.com/apache/maven/pull/13589


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Read the password to encrypt from the standard input when there is no console (fix #10230) [maven]

Posted by "gnodet-bot (via GitHub)" <gi...@apache.org>.
gnodet-bot commented on code in PR #13589:
URL: https://github.com/apache/maven/pull/13589#discussion_r4301819637


##########
maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java:
##########
@@ -1013,6 +1016,34 @@ private List<File> parseExtClasspath(CliRequest cliRequest) {
         return jars;
     }
 
+    /**
+     * Reads a password from the console and, when there is none because the streams are redirected, from the first
+     * line of the given input.
+     *
+     * @throws IllegalStateException if no password could be read, so that an empty one is not encrypted
+     */
+    static String readPassword(Console console, InputStream in, String prompt) throws IOException {
+        String password;
+        if (console != null) {
+            char[] chars = console.readPassword(prompt);
+            password = (chars == null) ? null : String.copyValueOf(chars);
+
+            if (chars != null) {
+                // Sun/Oracle advises to empty the char array
+                java.util.Arrays.fill(chars, ' ');
+            }
+        } else {
+            // do not close the reader, that would close the standard input
+            password = new BufferedReader(new InputStreamReader(in, Charset.defaultCharset())).readLine();

Review Comment:
   ⚠️ **`prompt` is silently ignored in the `else` branch.**
   
   When there is no console, the method reads from `in` but never displays the prompt to the user. This is a silent regression compared to the old code, which at least called `cons.readPassword("Password: ")` when the console was present. In the fallback path the prompt string is simply dropped — the user gets no indication that they should type a password.
   
   If there's no portable way to print to the terminal in this context (since `System.console()` is null), at minimum the Javadoc should document that `prompt` is unused when `console` is `null`.



##########
maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java:
##########
@@ -1013,6 +1016,34 @@ private List<File> parseExtClasspath(CliRequest cliRequest) {
         return jars;
     }
 
+    /**
+     * Reads a password from the console and, when there is none because the streams are redirected, from the first
+     * line of the given input.
+     *
+     * @throws IllegalStateException if no password could be read, so that an empty one is not encrypted
+     */
+    static String readPassword(Console console, InputStream in, String prompt) throws IOException {

Review Comment:
   📝 **Javadoc is incomplete.**
   
   - `@throws IOException` is declared in the method signature but not documented.
   - `@param` tags are missing for all three parameters (`console`, `in`, `prompt`).
   - `@return` tag is missing.
   
   ```suggestion
       /**
        * Reads a password from the console and, when there is none because the streams are redirected, from the first
        * line of the given input.
        *
        * @param console the system console, or {@code null} when streams are redirected
        * @param in the input stream to fall back to when {@code console} is {@code null}
        * @param prompt the prompt to display when reading from the console (ignored when {@code console} is {@code null})
        * @return the password read from the console or input stream
        * @throws IOException if an I/O error occurs while reading from the input stream
        * @throws IllegalStateException if no password could be read, so that an empty one is not encrypted
        */
       static String readPassword(Console console, InputStream in, String prompt) throws IOException {
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org