/* This file is part of ToaruOS and is released under the terms * of the NCSA / University of Illinois License - see LICENSE.md * Copyright (C) 2014 Kevin Lange */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * * sudo * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "lib/sha2.h" #define LINE_LEN 1024 uint32_t child = 0; int checkUserPass(char * user, char * pass) { /* Generate SHA512 */ char hash[SHA512_DIGEST_STRING_LENGTH]; SHA512_Data(pass, strlen(pass), hash); /* Open up /etc/master.passwd */ FILE * passwd = fopen("/etc/master.passwd", "r"); char line[2048]; while (fgets(line, 2048, passwd) != NULL) { line[strlen(line)-1] = '\0'; char *p, *tokens[4], *last; int i = 0; for ((p = strtok_r(line, ":", &last)); p; (p = strtok_r(NULL, ":", &last)), i++) { if (i < 511) tokens[i] = p; } tokens[i] = NULL; if (strcmp(tokens[0],user) != 0) { continue; } if (!strcmp(tokens[1],hash)) { fclose(passwd); return atoi(tokens[2]); } } fclose(passwd); return -1; } void usage(int argc, char * argv[]) { fprintf(stderr, "usage: %s [command]\n", argv[0]); } int main(int argc, char ** argv) { int fails = 0; if (argc < 2) { usage(argc, argv); return 1; } while (1) { /* * This is not very secure, but I'm lazy and just want this to exist. * It's not like we have file system permissions or anything like * that sitting around anyway... So, XXX: make this not dumb. */ char * username = getenv("USER"); char * password = malloc(sizeof(char) * 1024); fprintf(stdout, "[%s] password for %s: ", argv[0], username); fflush(stdout); /* Disable echo */ struct termios old, new; tcgetattr(fileno(stdin), &old); new = old; new.c_lflag &= (~ECHO); tcsetattr(fileno(stdin), TCSAFLUSH, &new); fgets(password, 1024, stdin); password[strlen(password)-1] = '\0'; tcsetattr(fileno(stdin), TCSAFLUSH, &old); fprintf(stdout, "\n"); int uid = checkUserPass(username, password); if (uid < 0) { fails++; if (fails == 3) { fprintf(stderr, "%s: %d incorrect password attempts\n", argv[0]); break; } fprintf(stderr, "Sorry, try again.\n"); continue; } char ** args = &argv[1]; int i = execvp(args[0], args); /* XXX: There are other things that can cause an exec to fail. */ fprintf(stderr, "%s: %s: command not found\n", argv[0], args[0]); } return 1; }