micro-utils/src/loginutils/login/login.c

124 lines
2.3 KiB
C
Raw Normal View History

2024-01-13 22:18:21 +00:00
#include <pwd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <signal.h>
2024-01-20 17:28:02 +00:00
#include <termios.h>
2024-01-13 22:18:21 +00:00
#include "pw_check.h"
2024-01-20 17:28:02 +00:00
#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL)
int hide_input(int fd, int flag) {
struct termios term;
if (tcgetattr(fd, &term) < 0)
return 1;
if (flag)
term.c_lflag &= ~ECHOFLAGS;
else
term.c_lflag |= ECHOFLAGS;
if (tcsetattr(fd, TCSAFLUSH, &term) < 0)
return 1;
return 0;
}
2024-01-13 22:18:21 +00:00
void login(const struct passwd *pw) {
2024-02-03 15:36:30 +00:00
char *shell = (pw->pw_shell[0] == '\0') ? "/bin/sh" : pw->pw_shell;
2024-01-13 22:18:21 +00:00
setenv("HOME", pw->pw_dir, 1);
setenv("SHELL", shell, 1);
setenv("USER", pw->pw_name, 1);
setenv("LOGNAME", pw->pw_name, 1);
2024-01-21 10:07:27 +00:00
setenv("PATH", "/bin", 1);
2024-01-13 22:18:21 +00:00
if (chdir(pw->pw_dir) < 0) {
fprintf(stderr, "login: %s\n", strerror(errno));
return;
}
execlp(shell, shell, "-l", NULL);
}
struct passwd *proccess_input(char *hostname) {
static char user[512];
static char psswd[512];
/* Username */
2024-01-21 10:07:27 +00:00
printf("Login on %s: ", hostname);
fflush(stdout);
2024-03-27 19:04:17 +00:00
off_t ret = 0;
if ((ret = read(STDIN_FILENO, user, sizeof(user))) <= 0)
2024-01-13 22:18:21 +00:00
return NULL;
2024-03-27 19:04:17 +00:00
user[ret - 1] = '\0';
2024-01-13 22:18:21 +00:00
struct passwd *pw = getpwnam(user);
if (!pw) {
fprintf(stderr, "login: Incorrent username\n");
return NULL;
}
/* Password */
2024-01-21 10:07:27 +00:00
printf("Password: ");
fflush(stdout);
2024-01-20 17:28:02 +00:00
if (hide_input(STDIN_FILENO, 1))
return NULL;
2024-03-27 19:04:17 +00:00
if ((ret = read(STDIN_FILENO, psswd, sizeof(psswd))) <= 0)
2024-01-13 22:18:21 +00:00
return NULL;
2024-03-27 19:04:17 +00:00
psswd[ret - 1] = '\0';
2024-01-21 10:07:27 +00:00
printf("\n");
2024-01-13 22:18:21 +00:00
if (pw_check("login", pw, psswd)) {
memset(psswd, '\0', sizeof(psswd));
return NULL;
}
memset(psswd, '\0', sizeof(psswd));
return pw;
}
int main(void) {
if ((!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO))) {
fprintf(stderr, "login: no tty\n");
return 1;
}
/* For prompt */
char hostname[HOST_NAME_MAX + 1];
if (gethostname(hostname, sizeof(hostname)) < 0) {
fprintf(stderr, "login: %s\n", strerror(errno));
return 1;
}
signal(SIGQUIT, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
struct passwd *pw = proccess_input(hostname);
2024-01-20 17:28:02 +00:00
hide_input(STDIN_FILENO, 0);
2024-01-13 22:18:21 +00:00
if (!pw)
return 1;
/* Start */
if (setgid(pw->pw_gid) < 0) {
fprintf(stderr, "login: %s\n", strerror(errno));
return 1;
}
if (setuid(pw->pw_uid) < 0) {
fprintf(stderr, "login: %s\n", strerror(errno));
return 1;
}
login(pw);
return 0;
}