Pam配置文件条件执行语句

Pam config file conditional execution of statements

我正在开展一个项目,在 linux 中制作一个 pam 模块,以通过个人的键入行为进行身份验证。我已经充分研究并了解 pam 配置文件中四个控制标志的工作方式,即。必需的,必需的,足够的和可选的。我有以下 2 个关于特定于我的项目的 PAM 配置文件的问题。

  1. 作为身份验证的第二个因素,我想使用 google-authenticator。 目前我的配置文件有以下代码:

    auth sufficient pam_test.so  
    auth required pam_google_authenticator.so
    

如果我的模块在输入的密码正确但输入行为不匹配时无法通过身份验证,则正确调用 google-authenticator 模块。但是,如果输入的密码本身不正确,它也会被调用。对于第二种情况,我想终止整个链条。有办法吗?我可以有条件地(基于不同的 pam 错误状态代码)调用 google-authenticator 模块吗?

  1. 另一个问题是,我想从 google-authenticator 模块返回到我的模块,并根据 google-authenticator 模块的 pam 状态代码做出决定。基本上,我想使用最新的训练样本进行未来的训练(自适应算法)。因此,为了区分真阴性和假阴性我想从 google-authenticator 模块回来?这可能吗?

这是我关于 Whosebug 的第一个问题。如果我在提问时有任何错误,我很抱歉。

有关这些 hijinx 的更多详细信息,请参阅 man 5 pam.d。我假设您正在使用 Linux-PAM 开发 Linux。

我假设 pam_test.so 是您写的东西。因此,当密码无效时,您应该 returning PAM_AUTH_ERR。您可以使用 "advanced" 语法根据不同的 return 代码指定不同的操作。 作为参考,pam.d 的(我的)手册页中,"simple" 操作具有以下 "advanced" 语法:

   required
       [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
   requisite
       [success=ok new_authtok_reqd=ok ignore=ignore default=die]
   sufficient
       [success=done new_authtok_reqd=done default=ignore]
   optional
       [success=ok new_authtok_reqd=ok default=ignore]

这些是 retval=action 的形式,其中 retval 是 PAM_* return 代码,PAM_ 被删除并转换为小写(因此 PAM_SUCCESS 成为成功)。动作 bad 和 die 都给出失败状态,但 die 退出堆栈。操作 ok 和 done(以及一个整数 N)表示成功状态。 'done' 也会停止堆栈的执行。使用整数 N 会跳过那么多后续模块。特殊的 "default" 表示 "any other return value from the module"。

然后你可以这样做:

auth [success=done new_authtok_reqd=ok auth_err=die default=ignore] pam_test.so

这将在密码错误时以失败停止执行 auth 堆栈,在模块通过时以成功停止执行,并在任何其他情况下沿着 auth 堆栈移动。

至于回到您的代码...那是一大堆新问题。你可以做到,但我想不出一种不完全破解的方法。例如,通过使用 code=N 跳转并使用特殊 args 调用您的模块,然后根据参数成功或失败,通过控制流跳过箍。为了完整起见,(和一个完整的 HACK)类似于:

auth [success=done new_authtok_reqd=ok auth_err=die default=ignore] pam_test.so
auth [success=ok default=1] pam_google_authenticator.so
auth [default=1] pam_test.so wasvalid
auth [default=bad] pam_test.so wasinvalid

这具有以下属性:如果密码无效或满足pam_test.so条件,则不会进行进一步的身份验证处理,并分别以失败或成功结束。如果 pam_test 由于任何其他原因失败,它会调用 google 验证器。如果成功,它会转到下一行调用 pam_test.so wasvalid,否则,它会转到 pam_test.so wasinvalid。随后的两个 pam_test.so 调用中只调用了一个。在此片段之后,return 代码是成功还是失败,具体取决于 google 身份验证器状态。这实际上是 "require pam_google_authenticator.so but also call my module with the appropriate flag"。如果你想让 auth 无论如何都以此结束,你可以使用:

auth [success=done new_authtok_reqd=ok auth_err=die default=ignore] pam_test.so
auth [success=ok default=1] pam_google_authenticator.so
auth [default=done] pam_test.so wasvalid
auth [default=die] pam_test.so wasinvalid