session, su: Split password-collecting logic into a separate function

This commit is contained in:
apio 2022-10-29 10:01:44 +02:00
parent 3e052c72a0
commit 8375701bf6
2 changed files with 48 additions and 18 deletions

View File

@ -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;
}

View File

@ -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;