Console locking

Chris Atenasio (root@lilo.dyn.ml.org)
Wed, 8 Apr 1998 21:36:39 -0400 (EDT)


Ok this is my first _real_ kernel patch so pay attention! :) The problem:
Lets say you want to be able to lock other people out of yer console but
dont want to constantly have to log out and back in. Until recently I was
using a nice program called vlock which would lock out all vt's until the
correct password was entered. Enter SysRq. Now the correct password for
vlock seems to be alt-printscreen-k... Fearing this I sat down today and
wrote a little console locking hack. This uses a SysRq to call a lock but
after locked, it grabs keys before SysRq can get them, effectively
avoiding damage. The first time you lock it it asks for a password and
then remembers that for future locks. Feedback !please! as I probably
broke all kinds of kernel standards :)

- Chris
--------------------------------------------------------------------------------
Chris Atenasio (chrisa@ultranet.com root@lilo.dyn.ml.org chrisa@casc.com)
Send me mail with subject "send pgp key" or "word of the day" for autoresponse.

diff -ur old/Documentation/Configure.help linux/Documentation/Configure.help
--- old/Documentation/Configure.help Thu Apr 2 11:42:29 1998
+++ linux/Documentation/Configure.help Wed Apr 8 20:49:12 1998
@@ -7032,6 +7032,17 @@
mean is "Use the source, Luke!" -- read drivers/char/sysrq.c.
Don't say Y unless you really know what this hack does.

+Console locking
+CONFIG_LOCK_CONSOLE
+ This is a SysRq addon which allows password protection of the console.
+ Having been conceived when SysRq made vlock obsolete, it intervenes
+ directly before SysRq keys and therefore keeps untrusted persons from
+ gaining control of the console.
+
+Maximum password length
+CONFIG_LOCK_CONSOLE_PLEN
+ The maximum allowable length of a console locking password.
+
ISDN subsystem
CONFIG_ISDN
ISDN ("Integrated Services Digital Networks", called RNIS in France)
diff -ur old/arch/i386/config.in linux/arch/i386/config.in
--- old/arch/i386/config.in Thu Apr 2 11:42:29 1998
+++ linux/arch/i386/config.in Wed Apr 8 20:49:19 1998
@@ -144,6 +144,12 @@
int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
fi
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_MAGIC_SYSRQ" = "y" ]; then
+ bool ' Console locking' CONFIG_LOCK_CONSOLE
+ if [ "$CONFIG_LOCK_CONSOLE" = "y" ]; then
+ int ' Maximum password length' CONFIG_LOCK_CONSOLE_PLEN 8
+ fi
+fi
endmenu

define_bool CONFIG_VGA_CONSOLE y
diff -ur old/drivers/char/keyboard.c linux/drivers/char/keyboard.c
--- old/drivers/char/keyboard.c Sun Mar 22 20:57:13 1998
+++ linux/drivers/char/keyboard.c Wed Apr 8 20:59:57 1998
@@ -19,6 +19,8 @@
* parts by Geert Uytterhoeven, May 1997
*
* 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
+ *
+ * 4-8-98 Console locking by Chris Atenasio (chrisa@ultranet.com)
*/

#include <linux/config.h>
@@ -189,6 +192,8 @@
return kbd_getkeycode(scancode);
}

+extern int console_locked;
+
void handle_scancode(unsigned char scancode)
{
unsigned char keycode;
@@ -234,7 +239,17 @@
rep = test_and_set_bit(keycode, key_down);

#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
+
+#ifdef CONFIG_LOCK_CONSOLE
+ if (console_locked) {
+ if (!up_flag) {
+ sysrq_check_password(keycode);
+ }
+ sysrq_pressed = 0;
+ return;
+ }
+#endif
if (keycode == SYSRQ_KEY) {
sysrq_pressed = !up_flag;
return;
} else if (sysrq_pressed) {
diff -ur old/drivers/char/sysrq.c linux/drivers/char/sysrq.c
--- old/drivers/char/sysrq.c Mon Feb 9 19:12:55 1998
+++ linux/drivers/char/sysrq.c Wed Apr 8 20:59:30 1998
@@ -6,6 +6,8 @@
*
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
* based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
+ *
+ * 4-8-98 Console locking by Chris Atenasio (chrisa@ultranet.com)
*/

#include <linux/config.h>
@@ -31,6 +33,13 @@
extern int console_loglevel;
extern struct vfsmount *vfsmntlist;

+#ifdef CONFIG_LOCK_CONSOLE
+int console_locked;
+char console_password[CONFIG_LOCK_CONSOLE_PLEN];
+int console_password_length = 0;
+#endif
+
+
/* Send a signal to all user processes */

static void send_sig_all(int sig, int even_init)
@@ -84,6 +93,16 @@
apm_set_power_state(APM_STATE_OFF);
break;
#endif
+#ifdef CONFIG_LOCK_CONSOLE
+ case 'c': /* C -- lock console */
+ printk("Lock Console\n",console_locked);
+ if (console_password_length == 0) {
+ sysrq_check_password(0);
+ } else {
+ console_locked = 3;
+ }
+ break;
+#endif
case 's': /* S -- emergency sync */
printk("Emergency Sync\n");
emergency_sync_scheduled = EMERG_SYNC;
@@ -135,6 +154,9 @@
#ifdef CONFIG_APM
"Off "
#endif
+#ifdef CONFIG_LOCK_CONSOLE
+ "lockConsole "
+#endif
"Sync Unmount showPc showTasks showMem loglevel0-8 tErm kIll killalL\n");
/* Don't use 'A' as it's handled specially on the Sparc */
}
@@ -241,3 +263,79 @@
unlock_kernel();
printk(KERN_INFO "Done.\n");
}
+
+#ifdef CONFIG_LOCK_CONSOLE
+void sysrq_check_password(unsigned char keycode)
+{
+ static unsigned char buf[CONFIG_LOCK_CONSOLE_PLEN];
+ static int buflen;
+
+ switch(console_locked) {
+ case 0:
+ buflen = 0;
+ printk("Enter password:\n");
+ console_locked = 1;
+ return;
+ case 1:
+ if (keycode == 28) {
+ strncpy(console_password, buf, buflen);
+ console_password_length = buflen;
+ buflen = 0;
+ console_locked = 2;
+ printk("Re-enter password:\n");
+ return;
+ }
+ buflen++;
+ if (buflen > CONFIG_LOCK_CONSOLE_PLEN)
+ {
+ printk("Password too long.\n");
+ console_locked = 0;
+ sysrq_check_password(0);
+ return;
+ }
+ buf[buflen-1] = keycode;
+ return;
+ case 2:
+ if (keycode == 28) {
+ if(strncmp(console_password, buf, buflen)) {
+ printk("Passwords don't match.\n");
+ console_locked = 0;
+ sysrq_check_password(0);
+ return;
+ }
+ console_locked = 3;
+ buflen=0;
+ printk("Console locked.\n");
+ return;
+ }
+ buflen++;
+ if (buflen > CONFIG_LOCK_CONSOLE_PLEN)
+ {
+ printk("Password too long.\n");
+ console_locked = 0;
+ sysrq_check_password(0);
+ return;
+ }
+ buf[buflen-1] = keycode;
+ return;
+ case 3:
+ if (keycode == 28) {
+ if(buflen == console_password_length && !strncmp(console_password, buf, console_password_length)) {
+ printk("Console unlocked.\n");
+ console_locked = 0;
+ }
+ buflen = 0;
+ return;
+ }
+ buflen++;
+ if (buflen > CONFIG_LOCK_CONSOLE_PLEN)
+ {
+ buflen = 0;
+ return;
+ }
+ buf[buflen-1] = keycode;
+ return;
+
+ }
+}
+#endif
diff -ur old/include/linux/sysrq.h linux/include/linux/sysrq.h
--- old/include/linux/sysrq.h Sun Mar 22 20:01:06 1998
+++ linux/include/linux/sysrq.h Wed Apr 8 17:25:18 1998
@@ -20,6 +20,8 @@

void handle_sysrq(int, struct pt_regs *, struct kbd_struct *, struct tty_struct *);

+void sysrq_check_password(unsigned char keycode);
+
/* Deferred actions */

extern int emergency_sync_scheduled;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu