diff -Naur util-linux-2.12p/mount/keygen.c util-linux-2.12p.new/mount/keygen.c --- util-linux-2.12p/mount/keygen.c 1970-01-01 03:00:00 +0300 +++ util-linux-2.12p.new/mount/keygen.c 2005-02-10 14:17:46 +0300 @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include + + +/* Split a string into pieces, using delim as the delimiter. * + * Returns the number of pieces. */ +static int +split_args (char *args[], const char *str, const char *delim, int nargs) { + int i=0; + char *s = xstrdup(str); + args[0] = strtok(s, delim); + if (args[0] == NULL) + return 0; + + while (++i < nargs) { + if ((args[i] = strtok(NULL, delim)) == NULL) + break; + } + + return i; +} + +#define KEYGEN_MAX_ARGS 64 /* more than anyone will need, right? */ + +/* Call an external program to give us the encryption key for an * + * encrypted device. We split the string s into a command and args on * + * semicolons ('cuz you can't put spaces in the fs_mntopts field), then * + * add some specific args (eg. the looped file or device, the * + * encryption method used; check the caller to see the actual list). * + * Returns a file descriptor from which we read the key. */ +int +use_keygen_prog (const char *s, const char *addl_args[], int naddl_args) { + int fd[2]; + pid_t keygen_pid; + + if (pipe(fd) == -1) { + perror("pipe"); + exit(EXIT_FAILURE); + } + if ((keygen_pid = fork()) == -1) { + perror("fork"); + exit(EXIT_FAILURE); + } else if (keygen_pid) { /* parent */ + close(fd[1]); + return fd[0]; + } else { /* child */ + char *args[KEYGEN_MAX_ARGS+1]; + int i, n = split_args(args, s, ";", KEYGEN_MAX_ARGS - naddl_args); + if (!n) { + fprintf(stderr, "Invalid keygen program, exiting\n"); + exit(EXIT_FAILURE); + } + for(i=0; i < naddl_args && n+i < KEYGEN_MAX_ARGS; i++) + args[n+i] = (char *) addl_args[i]; + args[n+i] = NULL; + + close(fd[0]); + if (dup2(fd[1], STDOUT_FILENO) == -1) { + perror("dup2"); + exit(EXIT_FAILURE); + } + setuid(getuid()); /* set euid to ruid */ + if (execvp(args[0], args) == -1) { + perror(args[0]); + exit(EXIT_FAILURE); + } + } + + return 0; /* so gcc will shut up */ +} + diff -Naur util-linux-2.12p/mount/keygen.h util-linux-2.12p.new/mount/keygen.h --- util-linux-2.12p/mount/keygen.h 1970-01-01 03:00:00 +0300 +++ util-linux-2.12p.new/mount/keygen.h 2005-02-10 14:17:46 +0300 @@ -0,0 +1 @@ +int use_keygen_prog (const char *s, const char *addl_args[], int naddl_args); diff -Naur util-linux-2.12p/mount/lomount.c util-linux-2.12p.new/mount/lomount.c --- util-linux-2.12p/mount/lomount.c 2005-02-10 14:31:18 +0300 +++ util-linux-2.12p.new/mount/lomount.c 2005-02-10 14:30:39 +0300 @@ -411,12 +411,14 @@ * must block it. */ sigset_t ss, oss; sigemptyset(&ss); + int rc; 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")); + if ((rc = read(pfd, loopinfo64.lo_encrypt_key, + LO_KEY_SIZE)) <= 0) { + fprintf(stderr, _("Error reading encryption key: %s\n"), + (rc < 0) ? strerror(errno) : "unexpected end of file"); + return -1; } sigprocmask(SIG_SETMASK, &oss, NULL); } @@ -546,8 +548,9 @@ %s loop_device # give info\n\ %s -d loop_device # delete\n\ %s -f # find unused\n\ + %s -k # use keygen program \n\ %s [-e encryption] [-o offset] {-f|loop_device} file # setup\n"), - progname, progname, progname, progname); + progname, progname, progname, progname, progname); exit(1); } @@ -616,7 +619,7 @@ if ((p = strrchr(progname, '/')) != NULL) progname = p+1; - while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) { + while ((c = getopt(argc, argv, "de:E:fo:p:vk:")) != -1) { switch (c) { case 'd': delete = 1; @@ -637,6 +640,9 @@ case 'v': verbose = 1; break; + case 'k': + pfd = use_keygen_prog(optarg, NULL,0); + break; default: usage(); } diff -Naur util-linux-2.12p/mount/losetup.8 util-linux-2.12p.new/mount/losetup.8 --- util-linux-2.12p/mount/losetup.8 2004-12-05 04:35:54 +0300 +++ util-linux-2.12p.new/mount/losetup.8 2005-02-10 14:17:46 +0300 @@ -70,7 +70,7 @@ Detach the file or device associated with the specified loop device. .IP "\fB\-E \fIencryption_type\fP" Enable data encryption with specified number. -.IP "\fB\-e \fIencryption_name\fP" +.IP "\fB\-e \fIencryption_name-mode-keysize\fP" Enable data encryption with specified name. .IP "\fB\-f\fP" Find the first unused loop device. If a @@ -95,6 +95,7 @@ .SH FILES .nf /dev/loop0, /dev/loop1, ... loop devices (major=7) +/lib/modules//kernel/net/cryptoapi/ciphers/* available ciphers .fi .SH EXAMPLE If you are using the loadable module you must have the module loaded @@ -110,8 +111,9 @@ The following commands can be used as an example of using the loop device. .nf .IP +# modprobe cryptoloop # dd if=/dev/zero of=/file bs=1k count=100 -# losetup -e des /dev/loop0 /file +# losetup -e aes-cbc-128 /dev/loop0 /file Password: Init (up to 16 hex digits): # mkfs -t ext2 /dev/loop0 100 diff -Naur util-linux-2.12p/mount/Makefile util-linux-2.12p.new/mount/Makefile --- util-linux-2.12p/mount/Makefile 2004-12-22 12:32:08 +0300 +++ util-linux-2.12p.new/mount/Makefile 2005-02-10 14:18:26 +0300 @@ -47,7 +47,7 @@ %.o: %.c $(COMPILE) $< -mount: mount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o version.o \ +mount: keygen.o mount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o version.o \ get_label_uuid.o mount_by_label.o mount_blkid.o mount_guess_fstype.o \ getusername.o $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) $(LINK) $^ -o $@ $(BLKID_LIB) @@ -64,7 +64,7 @@ main_losetup.o: lomount.c $(COMPILE) -DMAIN lomount.c -o $@ -losetup: main_losetup.o $(LIB)/xstrncpy.o +losetup: keygen.o main_losetup.o $(LIB)/xstrncpy.o $(LINK) $^ -o $@ mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h diff -Naur util-linux-2.12p/mount/mount.c util-linux-2.12p.new/mount/mount.c --- util-linux-2.12p/mount/mount.c 2005-02-10 14:31:18 +0300 +++ util-linux-2.12p.new/mount/mount.c 2005-02-10 14:17:46 +0300 @@ -37,6 +37,7 @@ #include "paths.h" #include "env.h" #include "nls.h" +#include "keygen.h" #define DO_PS_FIDDLING diff -Naur util-linux-2.12p/mount/sundries.c util-linux-2.12p.new/mount/sundries.c --- util-linux-2.12p/mount/sundries.c 2005-02-10 14:31:18 +0300 +++ util-linux-2.12p.new/mount/sundries.c 2005-02-10 14:17:46 +0300 @@ -12,8 +12,6 @@ #include #include #include /* for MNTTYPE_SWAP */ -#include -#include #include "fstab.h" #include "sundries.h" #include "realpath.h" @@ -249,99 +247,3 @@ return xstrdup(path); } -static volatile int keygen_wait = 1; - -/* Handle a SIGCHLD -- wait for the child process */ -static void -child_handler (int i) { - int status; - if (keygen_wait && wait(&status) != -1) { - keygen_wait = 0; - if (WEXITSTATUS(status) != 0) - exit(WEXITSTATUS(status)); - } -} - -/* Make sure we clean up after the child */ -static void -child_cleanup (void) { - /* "Clean up" means wait. So we let child_handler do all the work */ - while (keygen_wait) - sleep(1); -} - -/* Split a string into pieces, using delim as the delimiter. * - * Returns the number of pieces. */ -static int -split_args (char *args[], const char *str, const char *delim, int nargs) { - int i=0; - char *s = xstrdup(str); - args[0] = strtok(s, delim); - if (args[0] == NULL) - return 0; - - while (++i < nargs) { - if ((args[i] = strtok(NULL, delim)) == NULL) - break; - } - - return i; -} - -#define KEYGEN_MAX_ARGS 64 /* more than anyone will need, right? */ - -/* Call an external program to give us the encryption key for an * - * encrypted device. We split the string s into a command and args on * - * semicolons ('cuz you can't put spaces in the fs_mntopts field), then * - * add some specific args (eg. the looped file or device, the * - * encryption method used; check the caller to see the actual list). * - * Returns a file descriptor from which we read the key. */ -int -use_keygen_prog (const char *s, const char *addl_args[], int naddl_args) { - int fd[2]; - pid_t keygen_pid; - struct sigaction sa; - sa.sa_handler = child_handler; - sa.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 ((keygen_pid = fork()) == -1) { - perror("fork"); - exit(EX_SYSERR); - } else if (keygen_pid) { /* parent */ - atexit(child_cleanup); - close(fd[1]); - return fd[0]; - } else { /* child */ - char *args[KEYGEN_MAX_ARGS+1]; - int i, n = split_args(args, s, ";", KEYGEN_MAX_ARGS - naddl_args); - if (!n) { - fprintf(stderr, _("Invalid keygen program, exiting\n")); - exit(EX_USAGE); - } - for(i=0; i < naddl_args && n+i < KEYGEN_MAX_ARGS; i++) - args[n+i] = (char *) addl_args[i]; - args[n+i] = NULL; - - close(fd[0]); - if (dup2(fd[1], STDOUT_FILENO) == -1) { - perror("dup2"); - exit(EX_SYSERR); - } - setuid(getuid()); /* set euid to ruid */ - if (execvp(args[0], args) == -1) { - perror(args[0]); - exit(EX_USAGE); - } - } - - return 0; /* so gcc will shut up */ -} - diff -Naur util-linux-2.12p/mount/sundries.h util-linux-2.12p.new/mount/sundries.h --- util-linux-2.12p/mount/sundries.h 2005-02-10 14:31:18 +0300 +++ util-linux-2.12p.new/mount/sundries.h 2005-02-10 14:17:46 +0300 @@ -25,7 +25,6 @@ void error (const char *fmt, ...); int matching_type (const char *type, const char *types); int matching_opts (const char *options, const char *test_opts); -int use_keygen_prog (const char *s, const char *addl_args[], int naddl_args); void *xmalloc (size_t size); char *xstrdup (const char *s); char *xstrndup (const char *s, int n);