Bug 115547 - [geom] [patch] [request] let GEOM Eli get password from stdin (useful for non-interactive scripting)
Summary: [geom] [patch] [request] let GEOM Eli get password from stdin (useful for non...
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 1.0-CURRENT
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-15 13:50 UTC by Volker
Modified: 2018-01-03 05:13 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Volker 2007-08-15 13:50:03 UTC
To get GEOM Eli working in our project (http://www.freenas.org) I had
to enhance the geli userland application. The original code does not
support non-interactive scripting, e.g. when creating or initializing
GEOM Eli filesystem, because the password has to be entered interactively
on the console. Because our project is administrated via WebGUI it is
not possible to do that. With the patch you can enter the password non-
interactively as following:

(/bin/echo $passphrase; /bin/echo $passphrase) | /sbin/geli init -t -v -e $ealgo $disk

The code has been taken from the Samba tool 'smbpasswd'. The patch itself
has been done for CURRENT.

I think this is also useful for other users.

Greetings
Volker

/usr/src/sbin/geom/class/eli:

--- geom_eli.c.orig	Mon Aug  6 10:18:42 2007
+++ geom_eli.c	Mon Aug  6 10:36:02 2007
@@ -73,13 +73,15 @@
 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 ...
@@ -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_NONE },
 		G_OPT_SENTINEL
 	    },
-	    NULL, "[-bPv] [-a aalgo] [-e ealgo] [-i iterations] [-l keylen] [-K newkeyfile] [-s sectorsize] prov"
+	    NULL, "[-bPtv] [-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_NONE },
 		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_NONE },
 		G_OPT_SENTINEL
 	    },
-	    NULL, "[-dprv] [-k keyfile] prov"
+	    NULL, "[-dprtv] [-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_NONE },
 		G_OPT_SENTINEL
 	    },
-	    NULL, "[-pPv] [-n keyno] [-i iterations] [-k keyfile] [-K newkeyfile] prov"
+	    NULL, "[-pPtv] [-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.",
@@ -370,9 +376,8 @@
 			}
 	
 			if (new) {
-				p = readpassphrase("Reenter new passphrase: ",
-				    buf2, sizeof(buf2),
-				    RPP_ECHO_OFF | RPP_REQUIRE_TTY);
+				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));
@@ -1244,3 +1253,42 @@
 		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;
+}
+
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2007-08-15 19:33:39 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-geom

Over to maintainer(s).
Comment 2 Volker Theile 2008-06-03 09:00:18 UTC
You can also use volker@freenas.org

Patch for 0.7 can be found here:
http://freenas.svn.sourceforge.net/viewvc/freenas/trunk/build/ports/geom_eli/files/geom_eli.c.diff?view=markup

Regards
Volker

-------- Original-Nachricht --------
> Datum: Sun, 1 Jun 2008 21:29:34 GMT
> Von: pjd@FreeBSD.org
> An: votdev@gmx.de, pjd@FreeBSD.org, freebsd-geom@FreeBSD.org
> Betreff: Re: kern/115547: [geom] [patch] [request] let GEOM Eli get password from stdin (useful for non-interactive scripting)

> Synopsis: [geom] [patch] [request] let GEOM Eli get password from stdin
> (useful for non-interactive scripting)
> 
> State-Changed-From-To: open->suspended
> State-Changed-By: pjd
> State-Changed-When: ndz 1 cze 21:28:29 2008 UTC
> State-Changed-Why: 
> Suspend PR, because I can't contact PR author due misconfigured mail
> server, which refuses e-mail from my mail server.
> 
> http://www.freebsd.org/cgi/query-pr.cgi?pr=115547

-- 
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger
Comment 3 Gavin Atkinson freebsd_committer freebsd_triage 2009-04-17 14:54:01 UTC
State Changed
From-To: feedback->open

Mark as open, There seems to be no reason for this to be marked as 
awaiting feedback.
Comment 4 Pawel Jakub Dawidek freebsd_committer freebsd_triage 2014-06-01 06:39:03 UTC
State Changed
From-To: open->suspended

Suspend PR, because I can't contact PR author due misconfigured mail server, which refuses e-mail from my mail server.
Comment 5 Pawel Jakub Dawidek freebsd_committer freebsd_triage 2014-06-01 06:39:03 UTC
State Changed
From-To: suspended->feedback
Comment 6 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:01:37 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped