/* $OpenBSD: pgp_check.c,v 1.3 2001/04/08 16:45:48 espie Exp $ */ /*- * Copyright (c) 1999 Marc Espie. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Marc Espie for the OpenBSD * Project. * * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "stand.h" #include "pgp.h" #include "gzip.h" #include "extern.h" #ifndef _PATH_DEVNULL #define _PATH_DEVNULL "/dev/null" #endif /* transform current process into pgp signature checker -u userid type == TAG_PGP); n = malloc(sizeof *n); { struct stat sbuf; if (stat(PGP, &sbuf) == -1) { pwarnx("%s does not exist", PGP); return NULL; } } if (n == NULL) { pwarnx("Can't allocate pgp_checker"); return NULL; } if (pipe(topgpcheck) == -1) { warn("Pgp checker pipe"); free(n); return NULL; } switch(n->id = fork()) { case -1: warn("Pgp checker process"); free(n); return NULL; case 0: if (close(topgpcheck[1]) == -1) exit(errno); pgpcheck(topgpcheck[0], userid, envp); /*@notreached@*/ break; default: (void)close(topgpcheck[0]); break; } n->fdout = topgpcheck[1]; /* so that subsequent fork() won't duplicate it inadvertently */ (void)fcntl(n->fdout, F_SETFD, FD_CLOEXEC); #ifdef DEBUG_DUMP n->out = fopen("compare", "w"); #endif n->status = PKG_GOODSIG; pgp_add(n, sign->data, sign->length); if (gzip_copy_header(h, sign->next, pgp_add, n) == 0) { pwarnx("Unexpected header in %s", filename); n->status = PKG_SIGERROR; } return n; } void pgp_add(arg, buffer, length) void *arg; const char *buffer; size_t length; { struct pgp_checker *n = arg; if (n->status == PKG_GOODSIG) { #ifdef DEBUG_DUMP fwrite(buffer, 1, length, n->out); #endif while (length > 0) { ssize_t l = write(n->fdout, buffer, length); if (l == -1) { n->status = PKG_SIGERROR; break; } length -= l; buffer += l; } } } int pgp_sign_ok(arg) void *arg; { struct pgp_checker *n = arg; int status = n->status; #ifdef DEBUG_DUMP fclose(n->out); #endif if (close(n->fdout) != 0) status = PKG_SIGERROR; if (reap(n->id) != 0) status = PKG_BADSIG; free(n); return status; }