X-Git-Url: https://git.librecmc.org/?p=oweals%2Fucert.git;a=blobdiff_plain;f=usign-exec.c;h=21a24c2c7bf5a3031b1292aca12c11fc78b3a95b;hp=d25f9b651e16e41dafc62ae792045bc094d80e27;hb=54be4d654308175cd95b16fb38e0260220db242b;hpb=ca6d1ffd41f20fdaea517dd74492bbf2f635c859 diff --git a/usign-exec.c b/usign-exec.c index d25f9b6..21a24c2 100644 --- a/usign-exec.c +++ b/usign-exec.c @@ -1,61 +1,60 @@ +/* + * wrapper functions around the usign executable + * Copyright (C) 2018 Daniel Golle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 + * as published by the Free Software Foundation + * + * This program 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 General Public License for more details. + */ + #include +#include #include #include #include #include "usign.h" -int usign_v(const char *msgfile, const char *pubkeyfile, - const char *pubkeydir, const char *sigfile, bool quiet) { - pid_t pid; - int status; - const char *usign_argv[16] = {0}; - unsigned int usign_argc = 0; - - usign_argv[usign_argc++] = "/usr/bin/usign"; - usign_argv[usign_argc++] = "-V"; - usign_argv[usign_argc++] = "-m"; - usign_argv[usign_argc++] = msgfile; - - if (quiet) - usign_argv[usign_argc++] = "-q"; - - if (pubkeyfile) { - usign_argv[usign_argc++] = "-p"; - usign_argv[usign_argc++] = pubkeyfile; - } - - if (pubkeydir) { - usign_argv[usign_argc++] = "-P"; - usign_argv[usign_argc++] = pubkeydir; - } - - pid = fork(); - switch (pid) { - case -1: - return -1; - - case 0: - if (execv(usign_argv[0], usign_argv)) - return -1; - - break; - - default: - waitpid(pid, &status, 0); - return WEXITSTATUS(status); - } - - return -1; +#ifdef UCERT_HOST_BUILD +#define USIGN_EXEC "usign" +#else +#define USIGN_EXEC "/usr/bin/usign" +#endif + +/* + * check for revoker deadlink in pubkeydir + * return true if a revoker exists, false otherwise + */ +int _usign_key_is_revoked(const char *fingerprint, const char *pubkeydir) { + char tml[64] = {0}; + char rfname[256] = {0}; + + snprintf(rfname, sizeof(rfname)-1, "%s/%s", pubkeydir, fingerprint); + if (readlink(rfname, tml, sizeof(tml)) > 0 && + !strcmp(tml, ".revoked.")) { + return true; + }; + + return false; } +#ifdef UCERT_FULL +/* + * call usign -S ... + * return WEXITSTATUS or -1 if fork or execv fails + */ int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) { pid_t pid; int status; const char *usign_argv[16] = {0}; unsigned int usign_argc = 0; - usign_argv[usign_argc++] = "/usr/bin/usign"; + usign_argv[usign_argc++] = USIGN_EXEC; usign_argv[usign_argc++] = "-S"; usign_argv[usign_argc++] = "-m"; usign_argv[usign_argc++] = msgfile; @@ -73,7 +72,13 @@ int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bo return -1; case 0: - if (execv(usign_argv[0], usign_argv)) + if ( +#ifdef UCERT_HOST_BUILD + execvp(usign_argv[0], usign_argv) +#else + execv(usign_argv[0], usign_argv) +#endif + ) return -1; break; @@ -85,7 +90,16 @@ int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bo return -1; } +#else +int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) { + return -1; +}; +#endif +/* + * call usign -F ... and set fingerprint returned + * return WEXITSTATUS or -1 if fork or execv fails + */ static int usign_f(char *fingerprint, const char *pubkeyfile, const char *seckeyfile, const char *sigfile) { int fds[2]; pid_t pid; @@ -96,7 +110,7 @@ static int usign_f(char *fingerprint, const char *pubkeyfile, const char *seckey if (pipe(fds)) return -1; - usign_argv[usign_argc++] = "/usr/bin/usign"; + usign_argv[usign_argc++] = USIGN_EXEC; usign_argv[usign_argc++] = "-F"; if (pubkeyfile) { @@ -120,8 +134,6 @@ static int usign_f(char *fingerprint, const char *pubkeyfile, const char *seckey return -1; case 0: - uloop_done(); - dup2(fds[1], 1); close(0); @@ -129,34 +141,126 @@ static int usign_f(char *fingerprint, const char *pubkeyfile, const char *seckey close(fds[0]); close(fds[1]); - if (execv(usign_argv[0], usign_argv)) + if ( +#ifdef UCERT_HOST_BUILD + execvp(usign_argv[0], usign_argv) +#else + execv(usign_argv[0], usign_argv) +#endif + ) return -1; break; default: waitpid(pid, &status, 0); + status = WEXITSTATUS(status); if (fingerprint && !WEXITSTATUS(status)) { - memset(fingerprint, 0, 16); - read(fds[0], fingerprint, 16); + memset(fingerprint, 0, 17); + read(fds[0], fingerprint, 17); + if (fingerprint[16] != '\n') + status = -1; + fingerprint[16] = '\0'; + } close(fds[0]); close(fds[1]); - return WEXITSTATUS(status); + return status; } return -1; } +/* + * call usign -F -p ... + */ int usign_f_pubkey(char *fingerprint, const char *pubkeyfile) { return usign_f(fingerprint, pubkeyfile, NULL, NULL); } +/* + * call usign -F -s ... + */ int usign_f_seckey(char *fingerprint, const char *seckeyfile) { return usign_f(fingerprint, NULL, seckeyfile, NULL); } +/* + * call usign -F -x ... + */ int usign_f_sig(char *fingerprint, const char *sigfile) { return usign_f(fingerprint, NULL, NULL, sigfile); } + + +/* + * call usign -V ... + * return WEXITSTATUS or -1 if fork or execv fails + */ +int usign_v(const char *msgfile, const char *pubkeyfile, + const char *pubkeydir, const char *sigfile, bool quiet) { + pid_t pid; + int status; + const char *usign_argv[16] = {0}; + unsigned int usign_argc = 0; + char fingerprint[17]; + + if (usign_f_sig(fingerprint, sigfile)) { + if (!quiet) + fprintf(stdout, "cannot get signing key fingerprint\n"); + return 1; + } + + if (pubkeydir && _usign_key_is_revoked(fingerprint, pubkeydir)) { + if (!quiet) + fprintf(stdout, "key %s has been revoked!\n", fingerprint); + return 1; + } + usign_argv[usign_argc++] = USIGN_EXEC; + usign_argv[usign_argc++] = "-V"; + usign_argv[usign_argc++] = "-m"; + usign_argv[usign_argc++] = msgfile; + + if (quiet) + usign_argv[usign_argc++] = "-q"; + + if (pubkeyfile) { + usign_argv[usign_argc++] = "-p"; + usign_argv[usign_argc++] = pubkeyfile; + } + + if (pubkeydir) { + usign_argv[usign_argc++] = "-P"; + usign_argv[usign_argc++] = pubkeydir; + } + + if (sigfile) { + usign_argv[usign_argc++] = "-x"; + usign_argv[usign_argc++] = sigfile; + } + + pid = fork(); + switch (pid) { + case -1: + return -1; + + case 0: + if ( +#ifdef UCERT_HOST_BUILD + execvp(usign_argv[0], usign_argv) +#else + execv(usign_argv[0], usign_argv) +#endif + ) + return -1; + + break; + + default: + waitpid(pid, &status, 0); + return WEXITSTATUS(status); + } + + return -1; +}