如何在笔记本电脑盖关闭时禁用指纹验证?

如何在笔记本电脑盖关闭时禁用指纹验证?

我最近成功地在我的笔记本电脑上进行了指纹验证,这要归功于汇顶科技Linux开发Discord 社区以及 github 用户 Infinytum 和 Michael Teuscher 的driver/538d分支https://github.com/infinytum/libfprint/tree/driver/538d

但在启用指纹登录fprintd-enrollsudo访问后,sudo pam-auth-update我注意到一个问题:

每当我使用外接显示器工作时,盖子关闭时,我必须等待指纹验证超时才能输入密码sudo,这会导致几秒钟的延迟:

username@host:~/ron/libfprint$ sudo ls
Place your finger on the fingerprint reader
Place your finger on the reader again
Place your finger on the reader again
Place your finger on the reader again
Verification timed out
[sudo] password for username:

如何在笔记本电脑盖关闭时禁用指纹验证,以便我sudo无需等待指纹超时即可输入密码?

答案1

要在笔记本电脑盖子关闭时禁用指纹身份验证,并在重新打开时重新启用,我们将使用acpid将事件绑定button/lid.*到自定义脚本,该脚本将fprintd在盖子关闭时停止并屏蔽服务,并在盖子关闭时取消屏蔽并启动fprintd服务盖子打开。

我们还通过测试 的内容来检查 HDMI 电缆是否已连接/sys/class/drm/card0-HDMI-A-1/status

请按照以下步骤操作:

  1. 创建/etc/acpi/laptop-lid.sh包含以下内容的文件:

    #!/bin/bash
    
    lock=$HOME/fprint-disabled
    
    if grep -Fq closed /proc/acpi/button/lid/LID0/state &&
       grep -Fxq connected /sys/class/drm/card0-HDMI-A-1/status
    then
      touch "$lock"
      systemctl stop fprintd
      systemctl mask fprintd
    elif [ -f "$lock" ]
    then
      systemctl unmask fprintd
      systemctl start fprintd
      rm "$lock"
    fi
    
    
  2. 使文件可执行

    chmod +x /etc/acpi/laptop-lid.sh
    
  3. 创建/etc/acpi/events/laptop-lid包含以下内容的文件:

    event=button/lid.*
    action=/etc/acpi/laptop-lid.sh
    
  4. 使用以下命令重新启动acpid服务:

    sudo service acpid restart
    

现在只有当盖子打开时才会使用指纹。

为了fprintd在笔记本电脑关闭时断开/重新连接时恢复服务的正确状态,您可以从systemdinit 文件调用上述脚本。执行此操作的步骤如下:

  1. /etc/systemd/system/laptop-lid.service创建一个包含以下内容的文件:

    [Unit]
    Description=Laptop Lid
    After=suspend.target
    
    [Service]
    ExecStart=/etc/acpi/laptop-lid.sh
    
    [Install]
    WantedBy=multi-user.target
    WantedBy=suspend.target
    
  2. 重新加载 systemd 配置文件

    sudo systemctl daemon-reload
    
  3. 启动服务

    sudo systemctl start laptop-lid.service
    
  4. 启用该服务,使其在启动时自动启动

    sudo systemctl enable laptop-lid.service
    

现在,即使在计算机关闭时连接/断开连接,状态也应该正确。

用于在答案中创建代码的参考:

答案2

Linux 中的指纹验证通过聚丙烯酰胺,有pam_fprintd.so与服务对话的模块fprintd。当fprintd服务无法工作时,pam_fprintd无法与其通信,并且 PAM 身份验证会跳到配置中的下一个模块。但另一个 PAM 模块也可以跳过pam_fprintd

假设您有/etc/pam.d/system-auth以下内容:

auth            sufficient      pam_fprintd.so
auth            required        pam_unix.so

您的真实配置可能不同,甚至位于不同的位置,但最重要的是pam_fprintdpam_unix,它执行密码身份验证。

您可以做的就是在配置中添加另一个条目,pam_fprintd.so如果 LID 关闭,则在该条目之前会跳过该模块。实现这一目标的一种方法是通过pam_exec.so模块。创建/usr/local/bin/pam_check_lid包含以下内容的可执行脚本:

#!/bin/sh
LID_STATE=$(cat /proc/acpi/button/lid/LID/state | cut -d':' -f2 | tr -d ' ')

case ${LID_STATE} in
    closed)
    echo closed
    exit 1
    ;;
    open*)
    echo open
    exit 0
    ;;
    *)
    # LID is open by default
    echo unknown
    exit 0
    ;;
esac

重要的:确保该文件不可全局写入。否则,您可能会在系统中引入安全漏洞。另外,您可以通过 dbus 检查 LID 状态,详细信息请查看

然后在 之前添加以下行pam_fprintd

auth   [success=ignore default=1]   pam_exec.so quiet /usr/local/bin/pam_check_lid

所以你的配置看起来像这样:

auth   [success=ignore default=1]  pam_exec.so quiet /usr/local/bin/pam_check_lid
auth   sufficient                  pam_fprintd.so
auth   required                    pam_unix.so

现在,PAM 身份验证将在尝试指纹身份验证之前执行您的脚本,如果您的脚本返回非零退出代码(失败),它将执行默认操作,该操作会跳过 PAM 配置中的 1 个条目(因此它会跳到pam_fprintd下一个身份验证,即pam_unix)。当 LID 打开时,它将返回0退出代码,并且成功时它不会执行任何操作,因为ignore配置中的关键字。

或者,您可以制作自己的 PAM 模块,而不是pam_exec.so使用脚本,其行为与脚本相同。

关于调试和实际实现的注释很少。如果您遇到问题pam_exec,可以添加调试选项,如debuglog,详细信息请检查pam_exec 文档。最好在新的 PAM 配置上测试您的更改,而不是修改现有配置,因为配置中的错误可能会导致您无法使用帐户。例如,您可以复制您的system-authassystem-auth-new并继续工作system-auth-new,然后在测试时替换它。为了测试你可以使用帕姆测试仪。例如:

cp /etc/pam.d/system-auth /etc/pam.d/system-auth-new
# UPDATE /etc/pam.d/system-auth-new
pamtester system-auth-new YOUR_USER_NAME authenticate

当它按预期工作时,替换system-auth为您的新配置。

相关内容