有的时候有这样的情况,在qt实现的界面中输入了当前用户的密码,然后需要对该密码进行验证,找了好半天,有用的信息不多,很多都是一嘴带过,对于实现功能没有实际意义。这篇文章讲给出实际例子,这里有两个中验证的方式,一种是用户在qt界面输入密码,点击按钮后进行密码验证;另外一种是么有界面,需要在命令终端输入密码,实现密码验证。

实现密码验证的基于pam模块。通过调用linux系统下的pam模块实现密码验证功能。

基于qt的直接给出一个密码字符串进行密码验证的解决方案

#include <QCoreApplication>
#include <security/pam_appl.h>
#include <unistd.h>
#include <QDebug>
#include <security/pam_appl.h>
#include <security/pam_misc.h>


int conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) {
    Q_UNUSED(num_msg);

    // 传递的密码作为appdata_ptr参数传入
    const char *password = static_cast<const char *>(appdata_ptr);

    *resp = reinterpret_cast<pam_response *>(calloc(1, sizeof(struct pam_response)));
    if (!*resp) {
        return PAM_BUF_ERR;
    }

    // 将密码作为回复传递给PAM
    (*resp)[0].resp = strdup(password);
    if (!(*resp)[0].resp) {
        return PAM_BUF_ERR;
    }

    return PAM_SUCCESS;
}

int main(int argc, char *argv[]) {
//    QCoreApplication app(argc, argv);

    // 获取当前登录用户名
    QString username = QString::fromUtf8(getlogin());
    qDebug()<<"username = "<<username;
    // 获取要验证的密码
    QString password = "cs123456";

    // PAM会话开始
    pam_handle_t *pamh;
    int retval;

    // 传递密码到PAM的回调函数中
//    const_cast<char*>(password.toStdString().c_str())
    struct pam_conv conv = { /*misc_conv*/conversation, const_cast<char*>(password.toStdString().c_str()) };
    retval = pam_start("", username.toUtf8().constData(), &conv, &pamh);

    if (retval == PAM_SUCCESS) {
        // 通过PAM验证密码
        retval = pam_authenticate(pamh, 0);

        if (retval == PAM_SUCCESS) {
            qDebug() << "Authentication successful";
        } else {
            qDebug() << "Authentication failed";
        }
    } else {
        qDebug() << "PAM initialization failed: " << pam_strerror(pamh, retval);
    }

    // 结束PAM会话
    pam_end(pamh, retval);

//    return app.exec();
}

上面的代码中用户密码通过pam_conv结构输入,该结构两个参数,第一个参数是一个回调函数,该函数的大致意思就是定义了获取密码的一些行为方式,具体含义我也不太了解,但是通过自定义该回调函数可以自定义获取密码的方式,对于上面的自定义的函数就是从参数中获取密码。程序运行结果如下:

Linux+qt实现界面输入的密码验证-LMLPHP

终端窗口交互方式实现输入密码验证的方式

此种方式与第一种用方案类似,仅仅是回调的函数的不同,该方案采用libpam_misc.so中的函数misc_conv实现。代码如下:

#include <QCoreApplication>
#include <security/pam_appl.h>
#include <unistd.h>
#include <QDebug>
#include <security/pam_appl.h>
#include <security/pam_misc.h>


int main(int argc, char *argv[]) {
//    QCoreApplication app(argc, argv);

    // 获取当前登录用户名
    QString username = QString::fromUtf8(getlogin());
    qDebug()<<"username = "<<username;
    // 获取要验证的密码
    QString password = "cs123456";

    // PAM会话开始
    pam_handle_t *pamh;
    int retval;

    // 传递密码到PAM的回调函数中
    struct pam_conv conv = { /*misc_conv*/, NULL };
    retval = pam_start("", username.toUtf8().constData(), &conv, &pamh);

    if (retval == PAM_SUCCESS) {
        // 通过PAM验证密码
        retval = pam_authenticate(pamh, 0);

        if (retval == PAM_SUCCESS) {
            qDebug() << "Authentication successful";
        } else {
            qDebug() << "Authentication failed";
        }
    } else {
        qDebug() << "PAM initialization failed: " << pam_strerror(pamh, retval);
    }

    // 结束PAM会话
    pam_end(pamh, retval);

//    return app.exec();
}

运行结果如下所示:

Linux+qt实现界面输入的密码验证-LMLPHP

04-15 15:59