首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何为有效用户和密码处理PAM_AUTHTOK_RECOVERY_ERR从pam_authenticate返回的值?

如何为有效用户和密码处理PAM_AUTHTOK_RECOVERY_ERR从pam_authenticate返回的值?
EN

Stack Overflow用户
提问于 2014-08-15 08:44:31
回答 1查看 338关注 0票数 0

我正在尝试编写一些服务器,它使用linux对客户端进行身份验证。我写了下面的课:

代码语言:javascript
代码运行次数:0
运行
复制
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;
};

然后被使用如下:

代码语言:javascript
代码运行次数:0
运行
复制
Pam pam("system-auth", username);
if (pam.authenticate(passwd))
    return true;
// error handling code here

我发现pam_authenticate返回有效用户/密码的PAM_AUTHTOK_RECOVERY_ERR。手册页和Linux-pan.org authenticate中记录的可能返回值根本不包含此值。文档显示pam_chauthtok可以返回它,这意味着:

PAM_AUTHTOK_RECOVERY_ERR 模块无法获得旧的身份验证令牌。

目前还不清楚这对身份验证意味着什么。我尝试以普通用户和root用户的身份运行代码,结果是一样的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-15 12:05:25

正在发生的事情是,您将0视为appDataconvCallback中的值,这是错误的来源--回复数据是空的,这意味着会话错误,这将导致PAM_AUTHTOK_RECOVERY_ERR返回值。这是基于读取PAM源代码当前代码中的support.c文件。

好吧,有几个问题。

  1. 初始化后不能重新分配会话appdata_ptr值--指针的值应该在调用pam_start之后被视为常量。你应该在那里传递一个永远不会改变的值。如果您检查了会话函数,就会注意到appData的值是0
  2. 您必须假定将被放入应答中的值属于调用例程--也就是说,您必须增强密码字符串(与此相关的所有邪恶信息)。

考虑到这两个方面,我稍微修改了您的代码如下,这将解决您的问题(同样,这是简化的代码):

代码语言:javascript
代码运行次数: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;
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25323600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档