max23
max23

Reputation: 49

Java ProcessBuilder - Provide user password to process, but don't display the password in the terminal

I need to copy a file from a Docker volume to the host machine. To do so I need to provide my user password over the terminal. That works, but the problem is that, when I type in the password, it is visible at the terminal, as you can see in the provided screenshot.

I think this behavior comes from: pb.inheritIO();

I want that the password is not visible when I type it in.

Normally, e.g. on Ubuntu terminal, when you type in your password, the password is not shown. I would like to have this behavior for my Java program too. How to do that?

Code:

// Process Builder
ProcessBuilder pb = new ProcessBuilder();
String cmd = "cp";
String tableName = "password_entries.ibd";
String source = "/var/lib/docker/volumes/d74a425c8728e5333a3472860c2b62a3e47a0b5655dd44cce1b4c47ac2c3b6b8/_data/password_safe/";
String target = ".";

try {
    pb.inheritIO();
    // cp to host
    pb.command("sudo", "-S", cmd, source + tableName, target);
    pb.start().waitFor();
} catch (IOException | InterruptedException e) {
    throw new RuntimeException(e);
}

password

Edit: When I don't use pb.inheritIO(); the program starts, but doesn't terminate.

Code:

ProcessBuilder pb = new ProcessBuilder();
String cmd = "cp";
String tableName = "password_entries.ibd";
String source = "/var/lib/docker/volumes/d74a425c8728e5333a3472860c2b62a3e47a0b5655dd44cce1b4c47ac2c3b6b8/_data/password_safe/";
String target = ".";

try {
     //pb.inheritIO();
     Process p;

     // cp to host
     pb.command("sudo", "-S", cmd, source + tableName, target);
     p = pb.start();
     OutputStream os = p.getOutputStream();
     PrintWriter writer = new PrintWriter(os, true);
     writer.write("test\n");
     System.out.println(p.waitFor());
} catch (IOException | InterruptedException e) {
     throw new RuntimeException(e);
}

Upvotes: -1

Views: 73

Answers (1)

g00se
g00se

Reputation: 4292

Here's an example that's pretty close to your use case. It works for me. Note you ideally need to use independent threads to prevent lockups in the streams of the Process:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

public class Grandstream {
    public static void main(String[] args) throws Exception {
        Process p = new ProcessBuilder("sudo", "apt", "update").start();
        ProcessReader.read(p.getInputStream());
        OutputStream out = p.getOutputStream();
        out.write("password\n".getBytes(StandardCharsets.UTF_8));
        ProcessReader.read(p.getErrorStream());
        int exitValue = p.waitFor();
        System.exit(exitValue);
    }

    static class ProcessReader {

        static void read(InputStream in) {
            new Thread(() -> {
                try {
                    in.transferTo(System.out);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }
    }
}

Upvotes: 0

Related Questions