Subject: port-i386/24897: installboot requires passing boot password on the command-line
To: None <gnats-bugs@gnats.netbsd.org>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 03/24/2004 01:16:11
>Number:         24897
>Category:       port-i386
>Synopsis:       installboot requires passing boot password on the command-line
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-i386-maintainer
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Mar 24 01:17:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Christian Biere
>Release:        NetBSD 1.6ZJ
>Organization:
>Environment:
System: NetBSD cyclonus 1.6ZJ NetBSD 1.6ZJ (STARSCREAM) #0: Sat Feb 14 09:52:52 CET 2004 root@Cyclonus:/sys/arch/i386/compile/STARSCREAM i386
>Description:

Installboot supports setting a boot password on i386. Unfortunately, the
password can only be passed on the command-line which means anyone e.g.,
running ps in a loop could possibly read the password while installboot
is executed. IMHO, no program should ever read a password from the
command-line.

>How-To-Repeat:

# installboot -nv -o password=blah /dev/wd0d /usr/mdec/bootxx_ffsv1

>Fix:

I'd prefer if installboot doesn't support passing the password on the
command-line at all but in many environments this might not be an issue,
so I've left the option in it which means it's also almost completely
backwards compatible. If the password is set to "-" (underscore) the
password will be read using getpass(3). 

Index: installboot.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/installboot/installboot.8,v
retrieving revision 1.41
diff -u -r1.41 installboot.8
--- installboot.8	13 Mar 2004 23:43:45 -0000	1.41
+++ installboot.8	24 Mar 2004 01:03:00 -0000
@@ -264,6 +264,13 @@
 .It Sy password=\*[Lt]password\*[Gt]
 .Sy [ i386 ]
 Set the password which must be entered before the boot menu can be accessed.
+If the password is
+.Dq -
+the actual password is read from
+.Dq /dev/tty
+or
+.Dq stdin
+if the former cannot be read.
 .
 .It Sy resetvideo
 .Sy [ i386 ]
Index: arch/i386.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/installboot/arch/i386.c,v
retrieving revision 1.15
diff -u -r1.15 i386.c
--- arch/i386.c	14 Mar 2004 23:05:47 -0000	1.15
+++ arch/i386.c	24 Mar 2004 01:03:00 -0000
@@ -218,8 +218,44 @@
 	}
 	if (params->flags & IB_PASSWORD) {
 		MD5_CTX md5ctx;
+
 		MD5Init(&md5ctx);
-		MD5Update(&md5ctx, params->password, strlen(params->password));
+		if (!strcmp("-", params->password)) {
+			char *p, *q;
+
+			q = getpass("Enter boot password: ");
+			if (!q) {
+				warn("Reading password failed");
+				goto done;
+			}
+			p = strdup(q);
+			memset(q, 0, strlen(q));
+			if (!p) {
+				warn("strdup() failed");
+				goto done;
+			}
+			q = getpass("Repeat boot password: ");
+			if (!q) {
+				memset(p, 0, strlen(p));
+				warn("Reading password failed");
+				free(p);
+				goto done;
+			}
+			if (strcmp(p, q)) {
+				memset(q, 0, strlen(q));
+				memset(p, 0, strlen(p));
+				warnx("Passwords don't match");
+				free(p);
+				goto done;
+			}
+			memset(p, 0, strlen(p));
+			free(p);
+			MD5Update(&md5ctx, q, strlen(q));
+			memset(q, 0, strlen(q));
+		} else {
+			MD5Update(&md5ctx, params->password,
+				strlen(params->password));
+		}
 		MD5Final(bp->bp_password, &md5ctx);
 		bp->bp_flags |= htole32(X86_BP_FLAGS_PASSWORD);
 	}
>Release-Note:
>Audit-Trail:
>Unformatted: