c++ - 遗留应用程序的 PAM 身份验证

标签 c++ c linux authentication pam

我有一个遗留应用程序,它通过网络异步接收用户名/密码请求。由于我已经将用户名和密码存储为变量,在 Linux (Debian 6) 上使用 PAM 进行身份验证的最佳方法是什么?

我已经尝试编写自己的对话函数,但我不确定将密码输入其中的最佳方法。我考虑过将它存储在 appdata 中并从 pam_conv 结构中引用它,但几乎没有关于如何做到这一点的文档。

有没有一种更简单的方法来验证用户身份,而不会过度使用对话功能?我也无法成功使用 pam_set_data,我不确定这是否合适。

这是我正在做的:

user = guiMessage->username;
pass = guiMessage->password;

pam_handle_t* pamh = NULL;
int           pam_ret;
struct pam_conv conv = {
  my_conv,
  NULL
};

pam_start("nxs_login", user, &conv, &pamh);
pam_ret = pam_authenticate(pamh, 0);

if (pam_ret == PAM_SUCCESS)
  permissions = 0xff;

pam_end(pamh, pam_ret);

对话功能的初步尝试导致(密码被硬编码用于测试):

int 
my_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *data)
{
  struct pam_response *aresp;

  if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
    return (PAM_CONV_ERR);
  if ((aresp = (pam_response*)calloc(num_msg, sizeof *aresp)) == NULL)
    return (PAM_BUF_ERR);
  aresp[0].resp_retcode = 0;
  aresp[0].resp = strdup("mypassword");

  *resp = aresp;
  return (PAM_SUCCESS);
}

如有任何帮助,我们将不胜感激。谢谢!

最佳答案

这就是我最终所做的。请参阅标有三个星号的评论。

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <security/pam_appl.h>
#include <unistd.h>

// To build this:
// g++ test.cpp -lpam -o test

// if pam header files missing try:
// sudo apt install libpam0g-dev

struct pam_response *reply;

//function used to get user input
int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
{
  *resp = reply;
  return PAM_SUCCESS;
}

int main(int argc, char** argv)
{
  if(argc != 2) {
      fprintf(stderr, "Usage: check_user <username>\n");
      exit(1);
  }
  const char *username;
  username = argv[1];

  const struct pam_conv local_conversation = { function_conversation, NULL };
  pam_handle_t *local_auth_handle = NULL; // this gets set by pam_start

  int retval;

  // local_auth_handle gets set based on the service
  retval = pam_start("common-auth", username, &local_conversation, &local_auth_handle);

  if (retval != PAM_SUCCESS)
  {
    std::cout << "pam_start returned " << retval << std::endl;
    exit(retval);
  }

  reply = (struct pam_response *)malloc(sizeof(struct pam_response));

  // *** Get the password by any method, or maybe it was passed into this function.
  reply[0].resp = getpass("Password: ");
  reply[0].resp_retcode = 0;

  retval = pam_authenticate(local_auth_handle, 0);

  if (retval != PAM_SUCCESS)
  {
    if (retval == PAM_AUTH_ERR)
    {
      std::cout << "Authentication failure." << std::endl;
    }
    else
    {
      std::cout << "pam_authenticate returned " << retval << std::endl;
    }
    exit(retval);
  }

  std::cout << "Authenticated." << std::endl;

  retval = pam_end(local_auth_handle, retval);

  if (retval != PAM_SUCCESS)
  {
    std::cout << "pam_end returned " << retval << std::endl;
    exit(retval);
  }

  return retval;
}

关于c++ - 遗留应用程序的 PAM 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5913865/

相关文章:

c++ - 如何 "Overflow"超出特定范围(如 30 - 100)的值

c++ - CString 'Trim' : is not a member, 为什么?

c++ - 安全的多线程计数器增量

c - c如何处理不同范围内的相同变量名?

c - Lua:在 lua 中有效地操作(读/写)C 风格、C 分配的动态数组

c++ - 从现有对象创建对象

c - 在 C 中以困难的方式打印星号

linux - 为什么/etc/login.defs 中的 UMASK 设置不被接受?

linux - 创建永久别名 bash 命令

linux - 关于 SIGALRM 和报警