我正在进行一个项目,旨在通过个人的打字行为在Linux中创建一个pam模块进行身份验证。我已经充分研究并了解了pam配置文件中四个控制标志的工作原理,即requisite、required、sufficient和optional。关于我的项目,我对PAM配置文件有以下两个问题。
-
作为第二重身份验证,我希望使用google-authenticator。目前我的配置文件中有以下代码:
auth sufficient pam_test.so auth required pam_google_authenticator.so
如果我的模块在密码正确但打字行为不匹配时无法通过身份验证,google-authenticator模块会被正确调用。然而,如果输入的密码本身不正确,它也会被调用。对于第二种情况,我希望终止整个链条。有没有办法做到这一点?我能否根据不同的pam错误状态代码有条件地调用google-authenticator模块?
- 另一个问题是我希望从google-authenticator模块返回到我的模块,并根据google-authenticator模块的pam状态代码做出决策。基本上,我希望使用最新的训练样本进行未来的训练(自适应算法)。因此,为了区分真负和假负,我希望从google-authenticator模块返回。这是可能的吗?
这是我在stackoverflow上的第一个问题。如果我在提问时犯了任何错误,我深表歉意。
回答:
有关这些操作的更多详细信息,请参阅man 5 pam.d
。我假设您在Linux上工作,使用的是Linux-PAM。
我假设pam_test.so是您编写的。因此,当密码无效时,您应该返回PAM_AUTH_ERR。您可以根据不同的返回代码指定不同的操作,使用“高级”语法。作为参考,根据(我的)pam.d手册页,“简单”操作具有以下“高级”语法:
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_*返回代码,去掉PAM_并转换为小写(因此PAM_SUCCESS变为success)。操作bad和die都表示失败状态,但die会退出堆栈。操作ok和done(以及整数N)表示成功状态。’done’也会停止堆栈的执行。使用整数N跳过后续的N个模块。特殊的“default”表示“模块的任何其他返回值”。
然后您可以这样做:
auth [success=done new_authtok_reqd=ok auth_err=die default=ignore] pam_test.so
这将在密码错误时停止执行auth堆栈并以失败结束,在模块通过时停止执行并以成功结束,在任何其他情况下继续执行auth堆栈。
至于返回到您的代码…这是一个全新的问题。您可以做到,但我想不出一种不是完全hack的方法。例如,通过使用code=N来跳转控制流程,并使用特殊参数调用您的模块,然后根据参数成功或失败。对于完整性(以及一个完整的HACK),像这样:
auth [success=done new_authtok_reqd=ok auth_err=die default=ignore] pam_test.soauth [success=ok default=1] pam_google_authenticator.soauth [default=1] pam_test.so wasvalidauth [default=bad] pam_test.so wasinvalid
这具有以下属性:如果密码无效或满足pam_test.so条件,则不会进行进一步的身份验证处理,并分别以失败或成功结束。如果pam_test因任何其他原因失败,它会调用google authenticator。如果成功,它会继续到下一行调用pam_test.so wasvalid
,否则,它会转到pam_test.so wasinvalid
。只会执行两个后续的pam_test.so调用中的一个。在此片段之后,返回代码是成功或失败,具体取决于google authenticator的状态。这实际上是“需要pam_google_authenticator.so但也使用适当的标志调用我的模块”。如果您希望无论如何都以此结束auth,您可以使用:
auth [success=done new_authtok_reqd=ok auth_err=die default=ignore] pam_test.soauth [success=ok default=1] pam_google_authenticator.soauth [default=done] pam_test.so wasvalidauth [default=die] pam_test.so wasinvalid