pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/security/pam-pwauth_suid add a PAM module which used a...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/84ac87fe2643
branches:  trunk
changeset: 523506:84ac87fe2643
user:      drochner <drochner%pkgsrc.org@localhost>
date:      Mon Jan 08 18:39:44 2007 +0000

description:
add a PAM module which used a suid helper program to access the passwd
database, for use by unprivileged users to verify their own password
(in particular for screen savers)
thanks to many people for comments

diffstat:

 security/pam-pwauth_suid/DESCR                      |   7 +
 security/pam-pwauth_suid/MESSAGE                    |   6 +
 security/pam-pwauth_suid/Makefile                   |  30 ++++++++
 security/pam-pwauth_suid/PLIST                      |   3 +
 security/pam-pwauth_suid/files/pam_pwauth_suid.c    |  75 +++++++++++++++++++++
 security/pam-pwauth_suid/files/pwauth_suid_helper.c |  60 ++++++++++++++++
 6 files changed, 181 insertions(+), 0 deletions(-)

diffs (205 lines):

diff -r bcb51fd28ee2 -r 84ac87fe2643 security/pam-pwauth_suid/DESCR
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/security/pam-pwauth_suid/DESCR    Mon Jan 08 18:39:44 2007 +0000
@@ -0,0 +1,7 @@
+The pam_pwauth_suid authentication module uses a setuid program
+to verify a password against the encrypted password in the
+database used by the system. This way, an unprivileged user can
+verify his own passsword stored in a shadow password database.
+There might be some risk that the communication between the
+invoking program and the setuid program is logged, or for abuse
+for dictionary attacks.
diff -r bcb51fd28ee2 -r 84ac87fe2643 security/pam-pwauth_suid/MESSAGE
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/security/pam-pwauth_suid/MESSAGE  Mon Jan 08 18:39:44 2007 +0000
@@ -0,0 +1,6 @@
+===========================================================================
+$NetBSD: MESSAGE,v 1.1.1.1 2007/01/08 18:39:44 drochner Exp $
+
+The PAM authentication module "pam_pwauth_suid.so.0" needs to be
+installed into the directory "/usr/lib/security".
+===========================================================================
diff -r bcb51fd28ee2 -r 84ac87fe2643 security/pam-pwauth_suid/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/security/pam-pwauth_suid/Makefile Mon Jan 08 18:39:44 2007 +0000
@@ -0,0 +1,30 @@
+# $NetBSD: Makefile,v 1.1.1.1 2007/01/08 18:39:44 drochner Exp $
+
+DISTNAME=      pam-pwauth_suid-1.0
+CATEGORIES=    security
+DISTFILES=     # empty
+
+MAINTAINER=    drochner%NetBSD.org@localhost
+COMMENT=       PAM authentication module for unprivileged users
+
+NO_CHECKSUM=   yes
+WRKSRC=                ${WRKDIR}
+CFLAGS+=       -DPATH_HELPER=\"${PREFIX}/libexec/pwauth_suid_helper\"
+
+do-extract:
+       ${CP} ${FILESDIR}/pam_pwauth_suid.c ${FILESDIR}/pwauth_suid_helper.c \
+               ${WRKSRC}
+
+do-build:
+       (cd ${WRKSRC} && \
+        ${CC} ${CFLAGS} -shared pam_pwauth_suid.c -o pam_pwauth_suid.so.0 && \
+        ${CC} ${CFLAGS} pwauth_suid_helper.c -o pwauth_suid_helper -lcrypt)
+
+do-install:
+       ${INSTALL_DATA_DIR} ${PREFIX}/lib/security
+       ${INSTALL_DATA} ${WRKSRC}/pam_pwauth_suid.so.0 ${PREFIX}/lib/security
+       ${INSTALL_PROGRAM} ${WRKSRC}/pwauth_suid_helper ${PREFIX}/libexec
+       ${CHMOD} 04555 ${PREFIX}/libexec/pwauth_suid_helper
+
+.include "../../mk/pam.buildlink3.mk"
+.include "../../mk/bsd.pkg.mk"
diff -r bcb51fd28ee2 -r 84ac87fe2643 security/pam-pwauth_suid/PLIST
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/security/pam-pwauth_suid/PLIST    Mon Jan 08 18:39:44 2007 +0000
@@ -0,0 +1,3 @@
+@comment $NetBSD: PLIST,v 1.1.1.1 2007/01/08 18:39:44 drochner Exp $
+lib/security/pam_pwauth_suid.so.0
+libexec/pwauth_suid_helper
diff -r bcb51fd28ee2 -r 84ac87fe2643 security/pam-pwauth_suid/files/pam_pwauth_suid.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/security/pam-pwauth_suid/files/pam_pwauth_suid.c  Mon Jan 08 18:39:44 2007 +0000
@@ -0,0 +1,75 @@
+/* $NetBSD: pam_pwauth_suid.c,v 1.1.1.1 2007/01/08 18:39:44 drochner Exp $ */
+
+#include <sys/types.h>
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+static int
+askhelper(const char *user, const char *pass)
+{
+       int fd[2];
+       pid_t pid, rpid;
+       ssize_t res;
+       size_t pwlen;
+       int s;
+
+       if (pipe(fd) < 0)
+               return errno;
+
+       pid = vfork();
+       switch (pid) {
+               case -1:
+                       return errno;
+               case 0: /* child, feed it through its stdin */
+                       (void)dup2(fd[0], STDIN_FILENO);
+                       (void)close(fd[0]);
+                       (void)close(fd[1]);
+                       execl(PATH_HELPER, PATH_HELPER, user, NULL);
+                       _exit(errno);
+               default: /* parent */
+                       (void)close(fd[0]);
+                       break;
+       }
+
+       pwlen = strlen(pass);
+       res = write(fd[1], pass, pwlen);
+       if (res != pwlen)
+               return (res == -1 ? errno : EIO);
+
+       (void)close(fd[1]); /* now child gets an EOF */
+
+       rpid = waitpid(pid, &s, 0);
+       if (rpid != pid)
+               return errno;
+       if (!WIFEXITED(s) || WEXITSTATUS(s))
+               return EAUTH;
+
+       return 0;
+}
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags,
+                   int argc, const char **argv)
+{
+       const char *user, *pass;
+       int res;
+
+       res = pam_get_user(pamh, &user, NULL);
+       if (res != PAM_SUCCESS)
+               return res;
+       res = pam_get_authtok(pamh, PAM_AUTHTOK, &pass, NULL);
+       if (res != PAM_SUCCESS)
+               return res;
+
+       if (askhelper(user, pass) != 0)
+               return PAM_AUTH_ERR;
+
+       return PAM_SUCCESS;
+}
+
+PAM_MODULE_ENTRY("pam_passwdhelper");
diff -r bcb51fd28ee2 -r 84ac87fe2643 security/pam-pwauth_suid/files/pwauth_suid_helper.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/security/pam-pwauth_suid/files/pwauth_suid_helper.c       Mon Jan 08 18:39:44 2007 +0000
@@ -0,0 +1,60 @@
+/* $NetBSD: pwauth_suid_helper.c,v 1.1.1.1 2007/01/08 18:39:44 drochner Exp $ */
+
+#include <pwd.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+static char pwbuf[_PASSWORD_LEN + 1];
+
+int
+main(int argc, char **argv)
+{
+       const struct passwd *pwent;
+       ssize_t res;
+       char *bufptr;
+       const char *pwhash;
+       size_t buflen;
+
+       if (argc != 2)
+               return (EINVAL);
+
+       /*
+        * mlock(2) pwbuf[]? NetBSD's getpass(3) doesn't,
+        * so don't bother for now.
+        */
+
+       bufptr = pwbuf;
+       buflen = sizeof(pwbuf);
+       do {
+               res = read(STDIN_FILENO, bufptr, buflen);
+               if (res < 0)
+                       return (errno);
+               bufptr += res;
+               buflen -= res;
+       } while (res > 0 && buflen > 0);
+       if (buflen == 0)
+               return (ENOMEM);
+       /* pwbuf is \0-terminated here b/c pwbuf is in bss */
+
+       /*
+        * Use username as key rather than uid so that it will not
+        * fail completely if multiple pw entries share a uid.
+        * Return same result in "not me" and "doesn't exist" cases
+        * to avoid leak of account information.
+        */
+       pwent = getpwnam(argv[1]);
+       if (!pwent || (pwent->pw_uid != getuid()))
+               return (EPERM);
+
+       /*
+        * Forcibly eat up some wall time to prevent use of this program
+        * to brute-force? For now assume that process startup time etc.
+        * make it already ineffective.
+        */
+       pwhash = crypt(pwbuf, pwent->pw_passwd);
+       if (pwhash && strcmp(pwhash, pwent->pw_passwd) == 0)
+               return (0);
+
+       return (EAUTH);
+}



Home | Main Index | Thread Index | Old Index