From 025c5f4aa5ffbf8948482a4233318db81c2df5d2 Mon Sep 17 00:00:00 2001 From: mdw Date: Tue, 5 Apr 2005 20:59:07 +0000 Subject: [PATCH] Uprating of the passphrase pixie. --- Makefile.m4 | 4 +- passphrase.c | 25 ++++--- passphrase.h | 14 +++- pixie-client.c | 207 --------------------------------------------------------- pixie-common.c | 155 +++++++++++++++++++++++++++++++++++++++++- pixie.1 | 28 ++++++-- pixie.c | 58 ++++++++++++++-- 7 files changed, 264 insertions(+), 227 deletions(-) delete mode 100644 pixie-client.c diff --git a/Makefile.m4 b/Makefile.m4 index df761d2..2b869f4 100644 --- a/Makefile.m4 +++ b/Makefile.m4 @@ -220,7 +220,7 @@ libcatacomb_la_SOURCES = \ grand.c keysz.c \ lcrand.c fibrand.c rc4.c seal.c rand.c noise.c fipstest.c maurer.c \ arena.c \ - passphrase.c pixie-client.c pixie-common.c lmem.c \ + passphrase.c pixie-common.c lmem.c \ tlsprf.c sslprf.c \ gfshare.c \ MP_SOURCES karatsuba.h \ @@ -280,7 +280,7 @@ hashsum_SOURCES = hashsum.c rspit_SOURCES = rspit.c factorial_SOURCES = factorial.c perftest_SOURCES = perftest.c -pixie_SOURCES = pixie.c pixie-common.c lmem.c arena.c +pixie_SOURCES = pixie.c pixie-common.c lmem.c arena.c passphrase.c pixie_LDADD = mkphrase_SOURCES = mkphrase.c bittest_SOURCES = bittest.c diff --git a/passphrase.c b/passphrase.c index 0b8ddcf..410b7af 100644 --- a/passphrase.c +++ b/passphrase.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: passphrase.c,v 1.6 2004/04/08 01:36:15 mdw Exp $ + * $Id$ * * Reading of passphrases (Unix-specific) * @@ -50,28 +50,37 @@ static unsigned flags = 0; /*----- Main code ---------------------------------------------------------*/ -/* --- @pconn@ --- * +/* --- @passphrase_connect@ --- * - * Arguments: --- + * Arguments: @const char *sock@ = socket name to connect to, or null for + * default * * Returns: Zero if OK, nonzero if it failed * * Use: Attempts to connect to the passphrase pixie. */ -static int pconn(void) +int passphrase_connect(const char *sock) { if (fd != -1) - return (0); - if (flags & f_fail) - return (-1); - if ((fd = pixie_open(0)) < 0) { + close(fd); + if ((fd = pixie_open(sock)) < 0) { flags |= f_fail; return (-1); } + flags &= ~f_fail; return (0); } +static int pconn(void) +{ + if (fd != -1) + return (0); + if (flags & f_fail) + return (-1); + return (passphrase_connect(0)); +} + /* --- @passphrase_read@ --- * * * Arguments: @const char *tag@ = pointer to passphrase tag string diff --git a/passphrase.h b/passphrase.h index 85ec58e..611b7e1 100644 --- a/passphrase.h +++ b/passphrase.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: passphrase.h,v 1.2 2004/04/08 01:36:15 mdw Exp $ + * $Id$ * * Reading passphrases * @@ -53,6 +53,18 @@ enum { /*----- Functions provided ------------------------------------------------*/ +/* --- @passphrase_connect@ --- + * + * Arguments: @const char *sock@ = socket name to connect to, or null for + * default + * + * Returns: Zero if OK, nonzero if it failed + * + * Use: Attempts to connect to the passphrase pixie. + */ + +extern int passphrase_connect(const char */*sock*/); + /* --- @passphrase_read@ --- * * * Arguments: @const char *tag@ = pointer to passphrase tag string diff --git a/pixie-client.c b/pixie-client.c deleted file mode 100644 index 73558ff..0000000 --- a/pixie-client.c +++ /dev/null @@ -1,207 +0,0 @@ -/* -*-c-*- - * - * $Id$ - * - * Simple passphrase pixie client (Unix-specific) - * - * (c) 1999 Straylight/Edgeware - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of Catacomb. - * - * Catacomb is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Catacomb is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with Catacomb; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "passphrase.h" -#include "pixie.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @pixie_open@ --- * - * - * Arguments: @const char *sock@ = path to pixie socket - * - * Returns: Less than zero if it failed, or file descriptor. - * - * Use: Opens a connection to a passphrase pixie. - */ - -int pixie_open(const char *sock) -{ - struct sockaddr_un *sun; - size_t sz; - int fd; - - /* --- Open the connection --- */ - - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - goto fail_0; - sun = pixie_address(sock, &sz); - if (connect(fd, (struct sockaddr *)sun, sz)) - goto fail_1; - xfree(sun); - return (fd); - - /* --- Tidy up if things went wrong --- */ - -fail_1: - xfree(sun); - close(fd); -fail_0: - return (-1); -} - -/* --- @pixie_read@ --- * - * - * Arguments: @int fd@ = connection to passphrase pixie - * @const char *tag@ = pointer to tag string - * @unsigned mode@ = reading mode - * @char *buf@ = pointer to destination buffer - * @size_t sz@ = size of the buffer - * - * Returns: Zero if all went well, @-1@ if the read fails, @+1@ to - * request the passphrase from the user. - * - * Use: Reads a passphrase from the pixie. - */ - -int pixie_read(int fd, const char *tag, unsigned mode, char *buf, size_t sz) -{ - dstr d = DSTR_INIT; - char *p, *q; - - /* --- Send the request --- */ - - dstr_putf(&d, "%s %s\n", mode == PMODE_READ ? "PASS" : "VERIFY", tag); - write(fd, d.buf, d.len); - dstr_destroy(&d); - - /* --- Sort out the result --- */ - -again: - pixie_fdline(fd, buf, sz); - p = buf; - if ((q = str_getword(&p)) == 0) - return (-1); - if (strcmp(q, "INFO") == 0) - goto again; - else if (strcmp(q, "MISSING") == 0) - return (+1); - else if (strcmp(q, "OK") != 0) - return (-1); - - /* --- Return the final answer --- */ - - if (p) - memmove(buf, p, strlen(p) + 1); - else - *buf = 0; - return (0); -} - -/* --- @pixie_set@ --- * - * - * Arguments: @int fd@ = pixie file descriptor - * @const char *tag@ = pointer to tag string - * @const char *phrase@ = pointer to passphrase string - * - * Returns: --- - * - * Use: Sends a passphrase to the passphrase pixie. - */ - -void pixie_set(int fd, const char *tag, const char *phrase) -{ - dstr d = DSTR_INIT; - char buf[16]; - size_t sz = strlen(phrase); - char nl = '\n'; - char *p, *q; - - /* --- Send the request --- * - * - * I didn't want to copy it out of the caller's buffer. @writev@ may - * produce a copy, too, so I didn't do that either. - */ - - dstr_putf(&d, "SET %s -- ", tag); - write(fd, d.buf, d.len); - write(fd, phrase, sz); - write(fd, &nl, 1); - dstr_destroy(&d); - - /* --- Pick up the pieces --- */ - -again: - pixie_fdline(fd, buf, sizeof(buf)); - p = buf; - if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0) - goto again; -} - -/* --- @pixie_cancel@ --- * - * - * Arguments: @int fd@ = pixie file descriptor - * @const char *tag@ = pointer to tag string - * - * Returns: --- - * - * Use: Cancels a passphrase if it turns out to be bogus. - */ - -void pixie_cancel(int fd, const char *tag) -{ - dstr d = DSTR_INIT; - char buf[16]; - char *p, *q; - - /* --- Send the request --- */ - - dstr_putf(&d, "FLUSH %s\n", tag); - write(fd, d.buf, d.len); - dstr_destroy(&d); - - /* --- Sort out the result --- */ - -again: - pixie_fdline(fd, buf, sizeof(buf)); - p = buf; - if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0) - goto again; -} - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/pixie-common.c b/pixie-common.c index 6efd763..2395f52 100644 --- a/pixie-common.c +++ b/pixie-common.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: pixie-common.c,v 1.2 2004/04/08 01:36:15 mdw Exp $ + * $Id$ * * Common code for Pixie client and server (Unix-specific) * @@ -46,6 +46,7 @@ #include #include +#include #include "pixie.h" @@ -218,6 +219,158 @@ fail_0: return (-1); } +/* --- @pixie_open@ --- * + * + * Arguments: @const char *sock@ = path to pixie socket + * + * Returns: Less than zero if it failed, or file descriptor. + * + * Use: Opens a connection to a passphrase pixie. + */ + +int pixie_open(const char *sock) +{ + struct sockaddr_un *sun; + size_t sz; + int fd; + + /* --- Open the connection --- */ + + if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + goto fail_0; + sun = pixie_address(sock, &sz); + if (connect(fd, (struct sockaddr *)sun, sz)) + goto fail_1; + xfree(sun); + return (fd); + + /* --- Tidy up if things went wrong --- */ + +fail_1: + xfree(sun); + close(fd); +fail_0: + return (-1); +} + +/* --- @pixie_read@ --- * + * + * Arguments: @int fd@ = connection to passphrase pixie + * @const char *tag@ = pointer to tag string + * @unsigned mode@ = reading mode + * @char *buf@ = pointer to destination buffer + * @size_t sz@ = size of the buffer + * + * Returns: Zero if all went well, @-1@ if the read fails, @+1@ to + * request the passphrase from the user. + * + * Use: Reads a passphrase from the pixie. + */ + +int pixie_read(int fd, const char *tag, unsigned mode, char *buf, size_t sz) +{ + dstr d = DSTR_INIT; + char *p, *q; + + /* --- Send the request --- */ + + dstr_putf(&d, "%s %s\n", mode == PMODE_READ ? "PASS" : "VERIFY", tag); + write(fd, d.buf, d.len); + dstr_destroy(&d); + + /* --- Sort out the result --- */ + +again: + pixie_fdline(fd, buf, sz); + p = buf; + if ((q = str_getword(&p)) == 0) + return (-1); + if (strcmp(q, "INFO") == 0) + goto again; + else if (strcmp(q, "MISSING") == 0) + return (+1); + else if (strcmp(q, "OK") != 0) + return (-1); + + /* --- Return the final answer --- */ + + if (p) + memmove(buf, p, strlen(p) + 1); + else + *buf = 0; + return (0); +} + +/* --- @pixie_set@ --- * + * + * Arguments: @int fd@ = pixie file descriptor + * @const char *tag@ = pointer to tag string + * @const char *phrase@ = pointer to passphrase string + * + * Returns: --- + * + * Use: Sends a passphrase to the passphrase pixie. + */ + +void pixie_set(int fd, const char *tag, const char *phrase) +{ + dstr d = DSTR_INIT; + char buf[16]; + size_t sz = strlen(phrase); + char nl = '\n'; + char *p, *q; + + /* --- Send the request --- * + * + * I didn't want to copy it out of the caller's buffer. @writev@ may + * produce a copy, too, so I didn't do that either. + */ + + dstr_putf(&d, "SET %s -- ", tag); + write(fd, d.buf, d.len); + write(fd, phrase, sz); + write(fd, &nl, 1); + dstr_destroy(&d); + + /* --- Pick up the pieces --- */ + +again: + pixie_fdline(fd, buf, sizeof(buf)); + p = buf; + if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0) + goto again; +} + +/* --- @pixie_cancel@ --- * + * + * Arguments: @int fd@ = pixie file descriptor + * @const char *tag@ = pointer to tag string + * + * Returns: --- + * + * Use: Cancels a passphrase if it turns out to be bogus. + */ + +void pixie_cancel(int fd, const char *tag) +{ + dstr d = DSTR_INIT; + char buf[16]; + char *p, *q; + + /* --- Send the request --- */ + + dstr_putf(&d, "FLUSH %s\n", tag); + write(fd, d.buf, d.len); + dstr_destroy(&d); + + /* --- Sort out the result --- */ + +again: + pixie_fdline(fd, buf, sizeof(buf)); + p = buf; + if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0) + goto again; +} /*----- That's all, folks -------------------------------------------------*/ diff --git a/pixie.1 b/pixie.1 index c63492b..bdffd05 100644 --- a/pixie.1 +++ b/pixie.1 @@ -26,6 +26,12 @@ pixie \- Catacomb passphrase pixie .IR socket ] .B \-C .RI [ "request args" ...] +.br +.B pixie +.RB [ \-s +.IR socket ] +.BR \-P [ P ] +.I tag .SH "DESCRIPTION" The passphrase pixie manages passphrases. When it starts up, it creates a Unix-domain socket in a private directory. Clients may connect to it @@ -58,10 +64,24 @@ Print a terse usage summary and exit successfully. .B "\-C, \-\-client" Connect to a running pixie as a client. If command-line arguments are supplied, they are concatenated with spaces between them and submitted -to the pixie as a request; a reply is read from the pixie and printed -on stdout. If no command-line arguments are given, requestss are read -interactively from stdin and sent to the pixie; the pixie's responses -are printed on stdout. +to the pixie as a request; a reply is read from the pixie and formatted: +information is written to standard output; errors are reported via +standard error and the exit status. If no command-line arguments are +given, requestss are read interactively from stdin and sent to the +pixie; the pixie's responses are printed on stdout uninterpreted. +.TP +.B "\-P, \-\-passphrase" +Connect to a running pixie and request the passphrase with tag +.IR tag . +If no pixie is running then request the passphrase from the terminal. +Print the result on standard output, followed by a newline. +.TP +.B "\-PP, \-\-verify-passphrase" +Connect to a running pixie and request verification of the passphrase +with tag +.IR tag . +If no pixie is running, request the passphrase from the terminal. Print +the result on standard output, followed by a newline. .TP .B "\-q, \-\-quiet" Causes the pixie to emit fewer log messages. diff --git a/pixie.c b/pixie.c index b7083f3..993b60f 100644 --- a/pixie.c +++ b/pixie.c @@ -1024,6 +1024,7 @@ static unsigned c_flags = 0; #define cf_uclose 1u #define cf_sclose 2u +#define cf_cooked 4u /* --- Line handler functions --- */ @@ -1049,7 +1050,22 @@ static void c_sline(char *s, size_t len, void *p) } exit(0); } - puts(s); + if (!(c_flags & cf_cooked)) + puts(s); + else { + char *q = str_getword(&s); + if (strcmp(q, "FAIL") == 0) + die(1, "%s", p); + else if (strcmp(q, "INFO") == 0 || + strcmp(q, "ITEM") == 0) + puts(s); + else if (strcmp(q, "OK") == 0) { + if (s && *s) puts(s); + } else if (strcmp(q, "MISSING") == 0) + ; + else + moan("unexpected output: %s %s", q, s); + } } /* --- @pix_client@ --- * @@ -1093,7 +1109,7 @@ static void pix_client(struct sockaddr_un *sun, size_t sz, char *argv[]) DPUTC(&d, '\n'); write(fd, d.buf, d.len); shutdown(fd, 1); - c_flags |= cf_uclose; + c_flags |= cf_uclose | cf_cooked; dstr_destroy(&d); } @@ -1122,6 +1138,7 @@ static void usage(FILE *fp) Usage:\n\ $ [-qvfidl] [-c COMMAND] [-t TIMEOUT] [-s SOCKET]\n\ $ [-s SOCKET] -C [COMMAND ARGS...]\n\ + $ [-s SOCKET] -P[P] TAG\n\ "); } @@ -1144,6 +1161,9 @@ protect important keys. Options provided:\n\ -u, --usage Show a (very) terse usage summary.\n\ \n\ -C, --client Connect to a running pixie as a client.\n\ +-P, --passphrase Request passphrase TAG and print to stdout.\n\ +-PP, --verify-passphrase\n\ + Verify passphrase TAG and print to stdout.\n\ \n\ -q, --quiet Emit fewer log messages.\n\ -v, --version Emit more log messages.\n\ @@ -1190,6 +1210,8 @@ int main(int argc, char *argv[]) #define f_stdin 4u #define f_daemon 8u #define f_syslog 16u +#define f_fetch 32u +#define f_verify 64u /* --- Initialize libraries --- */ @@ -1217,6 +1239,8 @@ int main(int argc, char *argv[]) { "quiet", 0, 0, 'q' }, { "verbose", 0, 0, 'v' }, { "client", 0, 0, 'C' }, + { "passphrase", 0, 0, 'P' }, + { "verify-passphrase", 0, 0, '+' }, { "socket", OPTF_ARGREQ, 0, 's' }, { "command", OPTF_ARGREQ, 0, 'c' }, { "fetch", 0, 0, 'f' }, @@ -1232,7 +1256,7 @@ int main(int argc, char *argv[]) { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "hVuqvCs:c:ft:idl", opts, 0, 0, 0); + int i = mdwopt(argc, argv, "hVuqvCPs:c:ft:idl", opts, 0, 0, 0); if (i < 0) break; @@ -1261,6 +1285,17 @@ int main(int argc, char *argv[]) break; case 'C': f |= f_client; + f &= ~f_fetch; + break; + case 'P': + if (!(f & f_fetch)) + f |= f_fetch; + else + f |= f_verify; + break; + case '+': + f |= f_fetch | f_verify; + f &= ~f_client; break; case 's': path = optarg; @@ -1294,11 +1329,26 @@ int main(int argc, char *argv[]) } } - if (f & f_bogus || (optind < argc && !(f & f_client))) { + if (f & f_bogus || + (optind < argc && !(f & (f_client|f_fetch))) || + ((f & f_fetch) && optind != argc - 1)) { usage(stderr); exit(1); } + /* --- Handle request for a passphrase --- */ + + if (f & f_fetch) { + char *buf = l_alloc(&lm, 1024); + passphrase_connect(path); + if (passphrase_read(argv[optind], + (f & f_verify) ? PMODE_VERIFY : PMODE_READ, + buf, 1024)) + die(1, "failed to read passphrase: %s", strerror(errno)); + puts(buf); + return (0); + } + /* --- Set up the socket address --- */ sun = pixie_address(path, &sz); -- 2.11.0