X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/70a5dedfb44f242c012190f1fa9240241fa0f35f..1519ef6617fd7351bd40026b9eeb47c7f7f42234:/progs/pixie.c diff --git a/progs/pixie.c b/progs/pixie.c index 79162a85..f827c201 100644 --- a/progs/pixie.c +++ b/progs/pixie.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ static unsigned flags = 0; #define F_SYSLOG 1u #define F_FETCH 2u +#define F_REPLACE 4u /*----- Event logging -----------------------------------------------------*/ @@ -228,7 +230,7 @@ static phrase *p_find(const char *tag) phrase *p; for (p = p_head; p; p = p->next) { - if (strcmp(p->tag, tag) == 0) { + if (STRCMP(p->tag, ==, tag)) { if (p->t) { struct timeval tv; sel_rmtimer(&p->timer); @@ -310,7 +312,7 @@ static void p_flush(const char *tag) phrase *pp = p->next; if (!tag) p_free(p); - else if (strcmp(p->tag, tag) == 0) { + else if (STRCMP(p->tag, ==, tag)) { if (verbose > 1) pxlog("flushing passphrase `%s'", tag); p_free(p); @@ -444,7 +446,7 @@ static int p_request(const char *msg, const char *tag, char *buf, size_t sz) ok: { char *p = buf; size_t len; - while (isspace((unsigned char)*p)) + while (ISSPACE(*p)) p++; len = strlen(p); memmove(buf, p, len); @@ -516,7 +518,7 @@ static int p_get(const char **q, const char *tag, unsigned mode, time_t exp) goto fail; if (p_request("Verify passphrase", tag, pp, LBUFSZ) < 0) goto fail; - if (strcmp(pp, p->p) != 0) { + if (STRCMP(pp, !=, p->p)) { if (verbose) pxlog("passphrases for `%s' don't match", tag); p_free(p); @@ -676,20 +678,20 @@ static void pixserv_line(char *s, size_t len, void *p) if ((q = str_getword(&s)) == 0) return; for (qq = q; *qq; qq++) - *qq = tolower((unsigned char)*qq); + *qq = TOLOWER(*qq); /* --- Handle a help request --- */ - if (strcmp(q, "help") == 0) { + if (STRCMP(q, ==, "help")) { if (pixserv_write(px, "\ INFO Commands supported:\n\ -INFO HELP\n\ -INFO LIST\n\ -INFO PASS tag [expire]\n\ -INFO VERIFY tag [expire]\n\ -INFO FLUSH [tag]\n\ -INFO SET tag [expire] -- phrase\n\ -INFO QUIT\n\ +INFO flush [TAG]\n\ +INFO help\n\ +INFO list\n\ +INFO pass TAG [EXPIRE]\n\ +INFO quit\n\ +INFO set TAG [EXPIRE] -- PHRASE\n\ +INFO verify TAG [EXPIRE]\n\ OK\n\ ")) goto close; @@ -697,7 +699,7 @@ OK\n\ /* --- List the passphrases --- */ - else if (strcmp(q, "list") == 0) { + else if (STRCMP(q, ==, "list")) { phrase *p; for (p = p_head; p; p = p->next) { @@ -717,8 +719,8 @@ OK\n\ /* --- Request a passphrase --- */ - else if ((mode = PMODE_READ, strcmp(q, "pass") == 0) || - (mode = PMODE_VERIFY, strcmp(q, "verify") == 0)) { + else if ((mode = PMODE_READ, STRCMP(q, ==, "pass")) || + (mode = PMODE_VERIFY, STRCMP(q, ==, "verify"))) { unsigned long t; const char *p; int rc; @@ -746,7 +748,7 @@ OK\n\ /* --- Flush existing passphrases --- */ - else if (strcmp(q, "flush") == 0) { + else if (STRCMP(q, ==, "flush")) { q = str_getword(&s); p_flush(q); if (pixserv_write(px, "OK\n")) goto close; @@ -754,7 +756,7 @@ OK\n\ /* --- Set a passphrase --- */ - else if (strcmp(q, "set") == 0) { + else if (STRCMP(q, ==, "set")) { char *tag; unsigned long t; if ((tag = str_getword(&s)) == 0) { @@ -762,19 +764,19 @@ OK\n\ } else if ((q = str_getword(&s)) == 0) { if (pixserv_write(px, "FAIL no passphrase\n")) goto close; } else { - if (strcmp(q, "--") != 0) { + if (STRCMP(q, !=, "--")) { t = pixserv_timeout(q); q = str_getword(&s); } else t = pixserv_timeout(0); if (!q) { if (pixserv_write(px, "FAIL no passphrase\n")) goto close; - } else if (strcmp(q, "--") != 0) { + } else if (STRCMP(q, !=, "--")) { if (pixserv_write(px, "FAIL rubbish found before passphrase\n")) goto close; } else { p_flush(tag); - p_add(tag, s, t); + p_add(tag, s ? s : "", t); if (pixserv_write(px, "OK\n")) goto close; } } @@ -782,7 +784,7 @@ OK\n\ /* --- Shut the server down --- */ - else if (strcmp(q, "quit") == 0) { + else if (STRCMP(q, ==, "quit")) { if (verbose) { pxlog("%s client requested shutdown", px->f & px_stdin ? "local" : "remote"); @@ -848,7 +850,7 @@ static void pixserv_accept(int fd, unsigned mode, void *p) { int nfd; struct sockaddr_un sun; - size_t sunsz = sizeof(sun); + socklen_t sunsz = sizeof(sun); if (mode != SEL_READ) return; @@ -1005,7 +1007,7 @@ static void pix_setup(struct sockaddr_un *sun, size_t sz) pxlog("stale socket found; removing it"); unlink(sun->sun_path); close(fd); - } else { + } else if (flags & F_REPLACE) { if (verbose) pxlog("server already running; shutting it down"); if (write(fd, "QUIT\n", 5) < 0) { @@ -1014,7 +1016,8 @@ static void pix_setup(struct sockaddr_un *sun, size_t sz) } sleep(1); close(fd); - } + } else + die(EXIT_FAILURE, "pixie already running; not starting"); goto again; } chmod(sun->sun_path, 0600); @@ -1074,14 +1077,14 @@ static void c_sline(char *s, size_t len, void *p) puts(s); else { char *q = str_getword(&s); - if (strcmp(q, "FAIL") == 0) + if (STRCMP(q, ==, "FAIL")) die(1, "%s", s); - else if (strcmp(q, "INFO") == 0 || - strcmp(q, "ITEM") == 0) + else if (STRCMP(q, ==, "INFO") || + STRCMP(q, ==, "ITEM")) puts(s); - else if (strcmp(q, "OK") == 0) { + else if (STRCMP(q, ==, "OK")) { if (s && *s) puts(s); - } else if (strcmp(q, "MISSING") == 0) + } else if (STRCMP(q, ==, "MISSING")) ; else moan("unexpected output: %s %s", q, s); @@ -1188,6 +1191,7 @@ protect important keys. Options provided:\n\ -q, --quiet Emit fewer log messages.\n\ -v, --version Emit more log messages.\n\ -s, --socket=FILE Name the pixie's socket.\n\ +-r, --replace Replace existing pixie, if one is running.\n\ -c, --command=COMMAND Shell command to read a passphrase.\n\ -f, --fetch Fetch passphrases from the terminal.\n\ -t, --timeout=TIMEOUT Length of time to retain a passphrase in memory.\n\ @@ -1241,7 +1245,7 @@ int main(int argc, char *argv[]) /* --- Set up the locked memory area --- */ l_init(&lm, 16384); - setuid(getuid()); + if (setuid(getuid())) _exit(125); /* --- Parse command line arguments --- */ @@ -1262,6 +1266,7 @@ int main(int argc, char *argv[]) { "passphrase", 0, 0, 'P' }, { "verify-passphrase", 0, 0, '+' }, { "socket", OPTF_ARGREQ, 0, 's' }, + { "replace", 0, 0, 'r' }, { "command", OPTF_ARGREQ, 0, 'c' }, { "fetch", 0, 0, 'f' }, { "timeout", OPTF_ARGREQ, 0, 't' }, @@ -1276,7 +1281,7 @@ int main(int argc, char *argv[]) { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "hVuqvCPs:c:ft:idl", opts, 0, 0, 0); + int i = mdwopt(argc, argv, "hVuqvCPs:rc:ft:idl", opts, 0, 0, 0); if (i < 0) break; @@ -1320,6 +1325,9 @@ int main(int argc, char *argv[]) case 's': path = optarg; break; + case 'r': + flags |= F_REPLACE; + break; case 't': if ((timeout = pixserv_timeout(optarg)) == 0) die(1, "bad timeout `%s'", optarg);