Avoid leaving obvious password turds in memory.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
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)
--- /dev/null
+#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();
+}
+
+
/* execute.c */
void execute(const char *cmdline, enum kernel_type type);
+/* drain.c */
+void drain_keyboard(void);
+
#endif /* MENU_H */
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++ )
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;
*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;
}
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)