summaryrefslogtreecommitdiffstats
path: root/contrib/pwdauth.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pwdauth.c')
-rw-r--r--contrib/pwdauth.c308
1 files changed, 0 insertions, 308 deletions
diff --git a/contrib/pwdauth.c b/contrib/pwdauth.c
deleted file mode 100644
index ca15495..0000000
--- a/contrib/pwdauth.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * pwdauth.c - program to verify a given username/password pair.
- *
- * Run it with username in argv[1] (may be omitted - default is the
- * current user), and send it the password over a pipe on stdin.
- * Exit status: 0 - correct password, 1 - wrong password, >1 - other
- * errors. For use with shadow passwords, this program should be
- * installed setuid root.
- *
- * This can be used, for example, by xlock - you don't have to install
- * this large and complex (== possibly insecure) program setuid root,
- * just modify it to run this simple program to do the authentication.
- *
- * Recent versions (xlockmore-3.9) are cleaner, and drop privileges as
- * soon as possible after getting the user's encrypted password.
- * Using this program probably doesn't make it more secure, and has one
- * disadvantage: since we don't get the encrypted user's password at
- * startup (but at the time the user is authenticated), it is not clear
- * how we should handle errors (like getpwnam() returning NULL).
- * - fail the authentication? Problem: no way to unlock (other than kill
- * the process from somewhere else) if the NIS server stops responding.
- * - succeed and unlock? Problem: it's too easy to unlock by unplugging
- * the box from the network and waiting until NIS times out...
- *
- * This program is Copyright (C) 1996 Marek Michalkiewicz
- * <marekm@i17linuxb.ists.pwr.wroc.pl>.
- *
- * It may be used and distributed freely for any purposes. There is no
- * warranty - use at your own risk. I am not liable for any damages etc.
- * If you improve it, please send me your changes.
- */
-
-static char rcsid[] = "$Id$";
-
-/*
- * Define USE_SYSLOG to use syslog() to log successful and failed
- * authentication. This should be safe even if your system has
- * the infamous syslog buffer overrun security problem...
- */
-#define USE_SYSLOG
-
-/*
- * Define HAVE_GETSPNAM to get shadow passwords using getspnam().
- * Some systems don't have getspnam(), but getpwnam() returns
- * encrypted passwords only if running as root.
- *
- * According to the xlock source (not tested, except Linux) -
- * define: Linux, Solaris 2.x, SVR4, ...
- * undef: HP-UX with Secured Passwords, FreeBSD, NetBSD, QNX.
- * Known not supported (yet): Ultrix, OSF/1, SCO.
- */
-#define HAVE_GETSPNAM
-
-/*
- * Define HAVE_PW_ENCRYPT to use pw_encrypt() instead of crypt().
- * pw_encrypt() is like the standard crypt(), except that it may
- * support better password hashing algorithms.
- *
- * Define if linking with libshadow.a from the shadow password
- * suite (Linux, SunOS 4.x?).
- */
-#undef HAVE_PW_ENCRYPT
-
-/*
- * Define HAVE_AUTH_METHODS to support the shadow suite specific
- * extension: the encrypted password field contains a list of
- * administrator defined authentication methods, separated by
- * semicolons. This program only supports the standard password
- * authentication method (a string that doesn't start with '@').
- */
-#undef HAVE_AUTH_METHODS
-
-/*
- * FAIL_DELAY - number of seconds to sleep before exiting if the
- * password was wrong, to slow down password guessing attempts.
- */
-#define FAIL_DELAY 2
-
-/* No user-serviceable parts below :-). */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <pwd.h>
-
-#ifdef USE_SYSLOG
-#include <syslog.h>
-#ifndef LOG_AUTHPRIV
-#define LOG_AUTHPRIV LOG_AUTH
-#endif
-#endif
-
-#ifdef HAVE_GETSPNAM
-#include <shadow.h>
-#endif
-
-#ifdef HAVE_PW_ENCRYPT
-extern char *pw_encrypt();
-#define crypt pw_encrypt
-#endif
-
-/*
- * Read the password (one line) from fp. We don't turn off echo
- * because we expect input from a pipe.
- */
-static char *
-get_line(fp)
- FILE *fp;
-{
- static char buf[128];
- char *cp;
- int ch;
-
- cp = buf;
- while ((ch = getc(fp)) != EOF && ch != '\0' && ch != '\n') {
- if (cp >= buf + sizeof buf - 1)
- break;
- *cp++ = ch;
- }
- *cp = '\0';
- return buf;
-}
-
-/*
- * Get the password file entry for the current user. If the name
- * returned by getlogin() is correct (matches the current real uid),
- * return the entry for that user. Otherwise, return the entry (if
- * any) matching the current real uid. Return NULL on failure.
- */
-static struct passwd *
-get_my_pwent()
-{
- uid_t uid = getuid();
- char *name = getlogin();
-
- if (name && *name) {
- struct passwd *pw = getpwnam(name);
-
- if (pw && pw->pw_uid == uid)
- return pw;
- }
- return getpwuid(uid);
-}
-
-/*
- * Verify the password. The system-dependent shadow support is here.
- */
-static int
-password_auth_ok(pw, pass)
- const struct passwd *pw;
- const char *pass;
-{
- int result;
- char *cp;
-#ifdef HAVE_AUTH_METHODS
- char *buf;
-#endif
-#ifdef HAVE_GETSPNAM
- struct spwd *sp;
-#endif
-
- if (pw) {
-#ifdef HAVE_GETSPNAM
- sp = getspnam(pw->pw_name);
- if (sp)
- cp = sp->sp_pwdp;
- else
-#endif
- cp = pw->pw_passwd;
- } else
- cp = "xx";
-
-#ifdef HAVE_AUTH_METHODS
- buf = strdup(cp); /* will be modified by strtok() */
- if (!buf) {
- fprintf(stderr, "Out of memory.\n");
- exit(13);
- }
- cp = strtok(buf, ";");
- while (cp && *cp == '@')
- cp = strtok(NULL, ";");
-
- /* fail if no password authentication for this user */
- if (!cp)
- cp = "xx";
-#endif
-
- if (*pass || *cp)
- result = (strcmp(crypt(pass, cp), cp) == 0);
- else
- result = 1; /* user with no password */
-
-#ifdef HAVE_AUTH_METHODS
- free(buf);
-#endif
- return result;
-}
-
-/*
- * Main program.
- */
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- struct passwd *pw;
- char *pass, *name;
- char myname[32];
-
-#ifdef USE_SYSLOG
- openlog("pwdauth", LOG_PID | LOG_CONS, LOG_AUTHPRIV);
-#endif
- pw = get_my_pwent();
- if (!pw) {
-#ifdef USE_SYSLOG
- syslog(LOG_ERR, "can't get login name for uid %d.\n",
- (int) getuid());
-#endif
- fprintf(stderr, "Who are you?\n");
- exit(2);
- }
- strncpy(myname, pw->pw_name, sizeof myname - 1);
- myname[sizeof myname - 1] = '\0';
- name = myname;
-
- if (argc > 1) {
- name = argv[1];
- pw = getpwnam(name);
- }
-
- pass = get_line(stdin);
- if (password_auth_ok(pw, pass)) {
-#ifdef USE_SYSLOG
- syslog(pw->pw_uid ? LOG_INFO : LOG_NOTICE,
- "user `%s' entered correct password for `%.32s'.\n",
- myname, name);
-#endif
- exit(0);
- }
-#ifdef USE_SYSLOG
- /* be careful not to overrun the syslog buffer */
- syslog((!pw || pw->pw_uid) ? LOG_NOTICE : LOG_WARNING,
- "user `%s' entered incorrect password for `%.32s'.\n",
- myname, name);
-#endif
-#ifdef FAIL_DELAY
- sleep(FAIL_DELAY);
-#endif
- fprintf(stderr, "Wrong password.\n");
- exit(1);
-}
-
-#if 0
-/*
- * You can use code similar to the following to run this program.
- * Return values: >=0 - program exit status (use the <sys/wait.h>
- * macros to get the exit code, it is shifted left by 8 bits),
- * -1 - check errno.
- */
-int
-verify_password(const char *username, const char *password)
-{
- int pipe_fd[2];
- int pid, wpid, status;
-
- if (pipe(pipe_fd))
- return -1;
-
- if ((pid = fork()) == 0) {
- char *arg[3];
- char *env[1];
-
- /* child */
- close(pipe_fd[1]);
- if (pipe_fd[0] != 0) {
- if (dup2(pipe_fd[0], 0) != 0)
- _exit(127);
- close(pipe_fd[0]);
- }
- arg[0] = "/usr/bin/pwdauth";
- arg[1] = username;
- arg[2] = NULL;
- env[0] = NULL;
- execve(arg[0], arg, env);
- _exit(127);
- } else if (pid == -1) {
- /* error */
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- return -1;
- }
- /* parent */
- close(pipe_fd[0]);
- write(pipe_fd[1], password, strlen(password));
- write(pipe_fd[1], "\n", 1);
- close(pipe_fd[1]);
-
- while ((wpid = wait(&status)) != pid) {
- if (wpid == -1)
- return -1;
- }
- return status;
-}
-#endif