From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- release/src/router/busybox/loginutils/vlock.c | 248 ++++++-------------------- 1 file changed, 58 insertions(+), 190 deletions(-) (limited to 'release/src/router/busybox/loginutils/vlock.c') diff --git a/release/src/router/busybox/loginutils/vlock.c b/release/src/router/busybox/loginutils/vlock.c index 7abf120d..85f489c2 100644 --- a/release/src/router/busybox/loginutils/vlock.c +++ b/release/src/router/busybox/loginutils/vlock.c @@ -5,20 +5,7 @@ * Copyright (C) 2000 by spoon * Written by spoon * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ /* Shoutz to Michael K. Johnson , author of the @@ -28,149 +15,66 @@ /* Fixed by Erik Andersen to do passwords the tinylogin way... * It now works with md5, sha1, etc passwords. */ -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include "busybox.h" - -static struct passwd *pw; -static struct vt_mode ovtm; -static struct termios oterm; -static int vfd; -static int o_lock_all = 0; - -#ifdef CONFIG_FEATURE_SHADOWPASSWDS -static struct spwd *spw; - -/* getspuid - get a shadow entry by uid */ -struct spwd *getspuid(uid_t uid) -{ - struct spwd *sp; - struct passwd *mypw; - - if ((mypw = getpwuid(getuid())) == NULL) { - return (NULL); - } - setspent(); - while ((sp = getspent()) != NULL) { - if (strcmp(mypw->pw_name, sp->sp_namp) == 0) - break; - } - endspent(); - return (sp); -} -#endif +#include "libbb.h" -static void release_vt(int signo) +static void release_vt(int signo UNUSED_PARAM) { - if (!o_lock_all) - ioctl(vfd, VT_RELDISP, 1); - else - ioctl(vfd, VT_RELDISP, 0); + /* If -a, param is 0, which means: + * "no, kernel, we don't allow console switch away from us!" */ + ioctl(STDIN_FILENO, VT_RELDISP, (unsigned long) !option_mask32); } -static void acquire_vt(int signo) +static void acquire_vt(int signo UNUSED_PARAM) { - ioctl(vfd, VT_RELDISP, VT_ACKACQ); + /* ACK to kernel that switch to console is successful */ + ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ); } -static void restore_terminal(void) +int vlock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int vlock_main(int argc UNUSED_PARAM, char **argv) { - ioctl(vfd, VT_SETMODE, &ovtm); - tcsetattr(STDIN_FILENO, TCSANOW, &oterm); -} - -extern int vlock_main(int argc, char **argv) -{ - sigset_t sig; - struct sigaction sa; struct vt_mode vtm; - int times = 0; struct termios term; - - if (argc > 2) { - bb_show_usage(); - } - - if (argc == 2) { - if (strncmp(argv[1], "-a", 2)) { - bb_show_usage(); - } else { - o_lock_all = 1; - } - } - - if ((pw = getpwuid(getuid())) == NULL) { - bb_error_msg_and_die("no password for uid %d\n", getuid()); - } -#ifdef CONFIG_FEATURE_SHADOWPASSWDS - if ((strcmp(pw->pw_passwd, "x") == 0) - || (strcmp(pw->pw_passwd, "*") == 0)) { - - if ((spw = getspuid(getuid())) == NULL) { - bb_error_msg_and_die("could not read shadow password for uid %d: %s\n", - getuid(), strerror(errno)); - } - if (spw->sp_pwdp) { - pw->pw_passwd = spw->sp_pwdp; - } - } -#endif /* CONFIG_FEATURE_SHADOWPASSWDS */ - if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') { - bb_error_msg_and_die("Account disabled for uid %d\n", getuid()); - } - - /* we no longer need root privs */ - setuid(getuid()); - setgid(getgid()); - - if ((vfd = open("/dev/tty", O_RDWR)) < 0) { - bb_error_msg_and_die("/dev/tty"); - }; - - if (ioctl(vfd, VT_GETMODE, &vtm) < 0) { - bb_error_msg_and_die("/dev/tty"); - }; - - /* mask a bunch of signals */ - sigprocmask(SIG_SETMASK, NULL, &sig); - sigdelset(&sig, SIGUSR1); - sigdelset(&sig, SIGUSR2); - sigaddset(&sig, SIGTSTP); - sigaddset(&sig, SIGTTIN); - sigaddset(&sig, SIGTTOU); - sigaddset(&sig, SIGHUP); - sigaddset(&sig, SIGCHLD); - sigaddset(&sig, SIGQUIT); - sigaddset(&sig, SIGINT); - - sigemptyset(&(sa.sa_mask)); - sa.sa_flags = SA_RESTART; - sa.sa_handler = release_vt; - sigaction(SIGUSR1, &sa, NULL); - sa.sa_handler = acquire_vt; - sigaction(SIGUSR2, &sa, NULL); - - /* need to handle some signals so that we don't get killed by them */ - sa.sa_handler = SIG_IGN; - sigaction(SIGHUP, &sa, NULL); - sigaction(SIGQUIT, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTSTP, &sa, NULL); - + struct termios oterm; + struct vt_mode ovtm; + struct passwd *pw; + + pw = xgetpwuid(getuid()); + opt_complementary = "=0"; /* no params! */ + getopt32(argv, "a"); + + /* Ignore some signals so that we don't get killed by them */ + bb_signals(0 + + (1 << SIGTSTP) + + (1 << SIGTTIN) + + (1 << SIGTTOU) + + (1 << SIGHUP ) + + (1 << SIGCHLD) /* paranoia :) */ + + (1 << SIGQUIT) + + (1 << SIGINT ) + , SIG_IGN); + + /* We will use SIGUSRx for console switch control: */ + /* 1: set handlers */ + signal_SA_RESTART_empty_mask(SIGUSR1, release_vt); + signal_SA_RESTART_empty_mask(SIGUSR2, acquire_vt); + /* 2: unmask them */ + sig_unblock(SIGUSR1); + sig_unblock(SIGUSR2); + + /* Revert stdin/out to our controlling tty + * (or die if we have none) */ + xmove_fd(xopen(CURRENT_TTY, O_RDWR), STDIN_FILENO); + xdup2(STDIN_FILENO, STDOUT_FILENO); + + xioctl(STDIN_FILENO, VT_GETMODE, &vtm); ovtm = vtm; + /* "console switches are controlled by us, not kernel!" */ vtm.mode = VT_PROCESS; vtm.relsig = SIGUSR1; vtm.acqsig = SIGUSR2; - ioctl(vfd, VT_SETMODE, &vtm); + ioctl(STDIN_FILENO, VT_SETMODE, &vtm); tcgetattr(STDIN_FILENO, &oterm); term = oterm; @@ -178,56 +82,20 @@ extern int vlock_main(int argc, char **argv) term.c_iflag |= IGNBRK; term.c_lflag &= ~ISIG; term.c_lflag &= ~(ECHO | ECHOCTL); - tcsetattr(STDIN_FILENO, TCSANOW, &term); + tcsetattr_stdin_TCSANOW(&term); do { - char *pass, *crypt_pass; - char prompt[100]; - - if (o_lock_all) { - printf("All Virtual Consoles locked.\n"); - } else { - printf("This Virtual Console locked.\n"); - } - fflush(stdout); - - snprintf(prompt, 100, "%s's password: ", pw->pw_name); - - if ((pass = getpass(prompt)) == NULL) { - perror("getpass"); - restore_terminal(); - exit(1); - } - - crypt_pass = pw_encrypt(pass, pw->pw_passwd); - if (strncmp(crypt_pass, pw->pw_passwd, sizeof(crypt_pass)) == 0) { - memset(pass, 0, strlen(pass)); - memset(crypt_pass, 0, strlen(crypt_pass)); - restore_terminal(); - return 0; - } - memset(pass, 0, strlen(pass)); - memset(crypt_pass, 0, strlen(crypt_pass)); - - if (isatty(STDIN_FILENO) == 0) { - perror("isatty"); - restore_terminal(); - exit(1); - } - - sleep(++times); - printf("Password incorrect.\n"); - if (times >= 3) { - sleep(15); - times = 2; + printf("Virtual console%s locked by %s.\n", + option_mask32 /*o_lock_all*/ ? "s" : "", + pw->pw_name); + if (correct_password(pw)) { + break; } + bb_do_delay(FAIL_DELAY); + puts("Password incorrect"); } while (1); -} -/* -Local Variables: -c-file-style: "linux" -c-basic-offset: 4 -tab-width: 4 -End: -*/ + ioctl(STDIN_FILENO, VT_SETMODE, &ovtm); + tcsetattr_stdin_TCSANOW(&oterm); + fflush_stdout_and_exit(EXIT_SUCCESS); +} -- cgit v1.2.3-54-g00ecf