[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