[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: PATCH 2/2: external hashing program use in losetup
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;