Re: PATCH 2/2: external hashing program use in losetup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Duh...
--- lomount.c-no-reader-prog	2003-08-02 19:25:01.000000000 -0400
+++ lomount.c	2003-08-05 21:31:18.000000000 -0400
@@ -32,7 +32,9 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/sysmacros.h>
+#include <sys/wait.h>
 #include <regex.h>
+#include <signal.h>
 
 #include "loop.h"
 #include "lomount.h"
@@ -42,6 +44,67 @@
 extern int verbose;
 extern char *xstrdup (const char *s);	/* not: #include "sundries.h" */
 extern void error (const char *fmt, ...);	/* idem */
+#define EX_USAGE	1			/* idem */
+#define EX_SYSERR	2			/* idem */
+
+static volatile pid_t reader_pid = -1;
+
+static void
+child_handler (int i) {
+	int status;
+	if (reader_pid != -1 && wait(&status) == reader_pid) {
+		reader_pid = -1;
+		if (WEXITSTATUS(status) != 0)
+			exit(WEXITSTATUS(status));
+	}
+}
+
+static void
+child_cleanup (void) {
+	/* we are too lazy to clean up; child_handler will do it for us	*
+	 * if we wait							*/
+	while (reader_pid != -1)
+		wait(NULL);
+}
+
+int
+use_reader_prog (const char *s) {
+	int fd[2]; 
+	struct sigaction sa = {
+		.sa_handler = child_handler,
+		.sa_flags = SA_NOCLDSTOP
+	};
+
+	if (pipe(fd) == -1) {
+		perror("pipe");
+		exit(EX_SYSERR);
+	}
+	if (sigaction(SIGCHLD, &sa, NULL) == -1) {
+		perror("sigaction");
+		exit(EX_SYSERR);
+	}
+	if ((reader_pid = fork()) == -1) {
+		perror("fork");
+		exit(EX_SYSERR);
+	} else if (reader_pid) {	/* parent */
+		atexit(child_cleanup);
+		close(fd[1]);
+		return fd[0];
+	} else {		/* child */
+		close(fd[0]);
+		if (dup2(fd[1], STDOUT_FILENO) == -1) {
+			perror("dup2");
+			exit(EX_SYSERR);
+		}
+		setuid(getuid());	/* set euid to ruid */
+		if (execlp(s, s, NULL) == -1) {
+			perror(s);
+			exit(EX_USAGE);
+		}
+	}
+
+	return 0; /* so gcc will shut up */
+}
 
 #ifdef LOOP_SET_FD
 
@@ -347,8 +410,25 @@
 			return -1;
 		}
 		/* FIXME we should be checking keysize against the min/max in /proc/crypto */
-		pass = xgetpass(pfd, _("Password: "));
-		xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
+
+		if (reader_pid == -1) {
+			pass = xgetpass(pfd, _("Password: "));
+			xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
+		} else {
+			/* Odds are good that a SIGCHLD will interrupt	*
+			 * this read(), and ruin our whole day. So we	*
+			 * must block it.				*/
+			sigset_t ss, oss;
+			sigemptyset(&ss);
+			sigaddset(&ss, SIGCHLD);
+			sigprocmask(SIG_BLOCK, &ss, &oss);
+			if (read(pfd, loopinfo64.lo_encrypt_key,
+				 LO_KEY_SIZE) == -1) {
+				perror("read");
+				fprintf(stderr, _("Error reading encryption key, exiting\n"));
+			}
+			sigprocmask(SIG_SETMASK, &oss, NULL);
+		}
 		loopinfo64.lo_encrypt_key_size = keysize;
 	}
 
@@ -485,20 +565,21 @@
 
 int
 main(int argc, char **argv) {
-	char *offset, *encryption, *passfd;
+	char *offset, *encryption, *passfd, *passreader;
 	int delete, off, c;
 	int res = 0;
 	int ro = 0;
 	int pfd = -1;
+	int opt_p = 0, opt_P = 0;
 
 	setlocale(LC_ALL, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 
 	delete = off = 0;
-	offset = encryption = passfd = NULL;
+	offset = encryption = passfd = passreader = NULL;
 	progname = argv[0];
-	while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
+	while ((c = getopt(argc,argv,"de:E:o:p:P:v")) != -1) {
 		switch (c) {
 		case 'd':
 			delete = 1;
@@ -511,8 +592,21 @@
 			offset = optarg;
 			break;
 		case 'p':
+			if (opt_p || opt_P) {
+				fprintf(stderr, _("mount: only one -p or -P allowed"));
+				exit(1);
+			}
+			opt_p = 1;
 			passfd = optarg;
 			break;
+		case 'P':
+			if (opt_p || opt_P) {
+				fprintf(stderr, _("mount: only one -p or -P allowed"));
+				exit(1);
+			}
+			opt_P = 1;
+			passreader = optarg;
+			break;
 		case 'v':
 			verbose = 1;
 			break;
@@ -534,6 +628,8 @@
 			usage();
 		if (passfd && sscanf(passfd,"%d",&pfd) != 1)
 			usage();
+		if (passreader) 
+			pfd = use_reader_prog(passreader);
 		res = set_loop(argv[optind], argv[optind+1], off,
 			       encryption, pfd, &ro);
 	}
--- losetup.8-no-reader-prog	2003-07-15 19:06:37.000000000 -0400
+++ losetup.8	2003-08-04 19:32:27.000000000 -0400
@@ -13,6 +13,9 @@
 ] [
 .B \-p
 .I pfd
+] [
+.B \-P
+.I reader
 ]
 .I loop_device file
 .br
@@ -63,6 +66,12 @@
 Read the passphrase from file descriptor with number
 .I num
 instead of from the terminal.
+.IP "\fB\-P \fIprog\fP"
+Use the external program
+.I prog
+to read and process the passphrase. This is useful if you want to
+hash the passphrase for use as the encryption key (highly recommended).
+NOTE that the options -p and -P cannot be used together.
 .SH RETURN VALUE
 .B losetup
 returns 0 on success, nonzero on failure. When
--- mount.8-no-reader-prog	2003-08-04 00:26:04.000000000 -0400
+++ mount.8	2003-08-04 19:32:37.000000000 -0400
@@ -321,6 +321,13 @@
 .I num
 instead of from the terminal.
 .TP
+.BI \-P " prog"
+In case of a loop mount with encryption, use the external program
+.I prog
+to read and process the passphrase. This is useful if you want to
+hash the passphrase for use as the encryption key (highly recommended).
+NOTE that the options -p and -P cannot be used together.
+.TP
 .B \-s
 Tolerate sloppy mount options rather than failing. This will ignore
 mount options not supported by a filesystem type. Not all filesystems
--- mount.c-no-reader-prog	2003-07-15 17:38:48.000000000 -0400
+++ mount.c	2003-08-04 19:23:11.000000000 -0400
@@ -1371,6 +1371,7 @@
 	{ "options", 1, 0, 'o' },
 	{ "test-opts", 1, 0, 'O' },
 	{ "pass-fd", 1, 0, 'p' },
+	{ "pass-reader", 1, 0, 'P' },
 	{ "types", 1, 0, 't' },
 	{ "bind", 0, 0, 128 },
 	{ "replace", 0, 0, 129 },
@@ -1421,7 +1422,7 @@
 
 int
 main (int argc, char *argv[]) {
-	int c, result = 0, specseen;
+	int c, result = 0, specseen, opt_p = 0, opt_P = 0;
 	char *options = NULL, *test_opts = NULL, *spec, *node;
 	char *volumelabel = NULL;
 	char *uuid = NULL;
@@ -1447,7 +1448,7 @@
 	initproctitle(argc, argv);
 #endif
 
-	while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:rsU:vVwt:",
+	while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:P:rsU:vVwt:",
 				 longopts, NULL)) != -1) {
 		switch (c) {
 		case 'a':	       /* mount everything in fstab */
@@ -1487,8 +1488,17 @@
 				test_opts = xstrdup(optarg);
 			break;
 		case 'p':		/* fd on which to read passwd */
+			if (opt_p || opt_P)
+				die (EX_USAGE, _("mount: only one -p or -P allowed"));
+			opt_p = 1;
 			set_pfd(optarg);
 			break;
+		case 'P':		/* program to read the passwd */
+			if (opt_p || opt_P)
+				die (EX_USAGE, _("mount: only one -p or -P allowed"));
+			opt_P = 1;
+			pfd = use_reader_prog(optarg);
+			break;
 		case 'r':		/* mount readonly */
 			readonly = 1;
 			readwrite = 0;

[Index of Archives]     [Kernel]     [Linux Crypto]     [Gnu Crypto]     [Gnu Classpath]     [Netfilter]     [Bugtraq]
  Powered by Linux