[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-crypto
Subject:    [RESENT][PATCH] A better util-linux.getpass.patch
From:       Marc Mutz <Marc () Mutz ! com>
Date:       2000-11-13 23:29:07
[Download RAW message or body]

Hi Alex!

I've implemented the
Q> --pass-fd <num>
alias
Q> -p <num>
option for both mount(8) and losetup(8). It expects a number (<num>) as
argument and instructs mount/losetup to read the passphrase from file
descriptor <num> instead of from the terminal. man pages have been
updated, too. I have tested the xgetpass() routine both with a
passphrase below 128 bytes and with the to-do-list I sent you some days
ago with every newline removed, like
Q> cat my-ikp-todo.txt | tr -d $'\n' | \
Q> losetup -e blowfish -p 0 /dev/loop0 crypto-file
It works!

Also, it teaches losetup long options, see losetup.8 for more.

The patch applies to util-linux-2.10o, patched with the patch from
2.2.17.3. It will conflict with Gisle's and my previous stuff, no doubt.
but AFAICS, only in the switch statement, where my patch is trivial:
Just
Q> getpass("...")->xgetpass(pfd,"...")
everywhere. Please consider applying. if it makes too much noise when
patching, I'll rediff against 17.4 when that is out.


Marc

PS: I have also fixed the loop vs. remount bug described in my todo
list. A patch to Andries has been sent and he applied it. It is a
two-liner in mount.c:try_mount_one() and thus will not collide with the
kerneli-util-linux patches. But the difference in remount loop semantics
is _great_.

-- 
Marc Mutz <Marc@Mutz.com>        http://marc.mutz.com/Encryption-HOWTO/
University of Bielefeld, Dep. of Mathematics / Dep. of Physics

PGP-keyID's:   0xd46ce9ab (RSA), 0x7ae55b9e (DSS/DH)

["util-linux-2.10o-passfd.patch;" (text/plain)]

diff -urN util-linux-2.10o.i3/mount/lomount.c util-linux-2.10o.i3-getpass/mount/lomount.c
--- util-linux-2.10o.i3/mount/lomount.c	Sun Sep 24 16:46:02 2000
+++ util-linux-2.10o.i3-getpass/mount/lomount.c	Sun Sep 24 23:26:00 2000
@@ -6,6 +6,11 @@
  * - added Native Language Support
  * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  * - fixed strerr(errno) in gettext calls
+ * 2000-09-24 Marc Mutz <Marc@Mutz.com>
+ * - added long option names and the --pass-fd option to pass
+ *   passphrases via fd's to losetup/mount. Used for encryption in
+ *   non-interactive environments. The idea behind xgetpass() is stolen
+ *   from GnuPG, v.1.0.3 (http://www.gnupg.org/).
  */
 
 #define PROC_DEVICES	"/proc/devices"
@@ -176,9 +181,47 @@
 	return 0;
 }
 
+/* A function to read the passphrase either from the terminal or from
+ * an open file descriptor */
+static char *
+xgetpass (int pfd, const char *prompt)
+{
+        if (pfd < 0) /* terminal */
+	        return (getpass(prompt));
+	else {       /* file descriptor */
+	        char *pass = NULL;
+		int buflen, i;
+
+		buflen=0;
+		for (i=0; ; i++) {
+		        if (i >= buflen-1) {
+		                /* we're running out of space in the buffer. 
+				 * Make it bigger: */
+		                char *tmppass = pass;
+				buflen += 128;
+				pass = realloc(tmppass,buflen);
+				if (pass == NULL) {
+					/* realloc failed. Stop reading _now_. */
+			                error("not enough memory while reading passphrase");
+					pass = tmppass; /* the old buffer hasn't changed */
+					break;
+				}
+			};
+			if ( read(pfd,pass+i, 1) != 1 || pass[i] == '\n' )
+			        break;
+		}
+		if (pass == NULL)
+		        return "";
+		else {
+		        pass[i] = 0;
+		        return pass;
+		}
+	}
+}
+
 int
 set_loop (const char *device, const char *file, int offset,
-	  const char *encryption, int *loopro) {
+	  const char *encryption, int pfd, int *loopro) {
 	struct loop_info loopinfo;
 	int fd, ffd, mode, i;
 	char *pass;
@@ -227,14 +270,16 @@
 		loopinfo.lo_encrypt_key_size = 0;
 		break;
 	case LO_CRYPT_XOR:
-		pass = getpass (_("Password: "));
+          /* WARNING: xgetpass() can return massive amounts of data,
+           * not only 128 bytes like the original getpass(3) */
+		pass = xgetpass (pfd,_("Password: "));
 		strncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
 		loopinfo.lo_encrypt_key[LO_KEY_SIZE - 1] = 0;
 		loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
 		break;
 	case LO_CRYPT_DES:
 		printf(_("WARNING: Use of DES is depreciated.\n"));
-		pass = getpass (_("Password: "));
+		pass = xgetpass (pfd,_("Password: "));
 		strncpy (loopinfo.lo_encrypt_key, pass, 8);
 		loopinfo.lo_encrypt_key[8] = 0;
 		loopinfo.lo_encrypt_key_size = 8;
@@ -252,7 +297,7 @@
 		break;
 	case LO_CRYPT_FISH2:
 	case LO_CRYPT_BLOW:
-		pass = getpass("Password :");
+		pass = xgetpass(pfd,_("Password :"));
 		MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass));
 		loopinfo.lo_encrypt_key_size=20; /* 160 Bit key */
 		break;
@@ -262,7 +307,7 @@
 	case LO_CRYPT_MARS:
 	case LO_CRYPT_RC6:
 	case LO_CRYPT_DFC:
-		pass = getpass("Password :");
+		pass = xgetpass(pfd,_("Password :"));
 		MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass));
 		loopinfo.lo_encrypt_key_size=16; /* 128 Bit key */
 		break;
@@ -319,7 +364,7 @@
 
 int
 set_loop (const char *device, const char *file, int offset,
-	  const char *encryption, int *loopro) {
+	  const char *encryption, int pfd, int *loopro) {
 	mutter();
 	return 1;
 }
@@ -348,20 +393,34 @@
 int verbose = 0;
 static char *progname;
 
+static struct option longopts[] = {
+	{ "delete", 0, 0, 'd' },
+	{ "detach", 0, 0, 'd' },
+	{ "encryption", 1, 0, 'e' },
+	{ "help", 0, 0, 'h' },
+	{ "offset", 1, 0, 'o' },
+	{ "pass-fd", 1, 0, 'p' },
+	{ "verbose", 0, 0, 'v' },
+	{ NULL, 0, 0, 0 }
+};
+
+
 static void
 usage(void) {
-	struct crypt_type_struct *c;
 	fprintf(stderr, _("usage:\n\
   %s loop_device                                      # give info\n\
   %s -d loop_device                                   # delete\n\
-  %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
+  %s [ options ] loop_device file                     # setup\n\
+    where options include\n\
+    --offset <num>, -o <num>\n\
+        start at offset <num> into file.\n\
+    --pass-fd <num>, -p <num>\n\
+        read passphrase from file descriptor <num>\n\
+        instead of the terminal.\n\
+    --encryption <cipher>, -e <cipher>\n\
+        encrypt with <cipher>.\n\
+        Check /proc/cipher for available ciphers."),
 		progname, progname, progname);
-	fprintf(stderr, "    where encryption is one of:\n");
-	c = &crypt_type_tbl[0];
-	while(c->name) {
-		fprintf(stderr, "       %s\n", c->name);
-		c++;
-	}
 	exit(1);
 }
 
@@ -394,8 +453,9 @@
 
 int
 main(int argc, char **argv) {
-	char *offset, *encryption;
+	char *offset, *encryption, *passfd;
 	int delete,off,c;
+	int pfd = -1; 
 	int res = 0;
 	int ro = 0;
 
@@ -404,9 +464,10 @@
 	textdomain(PACKAGE);
 
 	delete = off = 0;
-	offset = encryption = NULL;
+	offset = encryption = passfd = NULL;
 	progname = argv[0];
-	while ((c = getopt(argc,argv,"de:o:v")) != EOF) {
+	while ((c = getopt_long(argc,argv,"de:ho:p:v",
+				longopts, NULL)) != EOF) {
 		switch (c) {
 		case 'd':
 			delete = 1;
@@ -417,6 +478,9 @@
 		case 'o':
 			offset = optarg;
 			break;
+		case 'p':
+		        passfd = optarg;
+			break;
 		case 'v':
 			verbose = 1;
 			break;
@@ -425,7 +489,7 @@
 		}
 	}
 	if (argc == 1) usage();
-	if ((delete && (argc != optind+1 || encryption || offset)) ||
+	if ((delete && (argc != optind+1 || encryption || offset || passfd)) ||
 	    (!delete && (argc < optind+1 || argc > optind+2)))
 		usage();
 	if (argc == optind+1) {
@@ -436,7 +500,9 @@
 	} else {
 		if (offset && sscanf(offset,"%d",&off) != 1)
 			usage();
-		res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
+		if (passfd && sscanf(passfd,"%d",&pfd) != 1)
+		        usage();
+		res = set_loop(argv[optind],argv[optind+1],off,encryption,pfd,&ro);
 	}
 	return res;
 }
diff -urN util-linux-2.10o.i3/mount/lomount.h util-linux-2.10o.i3-getpass/mount/lomount.h
--- util-linux-2.10o.i3/mount/lomount.h	Fri Jul  9 04:56:39 1999
+++ util-linux-2.10o.i3-getpass/mount/lomount.h	Sun Sep 24 17:20:01 2000
@@ -1,4 +1,4 @@
 extern int verbose;
-extern int set_loop (const char *, const char *, int, const char *, int *);
+extern int set_loop (const char *, const char *, int, const char *, int, int *);
 extern int del_loop (const char *);
 extern char * find_unused_loop_device (void);
diff -urN util-linux-2.10o.i3/mount/losetup.8 util-linux-2.10o.i3-getpass/mount/losetup.8
--- util-linux-2.10o.i3/mount/losetup.8	Sun Sep 24 16:46:02 2000
+++ util-linux-2.10o.i3-getpass/mount/losetup.8	Sun Sep 24 23:01:14 2000
@@ -10,6 +10,9 @@
 ] [
 .B \-o
 .I offset
+] [
+.B \-p
+.I num
 ]
 .I loop_device file
 .br
@@ -26,9 +29,9 @@
 \fIloop_device\fP argument is given, the status of the corresponding loop
 device is shown.
 .SH OPTIONS
-.IP \fB\-d\fP
+.IP "\fB\-\-delete, \-\-detach, \-d\fP"
 detach the file or device associated with the specified loop device.
-.IP "\fB\-e \fIencryption\fP"
+.IP "\fB\-\-encryption, \-e \fIencryption\fP"
 .RS
 enable data encryption. The following keywords are recognized:
 .IP \fBNONE\fP
@@ -79,9 +82,12 @@
 enabled in the Crypto API.
 .PD
 .RE
-.IP "\fB\-o \fIoffset\fP"
+.IP "\fB\-\-offset, \-o \fIoffset\fP"
 the data start is moved \fIoffset\fP bytes into the specified file or
 device.
+.IP "\fB\-\-pass-fd, \-p \fInum\fP"
+read the passphrase from file descriptor \fInum\fP instead of the
+terminal.
 .SH RETURN VALUE
 .B losetup
 returns 0 on success, nonzero on failure. When
diff -urN util-linux-2.10o.i3/mount/mount.8 util-linux-2.10o.i3-getpass/mount/mount.8
--- util-linux-2.10o.i3/mount/mount.8	Sun Jul 30 22:26:41 2000
+++ util-linux-2.10o.i3-getpass/mount/mount.8	Sun Sep 24 23:19:47 2000
@@ -252,6 +252,12 @@
 .B \-v
 Verbose mode.
 .TP
+.B \-p "\fInum\fP"
+If the mount requires a passphrase to be entered, read it from file
+descriptor
+.IR num\fP
+instead of from the terminal.
+.TP
 .B \-a
 Mount all filesystems (of the given types) mentioned in
 .IR fstab .
@@ -1240,7 +1246,10 @@
 .BR loop ", " offset " and " encryption ,
 that are really options to
 .BR losetup (8).
-If no explicit loop device is mentioned
+If the mount requires a passphrase, you will be prompted for one unless
+you specify a file descriptor to read from instead with the 
+.BR \-\-pass-fd
+option. If no explicit loop device is mentioned
 (but just an option `\fB\-o loop\fP' is given), then
 .B mount
 will try to find some unused loop device and use that.
diff -urN util-linux-2.10o.i3/mount/mount.c util-linux-2.10o.i3-getpass/mount/mount.c
--- util-linux-2.10o.i3/mount/mount.c	Fri Aug 11 14:50:10 2000
+++ util-linux-2.10o.i3-getpass/mount/mount.c	Sun Sep 24 23:24:09 2000
@@ -105,6 +105,9 @@
 /* True if ruid != euid.  */
 static int suid = 0;
 
+/* Contains the fd no. to read the passphrase from, if any */
+static int pfd = -1;
+
 /* Map from -o and fstab option strings to the flag argument to mount(2).  */
 struct opt_map {
   const char *opt;		/* option name */
@@ -536,7 +539,7 @@
       if (verbose)
 	printf(_("mount: going to use the loop device %s\n"), *loopdev);
       offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
-      if (set_loop (*loopdev, *loopfile, offset, opt_encryption, &loopro)) {
+      if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd, &loopro)) {
 	if (verbose)
 	  printf(_("mount: failed setting up loop device\n"));
 	return EX_FAIL;
@@ -1226,6 +1229,7 @@
 	{ "read-write", 0, 0, 'w' },
 	{ "rw", 0, 0, 'w' },
 	{ "options", 1, 0, 'o' },
+	{ "pass-fd", 1, 0, 'p' },
 	{ "types", 1, 0, 't' },
 	{ "bind", 0, 0, 128 },
 	{ "replace", 0, 0, 129 },
@@ -1259,7 +1263,7 @@
 	  "or by label, using  -L label  or by uuid, using  -U uuid .\n"
 	  "Union or stack mounts are specified using one of\n"
 	  "       --replace, --after, --before, --over\n"
-	  "Other options: [-nfFrsvw] [-o options].\n"
+	  "Other options: [-nfFrsvw] [-o options] [-p num].\n"
 	  "For many more details, say  man 8 mount .\n"
 	));
 	unlock_mtab();
@@ -1271,6 +1275,7 @@
 	int c, result = 0, specseen;
 	char *options = NULL, *spec, *node;
 	char *volumelabel = NULL;
+	char *passfd = NULL;
 	char *uuid = NULL;
 	string_list types = NULL;
 	struct mntentchn *mc;
@@ -1291,7 +1296,7 @@
 	initproctitle(argc, argv);
 #endif
 
-	while ((c = getopt_long (argc, argv, "afFhlL:no:rsU:vVwt:",
+	while ((c = getopt_long (argc, argv, "afFhlL:no:p:rsU:vVwt:",
 				 longopts, NULL)) != EOF) {
 		switch (c) {
 		case 'a':		/* mount everything in fstab */
@@ -1321,6 +1326,9 @@
 			else
 				options = xstrdup(optarg);
 			break;
+		case 'p':               /* read passphrase from given fd */
+		        passfd = optarg;
+			break;
 		case 'r':		/* mount readonly */
 			readonly = 1;
 			readwrite = 0;
@@ -1405,6 +1413,9 @@
 			printf(_("mount: mounting %s\n"), spec);
 	} else
 		spec = NULL;		/* just for gcc */
+
+	if (passfd && sscanf(passfd,"%d",&pfd) != 1)
+	        die (EX_USAGE, _("mount: argument to --pass-fd or -p must be a number"));
 
 	switch (argc+specseen) {
 	case 0:


Linux-crypto:  cryptography in and on the Linux system
Archive:       http://mail.nl.linux.org/linux-crypto/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic