Created
December 7, 2018 10:22
-
-
Save miquels/391811bd69c6382dad42f7de1e06d448 to your computer and use it in GitHub Desktop.
PAM authentication boilerplate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* cc -DTEST -Wall -o pamtest pam.c -lpam */ | |
#include <security/pam_appl.h> | |
#include <sys/resource.h> | |
#include <string.h> | |
#include <stdlib.h> | |
struct creds { | |
char *user; | |
char *password; | |
}; | |
static void add_reply(struct pam_response **reply, int count, char *txt) | |
{ | |
*reply = realloc(*reply, (count + 1) * sizeof(struct pam_response)); | |
(*reply)[count].resp_retcode = 0; | |
(*reply)[count].resp = strdup(txt ? txt: ""); | |
} | |
static int pam_conv(int num_msg, const struct pam_message **msg, | |
struct pam_response **resp, void *appdata) | |
{ | |
struct pam_response *reply = NULL; | |
struct creds *creds = (struct creds *)appdata; | |
int replies = 0; | |
for (int count = 0; count < num_msg; count++) { | |
switch (msg[count]->msg_style) { | |
case PAM_PROMPT_ECHO_ON: | |
add_reply(&reply, replies++, creds->user); | |
break; | |
case PAM_PROMPT_ECHO_OFF: | |
add_reply(&reply, replies++, creds->password); | |
break; | |
case PAM_TEXT_INFO: | |
break; | |
case PAM_ERROR_MSG: | |
default: | |
if (reply != NULL) | |
free(reply); | |
return PAM_CONV_ERR; | |
} | |
} | |
*resp = reply; | |
return PAM_SUCCESS; | |
} | |
int pam_auth(char *service, char *user, char *pass) | |
{ | |
struct creds creds = { | |
user, | |
pass, | |
}; | |
struct pam_conv conv = { | |
pam_conv, | |
&creds, | |
}; | |
pam_handle_t *pamh = NULL; | |
int ret = pam_start(service, user, &conv, &pamh); | |
if (ret != PAM_SUCCESS) | |
return ret; | |
if (ret == PAM_SUCCESS) | |
ret = pam_authenticate(pamh, 0); | |
pam_end(pamh, 0); | |
return ret; | |
} | |
#ifdef TEST | |
#include <stdio.h> | |
int main(int argc, char **argv) | |
{ | |
if (argc < 3 || argv[1][0] == '-') { | |
fprintf(stderr, "Usage: pamtest <service> <username> <password>\n"); | |
fprintf(stderr, " <service> is usually \"other\"\n"); | |
return 1; | |
} | |
int r = pam_auth(argv[1], argv[2], argv[3]); | |
if (r == PAM_SUCCESS) { | |
printf("Ok\n"); | |
} else { | |
printf("Fail, code = %d\n", r); | |
} | |
return r == PAM_SUCCESS ? 0 : 1; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment