Linux PAM应用程序端与服务程序端消息传递/交互核心代码示例

1、PAM应用程序端(PAM API)

        PAM应用程序端需要注册实现pam_conv回调函数,通过pam_message用于接收服务端的认证提示信息(如:登录用户名输入提示、密码输入提示、指纹登录系统中的指纹按压提示等)、pam_response用于向后端反馈用户的输入的交互信息(如:密码),如下是应用程序端的交互的核心代码示例:

#include <security/pam_appl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 应用程序端的会话函数 */
int converse(int num_msg, const struct pam_message **msg,
             struct pam_response **resp, void *appdata_ptr) {
    struct pam_response *aresp;
    char buf[PAM_MAX_RESP_SIZE];
    
    if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
        return PAM_CONV_ERR;
    
    aresp = calloc(num_msg, sizeof(struct pam_response));
    if (!aresp) return PAM_BUF_ERR;

    for (int i = 0; i < num_msg; i++) {
        aresp[i].resp_retcode = 0;
        switch (msg[i]->msg_style) {
            case PAM_PROMPT_ECHO_OFF:
                printf("%s", msg[i]->msg);
                fgets(buf, sizeof(buf), stdin);
                buf[strcspn(buf, "\n")] = '\0'; // 去除换行符
                aresp[i].resp = strdup(buf);
                break;
            case PAM_PROMPT_ECHO_ON:
                printf("%s", msg[i]->msg);
                fgets(buf, sizeof(buf), stdin);
                buf[strcspn(buf, "\n")] = '\0';
                aresp[i].resp = strdup(buf);
                break;
            case PAM_ERROR_MSG:
                fprintf(stderr, "ERROR: %s\n", msg[i]->msg);
                break;
            case PAM_TEXT_INFO:
                printf("%s\n", msg[i]->msg);
                break;
            default:
                free(aresp);
                return PAM_CONV_ERR;
        }
    }
    *resp = aresp;
    return PAM_SUCCESS;
}

2、PAM服务程序端(PAM SPI)

        PAM服务端程序端需要使用pam_get_item函数获取pam_conv结构体,该结构体包含pam_conv会话函数,通过调用会话函数实现pam_message认证提示信息(如:登录用户名输入提示、密码输入提示、指纹登录系统中的指纹按压提示等)的发送、pam_response交互信息(如:密码)的接收,如下是服务程序端的交互的核心代码示例:

#include <security/pam_modules.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* PAM模块端的认证函数 */
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                                  int argc, const char **argv) {
    int retval;
    const char *username;
    struct pam_conv *conv;
    struct pam_message msg;
    const struct pam_message *msgp;
    struct pam_response *resp = NULL;

    /* 获取会话函数 */
    retval = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
    if (retval != PAM_SUCCESS) return retval;

    /* 构造用户名提示消息 */
    msg.msg_style = PAM_PROMPT_ECHO_ON;
    msg.msg = "Username: ";
    msgp = &msg;

    /* 发送消息并获取响应 */
    retval = conv->conv(1, &msgp, &resp, conv->appdata_ptr);
    if (retval != PAM_SUCCESS || resp == NULL || resp->resp == NULL) {
        return PAM_AUTH_ERR;
    }
    username = resp->resp;

    /* 构造密码提示消息 */
    msg.msg_style = PAM_PROMPT_ECHO_OFF;
    msg.msg = "Password: ";
    
    /* 发送消息并获取响应 */
    retval = conv->conv(1, &msgp, &resp, conv->appdata_ptr);
    if (retval != PAM_SUCCESS) return retval;

    /* 此处应添加实际认证逻辑 */
    printf("Authenticating user: %s\n", username);
    
    /* 清理响应内存(由PAM自动完成)*/
    return PAM_SUCCESS;
}

相关核心关键字:pam_conv、pam_message、pam_response、pam交互机制

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值