From: Michael D. Lowis Date: Thu, 28 Apr 2016 01:54:31 +0000 (-0400) Subject: started implementing password checking logic X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=05c69351ae92d10e3596fcbed5b7e0540adfd0bf;p=proto%2Falbase.git started implementing password checking logic --- diff --git a/Makefile b/Makefile index eebb6c62..54d57205 100644 --- a/Makefile +++ b/Makefile @@ -7,15 +7,15 @@ CC = cc # flags LIBS = INCS = -Iinclude -CPPFLAGS = -CFLAGS = -O2 $(INCS) $(CPPFLAGS) +CPPFLAGS = $(INCS) +CFLAGS = -O2 $(CPPFLAGS) LDFLAGS = $(LIBS) BUILD = $(CC) $(CFLAGS) -o $@ $< #------------------------------------------------------------------------------ # Build-Specific Macros #------------------------------------------------------------------------------ -BINS = init getty +BINS = init getty login # load user-specific settings -include config.mk @@ -33,6 +33,9 @@ init: source/init.c getty: source/getty.c $(BUILD) +login: source/login.c + $(BUILD) + clean: $(RM) $(BINS) diff --git a/source/login.c b/source/login.c index ec9b8008..cce61fec 100644 --- a/source/login.c +++ b/source/login.c @@ -1,130 +1,302 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include +/** + @brief + @author Michael D. Lowis + @license BSD 2-clause License +*/ +#include "util.h" #include -#include +#include +#include -#include "config.h" -#include "passwd.h" -#include "util.h" +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include -/* Write utmp entry */ -static void -writeutmp(const char *user, const char *tty) -{ - struct utmp usr; - FILE *fp; - - memset(&usr, 0, sizeof(usr)); - - usr.ut_type = USER_PROCESS; - usr.ut_pid = getpid(); - strlcpy(usr.ut_user, user, sizeof(usr.ut_user)); - strlcpy(usr.ut_line, tty, sizeof(usr.ut_line)); - usr.ut_tv.tv_sec = time(NULL); - - fp = fopen(UTMP_PATH, "a"); - if (fp) { - if (fwrite(&usr, sizeof(usr), 1, fp) != 1) - if (ferror(fp)) - weprintf("%s: write error:", UTMP_PATH); - fclose(fp); +//#include "config.h" +//#include "passwd.h" +//#include "util.h" + +char* ARGV0; +static char* Hostname = NULL; +static char* Username = NULL; +static char* Password = NULL; +static bool PreserveEnv = false; + +static char* get_host(void) { + static char hostname[256] = { 0 }; + if (Hostname == NULL) { + gethostname(hostname, sizeof(hostname)-1); + return hostname; } else { - weprintf("fopen %s:", UTMP_PATH); + return Hostname; } } -static int -dologin(struct passwd *pw, int preserve) -{ - char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell; - - if (preserve == 0) - clearenv(); - setenv("HOME", pw->pw_dir, 1); - setenv("SHELL", shell, 1); - setenv("USER", pw->pw_name, 1); - setenv("LOGNAME", pw->pw_name, 1); - setenv("PATH", ENV_PATH, 1); - if (chdir(pw->pw_dir) < 0) - eprintf("chdir %s:", pw->pw_dir); - execlp(shell, shell, "-l", NULL); - weprintf("execlp %s:", shell); - return (errno == ENOENT) ? 127 : 126; +static char* get_user(void) { + static char username[256] = { 0 }; + if (Username == NULL) { + printf("login: "); + fflush(stdout); + fgets(username, sizeof(username)-1, stdin); + username[strlen(username)-1] = '\0'; + return username; + } else { + return Username; + } } -static void -usage(void) -{ - eprintf("usage: %s [-p] username\n", argv0); +static char* get_pass(void) { + return getpass("password: "); } -int -main(int argc, char *argv[]) -{ - struct passwd *pw; - char *pass, *user; - char *tty; - uid_t uid; - gid_t gid; - int pflag = 0; - - ARGBEGIN { - case 'p': - pflag = 1; - break; - default: - usage(); - } ARGEND; - - if (argc < 1) - usage(); +static bool check_pass(const char* user, char* pass) { + struct spwd* spw; + struct passwd* pwentry = getpwnam(user); + if (!pwentry || errno) + die("Could not find entry for user: %s", user); + /* Handle disabled accounts */ + if (pwentry->pw_passwd[0] == '!' || pwentry->pw_passwd[0] == '*') { + warn("access denied"); + return false; + } + /* Handle blank pass or blank pass entry */ + if ((pwentry->pw_passwd[0] == '\0') || (pass[0] == '\0')) { + warn("incorrect password\n"); + return false; + } + /* Handle shadow passwd entries */ + if (pwentry->pw_passwd[0] == 'x' && pwentry->pw_passwd[1] == '\0') { + errno = 0; + spw = getspnam(pwentry->pw_name); + if (!spw || errno) + die("could not retrieve shadow entry for %s", user); - if (isatty(0) == 0 || isatty(1) == 0 || isatty(2) == 0) - eprintf("no tty"); - - user = argv[0]; - errno = 0; - pw = getpwnam(user); - if (!pw) { - if (errno) - eprintf("getpwnam %s:", user); - else - eprintf("who are you?\n"); + if (spw->sp_pwdp[0] == '!' || spw->sp_pwdp[0] == '*') { + warn("access denied\n"); + return false; + } + } + /* Check the password */ + char* cryptpass = crypt(pass, spw->sp_pwdp); + if (strcmp(cryptpass, spw->sp_pwdp) != 0) { + warn("incorrect password"); + return false; } + return true; +} - uid = pw->pw_uid; - gid = pw->pw_gid; +int pw_check(const struct passwd *pw, const char *pass) +{ + char *cryptpass, *p; + struct spwd *spw; - /* Flush pending input */ - ioctl(0, TCFLSH, (void *)0); + p = pw->pw_passwd; + if (p[0] == '!' || p[0] == '*') { + weprintf("denied\n"); + return -1; + } - pass = getpass("Password: "); - if (!pass) - eprintf("getpass:"); - if (pw_check(pw, pass) <= 0) - exit(1); + if (pw->pw_passwd[0] == '\0') { + if (pass[0] == '\0') + return 1; + weprintf("incorrect password\n"); + return 0; + } - tty = ttyname(0); - if (!tty) - eprintf("ttyname:"); + if (pw->pw_passwd[0] == 'x' && pw->pw_passwd[1] == '\0') { + errno = 0; + spw = getspnam(pw->pw_name); + if (!spw) { + if (errno) + weprintf("getspnam: %s:", pw->pw_name); + else + weprintf("who are you?\n"); + return -1; + } + p = spw->sp_pwdp; + if (p[0] == '!' || p[0] == '*') { + weprintf("denied\n"); + return -1; + } + } - writeutmp(user, tty); + cryptpass = crypt(pass, p); + if (!cryptpass) { + weprintf("crypt:"); + return -1; + } + if (strcmp(cryptpass, p) != 0) { + weprintf("incorrect password\n"); + return 0; + } + return 1; +} + +int main(int argc, char** argv) { + /* Parse command line options */ + OPTBEGIN { + case 'p': + PreserveEnv = true; + break; + case 'h': + Hostname = EOPTARG(die("no hostname provided")); + break; + case 'u': + Username = EOPTARG(die("no username provided")); + break; + default: + die("Usage: %s [-p] [-h host] [-u user]", ARGV0); + } OPTEND; + /* */ + if (isatty(0) == 0 || isatty(1) == 0 || isatty(2) == 0) + die("no tty"); + printf("%s\n", get_host()); - if (initgroups(user, gid) < 0) - eprintf("initgroups:"); - if (setgid(gid) < 0) - eprintf("setgid:"); - if (setuid(uid) < 0) - eprintf("setuid:"); + char* user = get_user(); + char* pass = get_pass(); + if (check_pass(user, pass)) { - return dologin(pw, pflag); + } else { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } + +//* See LICENSE file for copyright and license details. */ +//#include +//#include +// +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +// +//#include "config.h" +//#include "passwd.h" +//#include "util.h" +// +///* Write utmp entry */ +//static void +//writeutmp(const char *user, const char *tty) +//{ +// struct utmp usr; +// FILE *fp; +// +// memset(&usr, 0, sizeof(usr)); +// +// usr.ut_type = USER_PROCESS; +// usr.ut_pid = getpid(); +// strlcpy(usr.ut_user, user, sizeof(usr.ut_user)); +// strlcpy(usr.ut_line, tty, sizeof(usr.ut_line)); +// usr.ut_tv.tv_sec = time(NULL); +// +// fp = fopen(UTMP_PATH, "a"); +// if (fp) { +// if (fwrite(&usr, sizeof(usr), 1, fp) != 1) +// if (ferror(fp)) +// weprintf("%s: write error:", UTMP_PATH); +// fclose(fp); +// } else { +// weprintf("fopen %s:", UTMP_PATH); +// } +//} +// +//static int +//dologin(struct passwd *pw, int preserve) +//{ +// char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell; +// +// if (preserve == 0) +// clearenv(); +// setenv("HOME", pw->pw_dir, 1); +// setenv("SHELL", shell, 1); +// setenv("USER", pw->pw_name, 1); +// setenv("LOGNAME", pw->pw_name, 1); +// setenv("PATH", ENV_PATH, 1); +// if (chdir(pw->pw_dir) < 0) +// eprintf("chdir %s:", pw->pw_dir); +// execlp(shell, shell, "-l", NULL); +// weprintf("execlp %s:", shell); +// return (errno == ENOENT) ? 127 : 126; +//} +// +//static void +//usage(void) +//{ +// eprintf("usage: %s [-p] username\n", argv0); +//} +// +//int +//main(int argc, char *argv[]) +//{ +// struct passwd *pw; +// char *pass, *user; +// char *tty; +// uid_t uid; +// gid_t gid; +// int pflag = 0; +// +// ARGBEGIN { +// case 'p': +// pflag = 1; +// break; +// default: +// usage(); +// } ARGEND; +// +// if (argc < 1) +// usage(); +// +// if (isatty(0) == 0 || isatty(1) == 0 || isatty(2) == 0) +// eprintf("no tty"); +// +// user = argv[0]; +// errno = 0; +// pw = getpwnam(user); +// if (!pw) { +// if (errno) +// eprintf("getpwnam %s:", user); +// else +// eprintf("who are you?\n"); +// } +// +// uid = pw->pw_uid; +// gid = pw->pw_gid; +// +// /* Flush pending input */ +// ioctl(0, TCFLSH, (void *)0); +// +// pass = getpass("Password: "); +// if (!pass) +// eprintf("getpass:"); +// if (pw_check(pw, pass) <= 0) +// exit(1); +// +// tty = ttyname(0); +// if (!tty) +// eprintf("ttyname:"); +// +// writeutmp(user, tty); +// +// if (initgroups(user, gid) < 0) +// eprintf("initgroups:"); +// if (setgid(gid) < 0) +// eprintf("setgid:"); +// if (setuid(uid) < 0) +// eprintf("setuid:"); +// +// return dologin(pw, pflag); +//}