如何确定客户端 SSH 连接是否具有与之关联的 tty?

如何确定客户端 SSH 连接是否具有与之关联的 tty?

我正在编写一个 PAM 模块来处理身份验证(服务器端 - sshd),并且我必须知道 ssh 客户端是否是 tty(交互式)或不是(非交互式)。

有人有线索吗?

答案1

您可以尝试检查$SSH_TTY,但这并不可靠。

$ ssh -6 fedoraplug.local
Last login: ......
-$ echo "${!SSH*}"
SSH_CLIENT SSH_CONNECTION SSH_TTY
-$ exit
$ ssh -6 fedoraplug.local 'echo "${!SSH*}"'
SSH_CLIENT SSH_CONNECTION
$ ssh -t -6 fedoraplug.local 'echo "${!SSH*}"'
SSH_CLIENT SSH_CONNECTION SSH_TTY
Connection to fedoraplug.local closed.

答案2

在客户端,您可以使用tty命令(手册页在这里)。假设会话是交互式的,此命令将返回类似以下内容:

breakthrough@lt0:~$ tty
/dev/pts/0

然而,如果客户不是interactive/tty-based,该命令将返回:

not a tty

实际上写作PAM 模块虽然tty提供了一些可以使用的退出代码,但您不太可能tty直接将该命令用作系统调用;相反,您应该看看ttyname()(或ttyname_r())函数

您可以看到以下示例实现这个函数在这里涵盖了一些一般用例。虽然查看是否返回了有效的 ttyname 就足够了,但最佳做法是检查是否引发错误ENOTTY,表明传递的文件描述符不引用终端设备。

答案3

如果你使用 C 语言编写:

man isatty

描述 isatty() 函数测试 fd 是否是指向终端的打开文件描述符。

返回值如果 fd 是指向终端的打开文件描述符,则 isatty() 返回 1;否则返回 0,并设置 errno 以指示错误。

相关内容