aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Holstein <nathan.holstein@gmail.com>2015-08-06 00:40:10 -0400
committerNathan Holstein <nathan.holstein@gmail.com>2015-08-06 00:40:10 -0400
commit67372a74fe974ba799bb209a111eb7c2e9bc1203 (patch)
tree071002cd042a9e11431690118aaa3b36364e1773
parent5c60366f659313e46a5b22ad27f50a3ba3ab8f15 (diff)
downloadopendoas-67372a74fe974ba799bb209a111eb7c2e9bc1203.tar.gz
Implement PAM authentication.
This now lets us check for a password. This still needs some error checking logic within pam_conv(). The current state could fail an IO operation but still return PAM_SUCCESS.
-rw-r--r--libopenbsd/auth_userokay.c101
1 files changed, 57 insertions, 44 deletions
diff --git a/libopenbsd/auth_userokay.c b/libopenbsd/auth_userokay.c
index 9c89625..2774976 100644
--- a/libopenbsd/auth_userokay.c
+++ b/libopenbsd/auth_userokay.c
@@ -15,11 +15,13 @@
*/
#include <sys/types.h>
+#include <err.h>
#include <errno.h>
#include <pwd.h>
#include <readpassphrase.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <security/pam_appl.h>
@@ -29,67 +31,78 @@
#define __UNUSED __attribute__ ((unused))
-static int
-pam_conv(__UNUSED int huh, __UNUSED const struct pam_message **msg,
- __UNUSED struct pam_response **rsp, __UNUSED void *ptr)
+static char *
+pam_prompt(const char *msg, int echo_on)
{
- return 0;
+ char buf[PAM_MAX_RESP_SIZE];
+ int flags = RPP_REQUIRE_TTY | (echo_on ? RPP_ECHO_ON : RPP_ECHO_OFF);
+ char *ret = readpassphrase(msg, buf, sizeof(buf), flags);
+ if (ret)
+ ret = strdup(ret);
+ explicit_bzero(buf, sizeof(buf));
+ return ret;
}
-static struct pam_conv conv = {
- .conv = pam_conv,
- .appdata_ptr = NULL,
-};
-
static int
-check_pam(const char *user)
+pam_conv(int nmsgs, const struct pam_message **msgs,
+ struct pam_response **rsps, __UNUSED void *ptr)
{
- fprintf(stderr, "check_pam(%s)\n", user);
-
- int ret;
- pam_handle_t *pamh = NULL;
-
- ret = pam_start(PAM_SERVICE, user, &conv, &pamh);
- if (ret != 0) {
- fprintf(stderr, "pam_start(\"%s\", \"%s\", ?, ?): failed\n",
- PAM_SERVICE, user);
- return -1;
- }
-
- if ((ret = pam_close_session(pamh, 0)) != 0) {
- fprintf(stderr, "pam_close_session(): %s\n", pam_strerror(pamh, ret));
- return -1;
+ int i, style;
+ struct pam_response *rsp;
+
+ if (!(rsp = calloc(nmsgs, sizeof(struct pam_response))))
+ errx(1, "couldn't malloc pam_response");
+ *rsps = rsp;
+
+ for (i = 0; i < nmsgs; i++) {
+ switch (style = msgs[i]->msg_style) {
+ case PAM_PROMPT_ECHO_OFF:
+ case PAM_PROMPT_ECHO_ON:
+ rsp[i].resp = pam_prompt(msgs[i]->msg,
+ style == PAM_PROMPT_ECHO_ON);
+ break;
+
+ case PAM_ERROR_MSG:
+ case PAM_TEXT_INFO:
+ fprintf(style == PAM_ERROR_MSG ? stderr : stdout,
+ "%s\n", msgs[i]->msg);
+ break;
+
+ default:
+ errx(1, "invalid PAM msg_style %d", style);
+ }
}
- return 0;
+ return PAM_SUCCESS;
}
int
auth_userokay(char *name, char *style, char *type, char *password)
{
+ static const struct pam_conv conv = {
+ .conv = pam_conv,
+ .appdata_ptr = NULL,
+ };
+
+ int ret, auth;
+ pam_handle_t *pamh = NULL;
+
if (!name)
return 0;
- if (style || type || password) {
- fprintf(stderr, "auth_userokay(name, NULL, NULL, NULL)!\n");
- exit(1);
- }
+ if (style || type || password)
+ errx(1, "auth_userokay(name, NULL, NULL, NULL)!\n");
- int ret = check_pam(name);
- if (ret != 0) {
- fprintf(stderr, "PAM authentication failed\n");
- return 0;
- }
+ ret = pam_start(PAM_SERVICE, name, &conv, &pamh);
+ if (ret != PAM_SUCCESS)
+ errx(1, "pam_start(\"%s\", \"%s\", ?, ?): failed\n",
+ PAM_SERVICE, name);
- /*
- char passbuf[256];
- if (readpassphrase("Password: ", passbuf, sizeof(passbuf),
- RPP_REQUIRE_TTY) == NULL)
- return 0;
+ auth = pam_authenticate(pamh, 0);
- explicit_bzero(passbuf, sizeof(passbuf));
- */
+ ret = pam_close_session(pamh, 0);
+ if (ret != PAM_SUCCESS)
+ errx(1, "pam_close_session(): %s\n", pam_strerror(pamh, ret));
- fprintf(stderr, "failing auth check for %s\n", name);
- return 0;
+ return auth == PAM_SUCCESS;
}