session, su: Split password-collecting logic into a separate function
This commit is contained in:
parent
3e052c72a0
commit
8375701bf6
@ -39,6 +39,24 @@ static void strip_newline(char* str)
|
|||||||
if (str[len - 1] == '\n') str[len - 1] = 0;
|
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)
|
static void login_as(struct passwd* user)
|
||||||
{
|
{
|
||||||
pid_t child = fork();
|
pid_t child = fork();
|
||||||
@ -74,18 +92,19 @@ static int login()
|
|||||||
printf("Unknown user %s\n", username);
|
printf("Unknown user %s\n", username);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf("Password: ");
|
char* password = collect_password();
|
||||||
char password[BUFSIZ];
|
putchar('\n');
|
||||||
fgets(password, BUFSIZ, stdin);
|
|
||||||
strip_newline(password);
|
|
||||||
puts("\n");
|
|
||||||
if (strcmp(user->pw_passwd, password) == 0)
|
if (strcmp(user->pw_passwd, password) == 0)
|
||||||
{
|
{
|
||||||
|
free(password);
|
||||||
login_as(user);
|
login_as(user);
|
||||||
puts("logout\n");
|
puts("logout\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
free(password);
|
||||||
puts("Invalid password.\n");
|
puts("Invalid password.\n");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,13 +19,26 @@ void strip_newline(char* str)
|
|||||||
if (str[len - 1] == '\n') str[len - 1] = 0;
|
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)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc == 1)
|
const char* username;
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: %s [username] [command | login shell]\n", argv[0]);
|
if (argc == 1) username = "root";
|
||||||
return EXIT_FAILURE;
|
else
|
||||||
}
|
username = argv[1];
|
||||||
|
|
||||||
if (getuid() != 0)
|
if (getuid() != 0)
|
||||||
{
|
{
|
||||||
@ -33,24 +46,22 @@ int main(int argc, char** argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct passwd* user = getpwnam(argv[1]);
|
struct passwd* user = getpwnam(username);
|
||||||
|
|
||||||
|
endpwent();
|
||||||
|
|
||||||
if (!user)
|
if (!user)
|
||||||
{
|
{
|
||||||
if (errno) perror("getpwnam");
|
if (errno) perror("getpwnam");
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Unknown user %s\n", argv[1]);
|
fprintf(stderr, "Unknown user %s\n", username);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getuid() != geteuid()) // we were started from a non-root user
|
if (getuid() != geteuid()) // we were started from a non-root user
|
||||||
{
|
{
|
||||||
printf("Password: ");
|
const char* pw = collect_password();
|
||||||
char buf[BUFSIZ];
|
if (strcmp(pw, user->pw_passwd) != 0)
|
||||||
fgets(buf, BUFSIZ, stdin);
|
|
||||||
strip_newline(buf);
|
|
||||||
putchar('\n');
|
|
||||||
if (strcmp(buf, user->pw_passwd) != 0)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid password\n");
|
fprintf(stderr, "Invalid password\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
Loading…
Reference in New Issue
Block a user