]> git.mdlowis.com Git - proto/albase.git/commitdiff
Finish initial implementation of login command
authorMike Lowis <mike.lowis@gentex.com>
Thu, 28 Apr 2016 15:12:52 +0000 (11:12 -0400)
committerMike Lowis <mike.lowis@gentex.com>
Thu, 28 Apr 2016 15:12:52 +0000 (11:12 -0400)
Makefile
include/util.h
source/login.c

index 54d572056c19dc3186372e6f570a5aefbd42c799..642dbf7874ae5d0179ee22695df9b60fac76cb8d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ CC = cc
 # flags
 LIBS     =
 INCS     = -Iinclude
-CPPFLAGS = $(INCS)
+CPPFLAGS = $(INCS) -D_XOPEN_SOURCE
 CFLAGS   = -O2 $(CPPFLAGS)
 LDFLAGS  = $(LIBS)
 BUILD    = $(CC) $(CFLAGS) -o $@ $<
@@ -34,7 +34,7 @@ getty: source/getty.c
        $(BUILD)
 
 login: source/login.c
-       $(BUILD)
+       $(BUILD) -lcrypt
 
 clean:
        $(RM) $(BINS)
index 5427c1ea370f60b117a739820953e91578f298cc..95b4afa3e583445716bdf6bbc8bb8ddd4d074f42 100644 (file)
@@ -164,7 +164,7 @@ static char* estrdup(const char *s)
 }
 
 /* Option Parsing
- *
+ ******************************************************************************
  * This following macros implement a simple POSIX-style option parsing strategy.
  * They are heavily influenced and inspired by the arg.h file from suckless.org
  * (http://git.suckless.org/libsl/tree/arg.h). That file is in turn inspired by
index cce61fec9f8164fd248433881f38e7e250011a05..7c5f0b632809a20d2d991bee664eb4b7878d38a9 100644 (file)
@@ -7,22 +7,9 @@
 #include <unistd.h>
 #include <pwd.h>
 #include <shadow.h>
+#include <sys/ioctl.h>
 
-//#include <sys/ioctl.h>
-//#include <sys/types.h>
-//#include <errno.h>
-//#include <grp.h>
-//#include <pwd.h>
-//#include <stdio.h>
-//#include <stdlib.h>
-//#include <string.h>
-//#include <time.h>
-//#include <unistd.h>
-//#include <utmp.h>
-
-//#include "config.h"
-//#include "passwd.h"
-//#include "util.h"
+#define ENV_PATH "/bin"
 
 char* ARGV0;
 static char* Hostname = NULL;
@@ -45,8 +32,8 @@ static char* get_user(void) {
     if (Username == NULL) {
         printf("login: ");
         fflush(stdout);
-        fgets(username, sizeof(username)-1, stdin);
-        username[strlen(username)-1] = '\0';
+        if (fgets(username, sizeof(username)-1, stdin))
+            username[strlen(username)-1] = '\0';
         return username;
     } else {
         return Username;
@@ -54,25 +41,28 @@ static char* get_user(void) {
 }
 
 static char* get_pass(void) {
+    /* flush input buffer */
+    ioctl(0, TCFLSH, (void *)0);
     return getpass("password: ");
 }
 
-static bool check_pass(const char* user, char* pass) {
+static struct passwd* check_pass(const char* user, char* pass) {
     struct spwd* spw;
+    /* get the passwd entry */
     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;
+        return NULL;
     }
     /* Handle blank pass or blank pass entry */
     if ((pwentry->pw_passwd[0] == '\0') || (pass[0] == '\0')) {
         warn("incorrect password\n");
-        return false;
+        return NULL;
     }
-    /* Handle shadow passwd entries */
+    /* Get the shadow entry */
     if (pwentry->pw_passwd[0] == 'x' && pwentry->pw_passwd[1] == '\0') {
         errno = 0;
         spw = getspnam(pwentry->pw_name);
@@ -81,63 +71,16 @@ static bool check_pass(const char* user, char* pass) {
 
         if (spw->sp_pwdp[0] == '!' || spw->sp_pwdp[0] == '*') {
             warn("access denied\n");
-            return false;
+            return NULL;
         }
     }
     /* Check the password */
     char* cryptpass = crypt(pass, spw->sp_pwdp);
     if (strcmp(cryptpass, spw->sp_pwdp) != 0) {
         warn("incorrect password");
-        return false;
-    }
-    return true;
-}
-
-int pw_check(const struct passwd *pw, const char *pass)
-{
-    char *cryptpass, *p;
-    struct spwd *spw;
-
-    p = pw->pw_passwd;
-    if (p[0] == '!' || p[0] == '*') {
-    weprintf("denied\n");
-    return -1;
-    }
-
-    if (pw->pw_passwd[0] == '\0') {
-        if (pass[0] == '\0')
-            return 1;
-        weprintf("incorrect password\n");
-        return 0;
-    }
-
-    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;
-        }
-    }
-
-    cryptpass = crypt(pass, p);
-    if (!cryptpass) {
-    weprintf("crypt:");
-    return -1;
-    }
-    if (strcmp(cryptpass, p) != 0) {
-    weprintf("incorrect password\n");
-    return 0;
+        return NULL;
     }
-    return 1;
+    return pwentry;
 }
 
 int main(int argc, char** argv) {
@@ -153,150 +96,35 @@ int main(int argc, char** argv) {
             Username = EOPTARG(die("no username provided"));
             break;
         default:
-            die("Usage: %s [-p] [-h host] [-u user]", ARGV0);
+            fprintf(stderr,"Usage: %s [-p] [-h host] [-u user]", ARGV0);
+            exit(EXIT_FAILURE);
     } OPTEND;
-    /*  */
+    /* Print the hostname to the tty */
     if (isatty(0) == 0 || isatty(1) == 0 || isatty(2) == 0)
         die("no tty");
-    printf("%s\n", get_host());
-
-    char* user = get_user();
-    char* pass = get_pass();
-    if (check_pass(user, pass)) {
-
-    } else {
-        return EXIT_FAILURE;
+    printf("This is %s\n\n", get_host());
+    /* Get the credentials and authenticate */
+    char* user  = get_user();
+    char* pass  = get_pass();
+    struct passwd* pwentry = check_pass(user, pass);
+    while (*pass) { *(pass++) = '\0'; }
+    if (pwentry != NULL) {
+        initgroups(user, pwentry->pw_gid);
+        check(setgid(pwentry->pw_gid), "setgid failed");
+        check(setuid(pwentry->pw_uid), "setuid failed");
+        char *shell = (pwentry->pw_shell[0] ? pwentry->pw_shell : "/bin/sh");
+        if (!PreserveEnv)
+            clearenv();
+        setenv("HOME",    pwentry->pw_dir,  1);
+        setenv("SHELL",   shell,            1);
+        setenv("USER",    pwentry->pw_name, 1);
+        setenv("LOGNAME", pwentry->pw_name, 1);
+        setenv("PATH",    ENV_PATH,         1);
+        check(chdir(pwentry->pw_dir), "chdir failed");
+        execlp(shell, shell, "-l", NULL);
     }
-    return EXIT_SUCCESS;
-}
 
-//* See LICENSE file for copyright and license details. */
-//#include <sys/ioctl.h>
-//#include <sys/types.h>
-//
-//#include <errno.h>
-//#include <grp.h>
-//#include <pwd.h>
-//#include <stdio.h>
-//#include <stdlib.h>
-//#include <string.h>
-//#include <time.h>
-//#include <unistd.h>
-//#include <utmp.h>
-//
-//#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);
-//}
+    /* Handle any unexpected errors that occurred */
+error:
+    return (errno == ENOENT) ? 127 : 126;
+}