0

I'd like to use checkpassword-pam in a java application. It's a very simple executable that reads a username and password from fd 3 and then verifies it. The protocol is described here.

In a shell you'd use it like this:

# echo -e "username\0password\0timestamp\0" \
| checkpassword-pam -s SERVICE \
--debug --stdout -- /usr/bin/id 3<&0

How would I do this from a java application ? I'm sure it can't be done through standard Java, but perhaps accessing posix api via jna...

Tom
  • 55,743
  • 3
  • 27
  • 35
  • 1
    You can run programs using `ProcessBuilder`/`Runtime.getRuntime().exec()`. You can then control `stdin`/`stdout`. – dan1st Feb 07 '21 at 22:58

2 Answers2

0

In order to do what you want you can use the Runtime class, using Runtime.getRuntime(), and the exec method of the runtime to run a command from inside your Java program. From this, you can use the Process class to control the standard input and output of that shell command, essentially simulating that the user typed in the command from their console. You can look here for more help

  • The question is specifically about writing to a non-standard file descriptor (3) and not stdin. – Tom Feb 08 '21 at 09:21
0

To answer my own question: a simple shell command can redirect fd 3 to stdin.

    try {
        Process p = new ProcessBuilder("/bin/sh", "-c" , "exec /usr/bin/checkpassword-pam -s sshd 3<&0 /usr/bin/id").redirectErrorStream(true).start();
        OutputStream os = p.getOutputStream();
        os.write(userName.getBytes(Charset.defaultCharset()));
        os.write(0);
        os.write(password.getBytes(Charset.defaultCharset()));
        os.write(0);
        os.close();
        p.waitFor(10, TimeUnit.SECONDS);
        if (p.exitValue() == 0) {
            logger.info("authenticated user {}", IOUtils.read(p.getInputStream()).trim());
            result = true;
        } else {
            logger.info("authenticated failed for user {}", userName);
            result = false;
        }
    } catch (IOException | InterruptedException e) {
        logger.error("failed to authenticate user {}",  userName, e);
        result = false;
    }
Tom
  • 55,743
  • 3
  • 27
  • 35