On 01/-10/63 20:59, grarpamp wrote:
For both init and attach (and even elsewhere where
applicable), I'd like to be able to specify the passphrase
and key material via the command line and/or the environment.
Yes, we have -J/j and -K/k, but they only permit the use of files
or standard in. And of course standard in is not an arbitrary
file descriptor and as such is only usable once. So it cannot
be used with both jay and kay. I use both jay and kay, and want
to do so programmatically without blocking on keyboard input.
In the current implementation, I cannot achieve this.
I'm well aware of all security implications of command line
and environment usage.
Please offer your consideration of this feature request :)
Thanks.
Hi!
I think since the -j/-J flags to geli(8) have been introduced, you may
play some tricks with the shell to redirect input (on stable/8 and later
systems).
For stable/7 systems the attached patch should do what you're looking
for. Please be aware, the (well tested) patch does a bit more than just
giving you the ability to read the passphrase from stdin (new -t cli
flag) but also makes some corrections if you're trying to backup and
restore an eli provider. That does not work well if the sizes do not
match and the attached patch fixes that also. I haven't tested for that
bug on stable/8 systems but I guess that bug hasn't been fixed yet.
HTH
Volker
--- sbin/geom/class/eli/geom_eli.c.orig 2009-06-17 17:26:12.000000000 +0200
+++ sbin/geom/class/eli/geom_eli.c 2009-11-10 09:26:25.000000000 +0100
@@ -73,18 +73,20 @@
static void eli_restore(struct gctl_req *req);
static void eli_clear(struct gctl_req *req);
static void eli_dump(struct gctl_req *req);
+static char *eli_get_passwd(struct gctl_req *, const char *, char *, size_t);
+static char *eli_get_stdin_passwd(void);
/*
* Available commands:
*
- * init [-bhPv] [-a aalgo] [-e ealgo] [-i iterations] [-l keylen] [-K
newkeyfile] prov
+ * init [-bhPtv] [-a aalgo] [-e ealgo] [-i iterations] [-l keylen] [-K
newkeyfile] prov
* label - alias for 'init'
- * attach [-dprv] [-k keyfile] prov
+ * attach [-dprtv] [-k keyfile] prov
* detach [-fl] prov ...
* stop - alias for 'detach'
* onetime [-d] [-a aalgo] [-e ealgo] [-l keylen] prov ...
* configure [-bB] prov ...
- * setkey [-pPv] [-n keyno] [-k keyfile] [-K newkeyfile] prov
+ * setkey [-ptPv] [-n keyno] [-k keyfile] [-K newkeyfile] prov
* delkey [-afv] [-n keyno] prov
* kill [-av] [prov ...]
* backup [-v] prov file
@@ -103,9 +105,10 @@
{ 'l', "keylen", &keylen, G_TYPE_NUMBER },
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
{ 's', "sectorsize", §orsize, G_TYPE_NUMBER },
+ { 't', "password-from-stdin", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
- NULL, "[-bPv] [-a aalgo] [-e ealgo] [-i iterations] [-l keylen] [-K
newkeyfile] [-s sectorsize] prov"
+ NULL, "[-btPv] [-a aalgo] [-e ealgo] [-i iterations] [-l keylen]
[-K newkeyfile] [-s sectorsize] prov"
},
{ "label", G_FLAG_VERBOSE, eli_main,
{
@@ -117,6 +120,7 @@
{ 'l', "keylen", &keylen, G_TYPE_NUMBER },
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
{ 's', "sectorsize", §orsize, G_TYPE_NUMBER },
+ { 't', "password-from-stdin", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
NULL, "- an alias for 'init'"
@@ -127,9 +131,10 @@
{ 'k', "keyfile", keyfile, G_TYPE_STRING },
{ 'p', "nopassphrase", NULL, G_TYPE_BOOL },
{ 'r', "readonly", NULL, G_TYPE_BOOL },
+ { 't', "password-from-stdin", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
- NULL, "[-dprv] [-k keyfile] prov"
+ NULL, "[-dtprv] [-k keyfile] prov"
},
{ "detach", 0, NULL,
{
@@ -174,9 +179,10 @@
{ 'n', "keyno", &keyno, G_TYPE_NUMBER },
{ 'p', "nopassphrase", NULL, G_TYPE_BOOL },
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
+ { 't', "password-from-stdin", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
- NULL, "[-pPv] [-n keyno] [-i iterations] [-k keyfile] [-K
newkeyfile] prov"
+ NULL, "[-ptPv] [-n keyno] [-i iterations] [-k keyfile] [-K
newkeyfile] prov"
},
{ "delkey", G_FLAG_VERBOSE, eli_main,
{
@@ -359,9 +365,9 @@
return (NULL);
}
for (;;) {
- p = readpassphrase(
- new ? "Enter new passphrase:" : "Enter passphrase:",
- buf1, sizeof(buf1), RPP_ECHO_OFF | RPP_REQUIRE_TTY);
+ p = eli_get_passwd(req,
+ new ? "Enter new passphrase: " : "Enter
passphrase: ",
+ buf1, sizeof(buf1));
if (p == NULL) {
bzero(buf1, sizeof(buf1));
gctl_error(req, "Cannot read passphrase: %s.",
@@ -369,10 +375,9 @@
return (NULL);
}
- if (new) {
- p = readpassphrase("Reenter new passphrase: ",
- buf2, sizeof(buf2),
- RPP_ECHO_OFF | RPP_REQUIRE_TTY);
+ if (new && ! gctl_get_int(req, "password-from-stdin")) {
+ p = eli_get_passwd(req, "Reenter new
passphrase: ",
+ buf2, sizeof(buf2));
if (p == NULL) {
bzero(buf1, sizeof(buf1));
gctl_error(req,
@@ -383,7 +388,11 @@
if (strcmp(buf1, buf2) != 0) {
bzero(buf2, sizeof(buf2));
- fprintf(stderr, "They didn't match.\n");
+ gctl_error(req, "Passphrases didn't
match.");
+ /* Exit immediately if reading
passwords from stdin. */
+ if (gctl_get_int(req,
"password-from-stdin")) {
+ return (NULL);
+ }
continue;
}
bzero(buf2, sizeof(buf2));
@@ -444,7 +453,7 @@
return (-1);
}
if (read(fd, sector, sizeof(sector)) != sizeof(sector)) {
- gctl_error(req, "Cannot read metadata from %s: %s.",
+ gctl_error(req, "Cannot read metadata file %s: %s.",
prov, strerror(errno));
close(fd);
return (-1);
@@ -1167,6 +1176,12 @@
gctl_error(req, "MD5 hash mismatch: not a geli backup file?");
goto out;
}
+ if (md.md_provsize != mediasize) {
+ printf( "warning: size %llu does not match %llu\n",
+ md.md_provsize, mediasize);
+ md.md_provsize = mediasize;
+ eli_metadata_encode(&md, sector);
+ }
/* Write metadata from the provider. */
if (pwrite(provfd, sector, secsize, mediasize - secsize) !=
(ssize_t)secsize) {
@@ -1225,8 +1240,11 @@
for (i = 0; i < nargs; i++) {
name = gctl_get_ascii(req, "arg%d", i);
+ error = eli_metadata_read(req, name, &tmpmd);
+ /*
error = g_metadata_read(name, (unsigned char *)&tmpmd,
sizeof(tmpmd), G_ELI_MAGIC);
+ */
if (error != 0) {
fprintf(stderr, "Cannot read metadata from %s: %s.\n",
name, strerror(error));
@@ -1244,3 +1262,43 @@
printf("\n");
}
}
+
+
+static char *
+eli_get_passwd(struct gctl_req *req, const char *prompt, char *buf, size_t
bufsiz)
+{
+ char *p = NULL;
+
+ if (gctl_get_int(req, "password-from-stdin")) {
+ p = eli_get_stdin_passwd();
+ strlcpy(buf, p, bufsiz);
+ } else {
+ p = readpassphrase(prompt, buf, bufsiz, RPP_ECHO_OFF |
RPP_REQUIRE_TTY);
+ }
+
+ return p;
+}
+
+static char *
+eli_get_stdin_passwd(void)
+{
+ static char buf[BUFSIZ];
+ size_t len;
+
+ bzero(buf, sizeof(buf));
+
+ /*
+ * if no error is reported from fgets() and string at least contains
+ * the newline that ends the password, then replace the newline with
+ * a null terminator.
+ */
+ if (fgets(buf, sizeof(buf), stdin) != NULL) {
+ if ((len = strlen(buf)) > 0) {
+ if (buf[len-1] == '\n')
+ buf[len - 1] = 0;
+ }
+ }
+
+ return buf;
+}
+
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-geom
To unsubscribe, send any mail to "[email protected]"