menu: avoid leaving obvious password turds in memory
authorH. Peter Anvin <hpa@zytor.com>
Tue, 26 Aug 2008 21:46:36 +0000 (14:46 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 26 Aug 2008 21:46:36 +0000 (14:46 -0700)
Avoid leaving obvious password turds in memory.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
com32/menu/Makefile
com32/menu/drain.c [new file with mode: 0644]
com32/menu/menu.h
com32/menu/menumain.c
com32/menu/passwd.c

index cfdea06..9b856c2 100644 (file)
@@ -23,7 +23,7 @@ LNXLIBS          = ../libutil/libutil_lnx.a
 MODULES          = menu.c32 vesamenu.c32
 TESTFILES =
 
-COMMONOBJS = menumain.o readconfig.o passwd.o printmsg.o colors.o \
+COMMONOBJS = menumain.o readconfig.o passwd.o drain.o printmsg.o colors.o \
        background.o refstr.o execute.o
 
 all: $(MODULES) $(TESTFILES)
diff --git a/com32/menu/drain.c b/com32/menu/drain.c
new file mode 100644 (file)
index 0000000..83ebbdc
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/cpu.h>
+
+void drain_keyboard(void)
+{
+  /* Prevent "ghost typing" and keyboard buffer snooping */
+  volatile char junk;
+  int rv;
+  
+  do {
+    rv = read(0, &junk, 1);
+  } while (rv > 0);
+
+  junk = 0;
+
+  cli();
+  *(volatile uint8_t *)0x419  = 0;     /* Alt-XXX keyboard area */
+  *(volatile uint16_t *)0x41a = 0x1e;  /* Keyboard buffer empty */
+  *(volatile uint16_t *)0x41c = 0x1e;
+  memset((volatile void *)0x41e, 0, 32); /* Clear the actual keyboard buffer */
+  sti();
+}
+
+  
index 3cb127e..1fa1a24 100644 (file)
@@ -217,4 +217,7 @@ void set_background(const char *new_background);
 /* execute.c */
 void execute(const char *cmdline, enum kernel_type type);
 
+/* drain.c */
+void drain_keyboard(void);
+
 #endif /* MENU_H */
index 01b4fb4..f7af90a 100644 (file)
@@ -215,6 +215,7 @@ ask_passwd(const char *menu_entry)
   int done;
   int key;
   int x;
+  int rv;
 
   printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN+1);
   for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ )
@@ -232,6 +233,8 @@ ask_passwd(const char *menu_entry)
         PASSWD_ROW, (WIDTH-(strlen(cm->messages[MSG_PASSPROMPT])+2))/2,
         cm->messages[MSG_PASSPROMPT], PASSWD_ROW+1, PASSWD_MARGIN+3);
 
+  drain_keyboard();
+
   /* Actually allow user to type a password, then compare to the SHA1 */
   done = 0;
   p = user_passwd;
@@ -282,9 +285,15 @@ ask_passwd(const char *menu_entry)
 
   *p = '\0';
 
-  return (cm->menu_master_passwd &&
-         passwd_compare(cm->menu_master_passwd, user_passwd))
+  rv = (cm->menu_master_passwd &&
+       passwd_compare(cm->menu_master_passwd, user_passwd))
     || (menu_entry && passwd_compare(menu_entry, user_passwd));
+
+  /* Clean up */
+  memset(user_passwd, 0, WIDTH);
+  drain_keyboard();
+
+  return rv;
 }
 
 
index b3bb70a..534fe8b 100644 (file)
 
 static int passwd_compare_sha1(const char *passwd, const char *entry)
 {
+  struct {
+    SHA1_CTX ctx;
+    unsigned char sha1[20], pwdsha1[20];
+  } d;
   const char *p;
-  SHA1_CTX ctx;
-  unsigned char sha1[20], pwdsha1[20];
+  int rv;
 
-  SHA1Init(&ctx);
+  SHA1Init(&d.ctx);
 
   if ( (p = strchr(passwd+3, '$')) ) {
-    SHA1Update(&ctx, (void *)passwd+3, p-(passwd+3));
+    SHA1Update(&d.ctx, (void *)passwd+3, p-(passwd+3));
     p++;
   } else {
     p = passwd+3;              /* Assume no salt */
   }
 
-  SHA1Update(&ctx, (void *)entry, strlen(entry));
-  SHA1Final(sha1, &ctx);
+  SHA1Update(&d.ctx, (void *)entry, strlen(entry));
+  SHA1Final(d.sha1, &d.ctx);
 
-  memset(pwdsha1, 0, 20);
-  unbase64(pwdsha1, 20, p);
+  memset(d.pwdsha1, 0, 20);
+  unbase64(d.pwdsha1, 20, p);
 
-  return !memcmp(sha1, pwdsha1, 20);
+  rv = !memcmp(d.sha1, d.pwdsha1, 20);
+
+  memset(&d, 0, sizeof d);
+  return rv;
 }
 
 static int passwd_compare_md5(const char *passwd, const char *entry)