使用 Java 中的 checkpassword-pam

问题描述

我想在 Java 应用程序中使用 checkpassword-pam。这是一个非常简单的可执行文件,它从 fd 3 读取用户名和密码,然后对其进行验证。 协议描述为here

在 shell 中,你会像这样使用它:

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

我将如何从 Java 应用程序执行此操作? 我确定它不能通过标准 Java 来完成,但也许可以通过 jna 访问 posix api...

解决方法

回答我自己的问题:一个简单的 shell 命令可以将 fd 3 重定向到 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;
    }
,

为了执行您想要的操作,您可以使用 Runtime 类、使用 Runtime.getRuntime() 和运行时的 exec 方法从 Java 程序内部运行命令。由此,您可以使用 Process 类来控制该 shell 命令的标准输入和输出,实质上模拟用户从其控制台键入命令。您可以向here寻求更多帮助