如何处理pam_authenticate对有效用户和密码的PAM_AUTHTOK_RECOVERY_ERR返回值
How to handle PAM_AUTHTOK_RECOVERY_ERR return value from pam_authenticate for valid user and password?
我正在尝试编写一些使用linux pam对客户端进行身份验证的服务器。我写了下面的类:
class Pam
{
public:
Pam(const char *module, const char *username)
{
mConv.appdata_ptr = nullptr;
mConv.conv = &convCallback;
const int res = pam_start("system-auth", username, &mConv, &mPamHandle);
if (res != PAM_SUCCESS)
throw std::runtime_error("Failed to initialize PAM");
}
bool authenticate(char *passwd)
{
pam_response *resp = static_cast<pam_response*>(malloc(sizeof(pam_response)));
resp->resp = passwd;
resp->resp_retcode = 0;
mConv.appdata_ptr = resp;
const int res = pam_authenticate(mPamHandle, 0);
log(res);
return res == PAM_SUCCESS;
}
~Pam()
{
if (mPamHandle)
pam_end(mPamHandle, PAM_SUCCESS);
mPamHandle = nullptr;
}
private:
static int convCallback (int msgId, const pam_message **msg, pam_response **resp, void *appData)
{
*resp = static_cast<pam_response*>(appData);
return PAM_SUCCESS;
}
private:
pam_handle_t *mPamHandle = nullptr;
pam_conv mConv;
};
它的用法如下:
Pam pam("system-auth", username);
if (pam.authenticate(passwd))
return true;
// error handling code here
我发现pam_authenticate对于有效的用户/密码返回PAM_AUTHTOK_RECOVERY_ERR。手册页和linuxpam.org http://www.linux-pam.org/Linux-PAM-html/adg-interface-by-app-expected.html#adg-pam_authenticate中记录的可能返回值根本不包含此值。文档说它可以通过pam_chauthtok返回,这意味着:
PAM_AUTHTOK_RECOVERY_ERR
一个模块无法获得旧的认证令牌。
目前还不清楚它在身份验证的情况下意味着什么。我已经尝试运行代码作为普通用户和根的结果是一样的。
正在发生的事情是,您将0
视为convCallback
中appData
的值,这就是错误的来源-回复数据为空,这意味着不良对话,这导致PAM_AUTHTOK_RECOVERY_ERR
返回值。这是基于读取PAM-Linux源代码的当前代码中的support.c
文件。
好,有几个问题。
-
你不能在初始化后重新分配会话appdata_ptr值-指针的值应该在调用
pam_start
后被视为常量。你应该在那里传递一个永远不会改变的值。如果您检查了对话功能,您会注意到appData
的值是0
。 -
你必须假设被放入回复中的值是由调用例程拥有的-也就是说,你必须将密码字符串(与所有与之相关的邪恶)串联起来。
class Pam
{
public:
Pam(const char *module, const char *username)
{
mConv.appdata_ptr = (void *)(this);
mConv.conv = &convCallback;
const int res = pam_start(module, username, &mConv, &mPamHandle);
if (res != PAM_SUCCESS)
throw std::runtime_error("Failed to initialize PAM");
}
bool authenticate(char *passwd)
{
mPassword = passwd;
const int res = pam_authenticate(mPamHandle, 0);
log(res);
return res == PAM_SUCCESS;
}
~Pam()
{
if (mPamHandle)
pam_end(mPamHandle, PAM_SUCCESS);
mPamHandle = 0;
}
private:
static int convCallback (int msgId, const pam_message **msg, pam_response **resp, void *appData)
{
Pam *me = static_cast<Pam *>(appData);
pam_response *reply = static_cast<pam_response *>(calloc(1, sizeof(pam_response)));
reply->resp = strdup(me->mPassword);
reply->resp_retcode = 0;
*resp = reply;
return PAM_SUCCESS;
}
private:
pam_handle_t *mPamHandle = 0;
pam_conv mConv;
const char *mPassword = 0;
};
相关文章:
- c++中的oop(密码生成)
- 密码登录程序将永远循环并显示不正确的结果
- OpenSSL没有共享密码
- Cryptopp:获取密码输入的填充字符串
- 密码长度验证 (c++)
- C++ win32 如何使密码字段可选并启用复制和粘贴?
- 仿射密码解密,输出大小写不同
- 替换密码:哪一个?
- 无法使用 openssl 服务器,因为密码已过时...什么的...ERR_SSL_VERSION_OR_CIPHER_MISMATCH
- 如何使用 c++ 在 sqlite3 中打开受密码保护的数据库?
- 根据用户名和密码 Qt C++重新访问数据库值
- C++密码问题
- 无法在 Cocos2dx 中使用受密码保护的 zip 文件
- 如何使用librdkafka设置明文协议(无SASL)的用户名和密码?
- 如何将凯撒密码的元素从字符串更改为字符串
- 如何在C++的凯撒密码程序中包含空格?
- 运行密钥密码解密知道密钥?
- 如何在 c++ 中将密码和用户名保存到 .txt 文件中.如果用户尝试登录,我仍然希望能够检索它们
- 当PSO细粒度策略对使用AdsGetObject MSDN API的Windows操作系统生效时,如何获取用户密码到期日
- 在PAM模块之间传递密码