debian/changelog: Prepare for next minor version.
[catacomb] / progs / pixie.c
index d964c0f..f827c20 100644 (file)
@@ -57,6 +57,7 @@
 #include <mLib/alloc.h>
 #include <mLib/dstr.h>
 #include <mLib/fdflags.h>
+#include <mLib/macros.h>
 #include <mLib/mdwopt.h>
 #include <mLib/quis.h>
 #include <mLib/report.h>
@@ -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");
@@ -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);