From owner-freebsd-geom@FreeBSD.ORG Mon Aug 6 10:21:24 2007 Return-Path: Delivered-To: freebsd-geom@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9189116A420 for ; Mon, 6 Aug 2007 10:21:24 +0000 (UTC) (envelope-from votdev@gmx.de) Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by mx1.freebsd.org (Postfix) with SMTP id 0663813C45A for ; Mon, 6 Aug 2007 10:21:23 +0000 (UTC) (envelope-from votdev@gmx.de) Received: (qmail 7240 invoked by uid 0); 6 Aug 2007 09:54:43 -0000 Received: from 217.111.66.66 by www099.gmx.net with HTTP; Mon, 06 Aug 2007 11:54:43 +0200 (CEST) Content-Type: text/plain; charset="us-ascii" Date: Mon, 06 Aug 2007 11:54:43 +0200 From: votdev@gmx.de Message-ID: <20070806095443.253590@gmx.net> MIME-Version: 1.0 To: freebsd-geom@freebsd.org X-Authenticated: #1412882 X-Flags: 0001 X-Mailer: WWW-Mail 6100 (Global Message Exchange) X-Priority: 3 X-Provags-ID: V01U2FsdGVkX19dZNNYXnddoJvuCVsASOAieYpjVK1k3zY3zoaWpJ ccghA/Hu1AnO+2hwzCY/BP4FvhcWqBc5kElg== Content-Transfer-Encoding: 7bit X-GMX-UID: sJvTNmcCZCEEc3z1cGwhOFB4IGhpZYYe Subject: [PATCH] for GEOM Eli to get password from stdin X-BeenThere: freebsd-geom@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: GEOM-specific discussions and implementations List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Aug 2007 10:21:24 -0000 Hello, i've done a patch for GEOM Eli to get password from stdin as it is done in smbpasswd. This has been done to add scripting ability to geli. It can be used as following: (/bin/echo $passphrase; /bin/echo $passphrase) | /sbin/geli init -t -v -e $ealgo $disk Hope you will integrate it into CURRENT. --- 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", §orsize, 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", §orsize, 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; +} + Greetings Volker -- GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS. Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail