背景
我正在使用PAM规范开发一个模块,我想测试一个pam函数(特别是pam_sm_authenticate),以确保我实现的辅助函数与规范一致。
pam_sm_ [authenticate,acct_mgmt ......等]系列函数都采用相同的参数。
int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
我在模拟struct pam_handle
时遇到问题,但需要这个结构包含对验证用户至关重要的信息。
使用来自互联网的PAM标题信息(pam_appl.h和pam_private.h)我试图直接将结构用作pam_handle_t normalPamh;
并自己填充,但是当我尝试获取以下错误:
error: aggregate 'pam_handle_t normalPamh' has incomplete type and cannot be defined
我真的想测试我的模块,以确保我没有做任何会导致分段错误的事情,并且我在合理范围内使用内存,但我这样做是因为我无法模拟这个结构。
问题
我如何模拟pam_handle_t结构?
答案 0 :(得分:1)
听起来,你所指的标题声明了pam-handle类型:
typedef struct pam_handle pam_handle_t;
但是struct pam_handle
的实际定义不是您描述的标题的一部分。要模拟它,您需要在编写代码访问struct pam_handle
成员的任何代码(无论它们是什么)之前指定实际结构。即:
在您的界面定义中,您只使用句柄“结束”结构定义:
int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv);
在您的测试代码中,为了测试目的而修改句柄成员,您必须对其进行定义,例如
#include "interface_to_be_tested.h"
// declare the pam_handle
struct pam_handle
{
// provide definition of struct-members here
};
...
// Test code here
更新:结构似乎是在libpam / pam_private.h中定义的,因此在测试代码中包含该文件应该足够了。请注意标题是“私有的”,因此您的实际实现当然不应该使用它。
希望有所帮助!
答案 1 :(得分:0)
我发现了一些完全符合我需要的开源软件。
它被称为pamtester,它在许多* nix系统上编译。
安装完成后,您可以像以下一样运行它:
pamtester -v -I user=test01@test.com -I rhost=192.168.2.150 dovecot test01@test.com "authenticate(PAM_ESTABLISH_CRED)"
它将处理建立用户凭据所需的所有其他内容。
我想通过C在自动化测试中使用它,所以我在bash脚本中包含了很多调用,我可以在其中指定我想要改变的输入,如user和ruser。
问题是当程序要求输入密码时需要输入密码。我在C源代码中使用popen
解决了这个问题。
以下是我做的参考示例。这并不完美,但对于可能遇到类似情况的其他人来说,这可能是一个起点。
int testPamSmAuthenticate(char * username, char * hostname, char * password) {
//--------------------------------------
// declarations
//--------------------------------------
char testCommand[512];
char passwordPromptResponse[128];
char resultLine[3];
FILE * testFile;
//--------------------------------------
// declarations
//--------------------------------------
sprintf(testCommand, "%s %s %s", PAM_TEST_SCRIPT_PATH, username, hostname);
sprintf(passwordPromptResponse, "%s\n", password);
//--------------------------------------
// run the command and enter a password
//--------------------------------------
if (!(testFile = popen(testCommand, "w"))){
return(1);
}
fputs(passwordPromptResponse, testFile);
pclose(testFile);
//--------------------------------------
// get the output of the command from
// the text file written by bash
//--------------------------------------
testFile = fopen(PAM_TEST_RESULT_PATH, "r");
while (fgets(resultLine, sizeof(resultLine), testFile)) {
printf("%s", resultLine);
}
fclose(testFile);
//--------------------------------------
// evaulate and return a code
// 1 == authentication good
// 0 == authentication bad
//--------------------------------------
if (strchr(resultLine, '0')) {
printf("Authentication successful!\n");
return(1);
}
printf("Authentication failed!\n");
return(0);
}
有关使用此程序的更多信息,请下载源代码并阅读其自述文件。