Репозиторий ALT Linux backports/2.4
Последнее обновление: 9 июля 2008 | Пакетов: 497 | Посещений: 1584451
 поиск   регистрация   авторизация 
 
Группа :: Система/Основа
Пакет: util-linux

 Главная   Изменения   Спек   Патчи   Загрузить   Bugs and FR 

Патч: util-linux-2.12a-alt-encryption.patch


diff -Naur util-linux-2.12a/mount/keygen.c util-linux-2.12a.new/mount/keygen.c
--- util-linux-2.12a/mount/keygen.c	1970-01-01 03:00:00 +0300
+++ util-linux-2.12a.new/mount/keygen.c	2004-03-31 18:48:24 +0400
@@ -0,0 +1,75 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+
+/* 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.12a/mount/keygen.h util-linux-2.12a.new/mount/keygen.h
--- util-linux-2.12a/mount/keygen.h	1970-01-01 03:00:00 +0300
+++ util-linux-2.12a.new/mount/keygen.h	2004-03-31 18:33:41 +0400
@@ -0,0 +1 @@
+int use_keygen_prog (const char *s, const char *addl_args[], int naddl_args);
diff -Naur util-linux-2.12a/mount/lomount.c util-linux-2.12a.new/mount/lomount.c
--- util-linux-2.12a/mount/lomount.c	2004-03-31 18:49:13 +0400
+++ util-linux-2.12a.new/mount/lomount.c	2004-03-31 18:48:49 +0400
@@ -38,11 +38,14 @@
 #include "lomount.h"
 #include "xstrncpy.h"
 #include "nls.h"
+#include "keygen.h"
 
 extern int verbose;
 extern char *xstrdup (const char *s);	/* not: #include "sundries.h" */
 extern void *xmalloc (size_t size);		/* idem */
 extern void error (const char *fmt, ...);	/* idem */
+static void loop_info_to_very_old(struct loop_info* info,const char *name);
+
 
 #ifdef LOOP_SET_FD
 
@@ -402,6 +405,7 @@
 	}
 #endif
 
+
 	switch (loopinfo64.lo_encrypt_type) {
 	case LO_CRYPT_NONE:
 		loopinfo64.lo_encrypt_key_size = 0;
@@ -422,13 +426,15 @@
 			 * this read(), and ruin our whole day. So we	*
 			 * must block it.				*/
 			sigset_t ss, oss;
+			int rc;
 			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"));
+			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);
 		}
@@ -443,6 +449,9 @@
 	if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
 		struct loop_info loopinfo;
 		int errsv = errno;
+		int tried_old;
+		int saved_type;
+		int saved_size;
 
 		if (errno == EINVAL &&
 		    loopinfo64.lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
@@ -458,10 +467,17 @@
 			perror("ioctl: LOOP_SET_STATUS64");
 			goto fail;
 		}
-
+		
+		tried_old = 0;
+again:
 		if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
-			errsv = errno;
-
+		/* Try again with old-style LO_CRYPT_XX if
+		  new-style LO_CRYPT_CRYPTOAPI ioctl didn't work */
+		    errsv = errno;
+		    if (tried_old)
+		    {
+			loopinfo.lo_encrypt_type = saved_type;
+			loopinfo.lo_encrypt_key_size = saved_size;
 			if (errno == EINVAL &&
 			    loopinfo.lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
 				if (!check_crypto_old(&loopinfo)) {
@@ -473,6 +489,13 @@
 			errno = errsv;
 			perror("ioctl: LOOP_SET_STATUS");
 			goto fail;
+		    }
+		    saved_type = loopinfo.lo_encrypt_type;
+		    saved_size = loopinfo.lo_encrypt_key_size;
+		    loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
+		    loop_info_to_very_old(&loopinfo,encryption);
+		    tried_old = 1;
+		    goto again;
 		}
 	}
 
@@ -615,7 +638,7 @@
 	delete = off = 0;
 	offset = encryption = passfd = NULL;
 	progname = argv[0];
-	while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
+	while ((c = getopt(argc,argv,"de:E:o:p:vk:")) != -1) {
 		switch (c) {
 		case 'd':
 			delete = 1;
@@ -630,6 +653,9 @@
 		case 'p':
 			passfd = optarg;
 			break;
+		case 'k':
+			pfd = use_keygen_prog(optarg, NULL,0);
+			break;
 		case 'v':
 			verbose = 1;
 			break;
@@ -668,3 +694,85 @@
 }
 #endif
 #endif
+
+#ifndef LO_CRYPT_CRYPTOAPI
+#define LO_CRYPT_CRYPTOAPI 18
+#endif
+#ifndef LO_CRYPT_NONE
+#define LO_CRYPT_NONE 0
+#endif
+#ifndef LO_CRYPT_XOR
+#define LO_CRYPT_XOR 1
+#endif
+#ifndef LO_CRYPT_DES
+#define LO_CRYPT_DES 2
+#endif
+#ifndef LO_CRYPT_FISH2
+#define LO_CRYPT_FISH2 3
+#endif
+#ifndef LO_CRYPT_BLOW
+#define LO_CRYPT_BLOW 4
+#endif
+#ifndef LO_CRYPT_CAST128
+#define LO_CRYPT_CAST128 5
+#endif
+#ifndef LO_CRYPT_IDEA
+#define LO_CRYPT_IDEA 6
+#endif
+#ifndef LO_CRYPT_SERPENT
+#define LO_CRYPT_SERPENT 7
+#endif
+#ifndef LO_CRYPT_MARS
+#define LO_CRYPT_MARS 8
+#endif
+#ifndef LO_CRYPT_RC6
+#define LO_CRYPT_RC6 11
+#endif
+#ifndef LO_CRYPT_3DES
+#define LO_CRYPT_3DES 12
+#endif
+#ifndef LO_CRYPT_DFC
+#define LO_CRYPT_DFC 15
+#endif
+#ifndef LO_CRYPT_RIJNDAEL
+#define LO_CRYPT_RIJNDAEL 16
+#endif
+
+struct crypt_type_struct {
+	int id;
+	char *name;
+	int keylength;
+} crypt_type_tbl[] = {
+         { LO_CRYPT_NONE, "none", 0 },
+         { LO_CRYPT_XOR, "xor", 0 },
+         { LO_CRYPT_DES, "des", 8 },
+         { LO_CRYPT_FISH2, "twofish", 20 },
+         { LO_CRYPT_BLOW, "blowfish", 20 },
+         { LO_CRYPT_CAST128, "cast", 16 },
+         { LO_CRYPT_SERPENT, "serpent", 16 },
+         { LO_CRYPT_MARS, "mars", 16 },
+         { LO_CRYPT_RC6, "rc6", 16 },
+         { LO_CRYPT_3DES, "des-ede3", 24 },
+         { LO_CRYPT_DFC, "dfc", 16 },
+         { LO_CRYPT_IDEA, "idea", 16 },
+         { LO_CRYPT_RIJNDAEL, "rijndael", 16 },
+	 { -1, NULL,0   }
+};
+
+
+static void
+loop_info_to_very_old(struct loop_info* info,const char *name)
+{
+    int i;
+
+    if (name) {
+            for (i = 0; crypt_type_tbl[i].id != -1; i++)
+                    if (strstr (name, crypt_type_tbl[i].name))
+		    {
+			    info->lo_encrypt_type = crypt_type_tbl[i].id;
+			    info->lo_encrypt_key_size = crypt_type_tbl[i].keylength;
+			    return;
+		    }
+    }
+}
+
diff -Naur util-linux-2.12a/mount/losetup.8 util-linux-2.12a.new/mount/losetup.8
--- util-linux-2.12a/mount/losetup.8	2003-07-16 03:06:37 +0400
+++ util-linux-2.12a.new/mount/losetup.8	2004-03-31 18:44:45 +0400
@@ -54,7 +54,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\-o \fIoffset\fP"
 The data start is moved \fIoffset\fP bytes into the specified file or
@@ -75,6 +75,7 @@
 .SH FILES
 .nf
 /dev/loop0, /dev/loop1, ...   loop devices (major=7)
+/lib/modules/<version>/kernel/net/cryptoapi/ciphers/* available ciphers
 .fi
 .SH EXAMPLE
 If you are using the loadable module you must have the module loaded
@@ -90,8 +91,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.12a/mount/Makefile util-linux-2.12a.new/mount/Makefile
--- util-linux-2.12a/mount/Makefile	2003-07-17 00:07:27 +0400
+++ util-linux-2.12a.new/mount/Makefile	2004-03-31 18:37:27 +0400
@@ -42,7 +42,7 @@
 %.o: %.c
 	$(COMPILE) $<
 
-mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \
+mount: keygen.o mount.o fstab.o sundries.o realpath.o mntent.o version.o \
        mount_guess_fstype.o get_label_uuid.o mount_by_label.o getusername.o \
        $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS)
 	$(LINK) $^ -o $@
@@ -57,7 +57,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.12a/mount/mount.c util-linux-2.12a.new/mount/mount.c
--- util-linux-2.12a/mount/mount.c	2004-03-31 18:49:13 +0400
+++ util-linux-2.12a.new/mount/mount.c	2004-03-31 18:49:00 +0400
@@ -70,6 +70,7 @@
 #include "getusername.h"
 #include "env.h"
 #include "nls.h"
+#include "keygen.h"
 
 #define DO_PS_FIDDLING
 
diff -Naur util-linux-2.12a/mount/sundries.c util-linux-2.12a.new/mount/sundries.c
--- util-linux-2.12a/mount/sundries.c	2004-03-31 18:49:13 +0400
+++ util-linux-2.12a.new/mount/sundries.c	2004-03-31 18:35:35 +0400
@@ -12,8 +12,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <mntent.h>		/* for MNTTYPE_SWAP */
-#include <sys/types.h>
-#include <sys/wait.h>
 #include "fstab.h"
 #include "sundries.h"
 #include "realpath.h"
@@ -288,99 +286,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.12a/mount/sundries.h util-linux-2.12a.new/mount/sundries.h
--- util-linux-2.12a/mount/sundries.h	2004-03-31 18:49:13 +0400
+++ util-linux-2.12a.new/mount/sundries.h	2004-03-31 18:35:49 +0400
@@ -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);
 
design & coding: Vladimir Lettiev aka crux © 2004-2005