blob: 44b14e6bc460387c0e6ec23ed7714808e6934c3a [file] [log] [blame]
Eric Andersen27f64e12002-06-23 04:24:25 +00001/* vi: set sw=4 ts=4: */
2/*
3 * vlock implementation for busybox
4 *
5 * Copyright (C) 2000 by spoon <spoon@ix.netcom.com>
6 * Written by spoon <spon@ix.netcom.com>
7 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02008 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Eric Andersen27f64e12002-06-23 04:24:25 +00009 */
10
11/* Shoutz to Michael K. Johnson <johnsonm@redhat.com>, author of the
12 * original vlock. I snagged a bunch of his code to write this
13 * minimalistic vlock.
14 */
15/* Fixed by Erik Andersen to do passwords the tinylogin way...
16 * It now works with md5, sha1, etc passwords. */
17
Pere Orga6a3e01d2011-04-01 22:56:30 +020018//usage:#define vlock_trivial_usage
19//usage: "[-a]"
20//usage:#define vlock_full_usage "\n\n"
21//usage: "Lock a virtual terminal. A password is required to unlock.\n"
Pere Orga6a3e01d2011-04-01 22:56:30 +020022//usage: "\n -a Lock all VTs"
23
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000024#include "libbb.h"
Eric Andersen27f64e12002-06-23 04:24:25 +000025
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020026#ifdef __linux__
27#include <sys/vt.h>
28
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +000029static void release_vt(int signo UNUSED_PARAM)
Eric Andersen27f64e12002-06-23 04:24:25 +000030{
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000031 /* If -a, param is 0, which means:
32 * "no, kernel, we don't allow console switch away from us!" */
33 ioctl(STDIN_FILENO, VT_RELDISP, (unsigned long) !option_mask32);
Eric Andersen27f64e12002-06-23 04:24:25 +000034}
35
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +000036static void acquire_vt(int signo UNUSED_PARAM)
Eric Andersen27f64e12002-06-23 04:24:25 +000037{
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000038 /* ACK to kernel that switch to console is successful */
39 ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
Eric Andersen27f64e12002-06-23 04:24:25 +000040}
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020041#endif
Eric Andersen27f64e12002-06-23 04:24:25 +000042
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000043int vlock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +000044int vlock_main(int argc UNUSED_PARAM, char **argv)
Eric Andersen27f64e12002-06-23 04:24:25 +000045{
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020046#ifdef __linux__
Eric Andersen27f64e12002-06-23 04:24:25 +000047 struct vt_mode vtm;
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020048 struct vt_mode ovtm;
49#endif
Eric Andersen27f64e12002-06-23 04:24:25 +000050 struct termios term;
Denis Vlasenko33b900f2007-09-27 10:12:02 +000051 struct termios oterm;
Denis Vlasenko33b900f2007-09-27 10:12:02 +000052 struct passwd *pw;
Eric Andersen27f64e12002-06-23 04:24:25 +000053
Denis Vlasenko0c68a872008-12-02 22:56:59 +000054 pw = xgetpwuid(getuid());
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000055 opt_complementary = "=0"; /* no params! */
56 getopt32(argv, "a");
Eric Andersen27f64e12002-06-23 04:24:25 +000057
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000058 /* Ignore some signals so that we don't get killed by them */
59 bb_signals(0
60 + (1 << SIGTSTP)
61 + (1 << SIGTTIN)
62 + (1 << SIGTTOU)
63 + (1 << SIGHUP )
64 + (1 << SIGCHLD) /* paranoia :) */
65 + (1 << SIGQUIT)
66 + (1 << SIGINT )
67 , SIG_IGN);
Rob Landley68eb9dd2005-12-19 02:50:10 +000068
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020069#ifdef __linux__
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000070 /* We will use SIGUSRx for console switch control: */
71 /* 1: set handlers */
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000072 signal_SA_RESTART_empty_mask(SIGUSR1, release_vt);
73 signal_SA_RESTART_empty_mask(SIGUSR2, acquire_vt);
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000074 /* 2: unmask them */
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000075 sig_unblock(SIGUSR1);
76 sig_unblock(SIGUSR2);
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020077#endif
Eric Andersen27f64e12002-06-23 04:24:25 +000078
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000079 /* Revert stdin/out to our controlling tty
80 * (or die if we have none) */
81 xmove_fd(xopen(CURRENT_TTY, O_RDWR), STDIN_FILENO);
82 xdup2(STDIN_FILENO, STDOUT_FILENO);
Eric Andersen27f64e12002-06-23 04:24:25 +000083
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020084#ifdef __linux__
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000085 xioctl(STDIN_FILENO, VT_GETMODE, &vtm);
Eric Andersen27f64e12002-06-23 04:24:25 +000086 ovtm = vtm;
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000087 /* "console switches are controlled by us, not kernel!" */
Eric Andersen27f64e12002-06-23 04:24:25 +000088 vtm.mode = VT_PROCESS;
89 vtm.relsig = SIGUSR1;
90 vtm.acqsig = SIGUSR2;
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000091 ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
Jeremie Koenig68fca4c2010-07-29 04:29:52 +020092#endif
Eric Andersen27f64e12002-06-23 04:24:25 +000093
94 tcgetattr(STDIN_FILENO, &oterm);
95 term = oterm;
96 term.c_iflag &= ~BRKINT;
97 term.c_iflag |= IGNBRK;
98 term.c_lflag &= ~ISIG;
99 term.c_lflag &= ~(ECHO | ECHOCTL);
Denis Vlasenko202ac502008-11-05 13:20:58 +0000100 tcsetattr_stdin_TCSANOW(&term);
Eric Andersen27f64e12002-06-23 04:24:25 +0000101
Denys Vlasenko940c7202011-03-02 04:07:14 +0100102 while (1) {
Denis Vlasenko33b900f2007-09-27 10:12:02 +0000103 printf("Virtual console%s locked by %s.\n",
Denys Vlasenko940c7202011-03-02 04:07:14 +0100104 /* "s" if -a, else "": */ "s" + !option_mask32,
105 pw->pw_name
106 );
maxwen27116ba2015-08-14 21:41:28 +0200107 if (ask_and_check_password(pw) > 0) {
Rob Landley68eb9dd2005-12-19 02:50:10 +0000108 break;
Eric Andersen27f64e12002-06-23 04:24:25 +0000109 }
Denys Vlasenko7d4e7a22011-03-08 21:07:05 +0100110 bb_do_delay(LOGIN_FAIL_DELAY);
111 puts("Incorrect password");
Denys Vlasenko940c7202011-03-02 04:07:14 +0100112 }
Denis Vlasenko33b900f2007-09-27 10:12:02 +0000113
Jeremie Koenig68fca4c2010-07-29 04:29:52 +0200114#ifdef __linux__
Denis Vlasenko4cf1d082008-03-12 23:13:50 +0000115 ioctl(STDIN_FILENO, VT_SETMODE, &ovtm);
Jeremie Koenig68fca4c2010-07-29 04:29:52 +0200116#endif
Denis Vlasenko202ac502008-11-05 13:20:58 +0000117 tcsetattr_stdin_TCSANOW(&oterm);
Bernhard Reutner-Fischer636a1f82008-05-19 09:29:47 +0000118 fflush_stdout_and_exit(EXIT_SUCCESS);
Eric Andersen27f64e12002-06-23 04:24:25 +0000119}