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", &sectorsize, 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", &sectorsize, 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]"

Reply via email to