diff --git a/apps/src/session.c b/apps/src/session.c index 116e01a5..abcc707e 100644 --- a/apps/src/session.c +++ b/apps/src/session.c @@ -39,6 +39,24 @@ static void strip_newline(char* str) if (str[len - 1] == '\n') str[len - 1] = 0; } +static char* collect_password() +{ + static char buf[BUFSIZ]; + + printf("Password: "); + fgets(buf, BUFSIZ, stdin); + + strip_newline(buf); + putchar('\n'); + + char* copy = strdup( + buf); // The password only stays in a caller-controlled heap-allocated buffer, where it can be freed at will. + + memset(buf, 0, BUFSIZ); + + return copy; +} + static void login_as(struct passwd* user) { pid_t child = fork(); @@ -74,18 +92,19 @@ static int login() printf("Unknown user %s\n", username); return 0; } - printf("Password: "); - char password[BUFSIZ]; - fgets(password, BUFSIZ, stdin); - strip_newline(password); - puts("\n"); + char* password = collect_password(); + putchar('\n'); if (strcmp(user->pw_passwd, password) == 0) { + free(password); login_as(user); puts("logout\n"); } else + { + free(password); puts("Invalid password.\n"); + } return 0; } diff --git a/apps/src/su.c b/apps/src/su.c index 844ac07a..469b720c 100644 --- a/apps/src/su.c +++ b/apps/src/su.c @@ -19,13 +19,26 @@ void strip_newline(char* str) if (str[len - 1] == '\n') str[len - 1] = 0; } +static const char* collect_password() +{ + static char buf[BUFSIZ]; + + printf("Password: "); + fgets(buf, BUFSIZ, stdin); + + strip_newline(buf); + putchar('\n'); + + return buf; +} + int main(int argc, char** argv) { - if (argc == 1) - { - fprintf(stderr, "Usage: %s [username] [command | login shell]\n", argv[0]); - return EXIT_FAILURE; - } + const char* username; + + if (argc == 1) username = "root"; + else + username = argv[1]; if (getuid() != 0) { @@ -33,24 +46,22 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - struct passwd* user = getpwnam(argv[1]); + struct passwd* user = getpwnam(username); + + endpwent(); if (!user) { if (errno) perror("getpwnam"); else - fprintf(stderr, "Unknown user %s\n", argv[1]); + fprintf(stderr, "Unknown user %s\n", username); return EXIT_FAILURE; } if (getuid() != geteuid()) // we were started from a non-root user { - printf("Password: "); - char buf[BUFSIZ]; - fgets(buf, BUFSIZ, stdin); - strip_newline(buf); - putchar('\n'); - if (strcmp(buf, user->pw_passwd) != 0) + const char* pw = collect_password(); + if (strcmp(pw, user->pw_passwd) != 0) { fprintf(stderr, "Invalid password\n"); return EXIT_FAILURE;