summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>1999-09-27 21:40:05 +0000
committerMarc Espie <espie@cvs.openbsd.org>1999-09-27 21:40:05 +0000
commit15cdb0079bec35779f3740a53e32a70eeb9c4184 (patch)
tree8c276193079b4c538549eb322b751044c55f1cf3
parentcff7f5ea4e4e751582a53fe2574a39b52923ddd8 (diff)
Stand-alone package signer.
Requires pgp for now, though the general scheme is generic.
-rw-r--r--usr.sbin/pkg_install/sign/INSTALL21
-rw-r--r--usr.sbin/pkg_install/sign/MANIFEST14
-rw-r--r--usr.sbin/pkg_install/sign/Makefile20
-rw-r--r--usr.sbin/pkg_install/sign/Makefile.bsd-wrapper20
-rw-r--r--usr.sbin/pkg_install/sign/README21
-rw-r--r--usr.sbin/pkg_install/sign/check.c206
-rw-r--r--usr.sbin/pkg_install/sign/common.c88
-rw-r--r--usr.sbin/pkg_install/sign/extern.h50
-rw-r--r--usr.sbin/pkg_install/sign/gzip.c136
-rw-r--r--usr.sbin/pkg_install/sign/gzip.h63
-rw-r--r--usr.sbin/pkg_install/sign/main.c144
-rw-r--r--usr.sbin/pkg_install/sign/pgp.h7
-rw-r--r--usr.sbin/pkg_install/sign/pkg_sign.1138
-rw-r--r--usr.sbin/pkg_install/sign/sign.c202
-rw-r--r--usr.sbin/pkg_install/sign/simple_check.c72
-rw-r--r--usr.sbin/pkg_install/sign/stand.h16
16 files changed, 1218 insertions, 0 deletions
diff --git a/usr.sbin/pkg_install/sign/INSTALL b/usr.sbin/pkg_install/sign/INSTALL
new file mode 100644
index 00000000000..1577272fc8c
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/INSTALL
@@ -0,0 +1,21 @@
+These are just bare bones installation instructions.
+
+Normally, `make' should be enough to build these tools.
+A simpler version can be built by using `make check_sign'
+(does not depend on the existence of getpass())
+
+You should define PGP and GZCAT in the Makefile if the defaults
+(/usr/local/bin/pgp and /usr/bin/gzcat) don't apply.
+
+There is no install target, just copy pkg_sign and/or check_sign where
+you want, along with the manpage.
+
+You need to install pgp by yourself. This should be pgp 2.63,
+as these tools won't work with pgp5.
+
+A standard Unix environment is assumed. Common functions such
+as getopt() or strdup() should be obtained from another free software
+package such as libiberty if not available on your platform.
+
+These tools won't work on Unix-lookalike that don't provide fork()
+or popen() without some extensive modifications.
diff --git a/usr.sbin/pkg_install/sign/MANIFEST b/usr.sbin/pkg_install/sign/MANIFEST
new file mode 100644
index 00000000000..a02d940c0d6
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/MANIFEST
@@ -0,0 +1,14 @@
+INSTALL
+Makefile
+MANIFEST
+README
+check.c
+common.c
+extern.h
+gzip.c
+gzip.h
+main.c
+pgp.h
+pkg_sign.1
+sign.c
+stand.h
diff --git a/usr.sbin/pkg_install/sign/Makefile b/usr.sbin/pkg_install/sign/Makefile
new file mode 100644
index 00000000000..b3adf4d287d
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/Makefile
@@ -0,0 +1,20 @@
+# define PGP to be the path to pgp (default: /usr/local/bin/pgp)
+# and GZCAT to be the path to gzcat (default: /usr/bin/gzcat)
+
+# Use the check_sign target if your system can't handle pipes or getpass
+all: pkg_sign
+
+OBJS=main.o sign.o check.o gzip.o common.o
+OBJS2=varmain.o check.o gzip.o common.o
+
+pkg_sign: $(OBJS)
+ ${CC} ${CFLAGS} -o $@ $(OBJS)
+
+check_sign: $(OBJS2)
+ ${CC} ${CFLAGS} -o $@ $(OBJS2)
+
+varmain.o: main.c
+ ${CC} ${CFLAGS} -DCHECKER_ONLY -o varmain.o -c main.c
+
+clean:
+ rm *.o
diff --git a/usr.sbin/pkg_install/sign/Makefile.bsd-wrapper b/usr.sbin/pkg_install/sign/Makefile.bsd-wrapper
new file mode 100644
index 00000000000..b8b64ec6335
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/Makefile.bsd-wrapper
@@ -0,0 +1,20 @@
+# $OpenBSD: Makefile.bsd-wrapper,v 1.1 1999/09/27 21:40:03 espie Exp $
+
+PROG= pkg_sign
+SRCS= main.c sign.c
+
+.if exists(${.CURDIR}/../lib/${__objdir})
+LDADD+= -L${.CURDIR}/../lib/${__objdir} -linstall
+DPADD+= ${.CURDIR}/../lib/${__objdir}/libinstall.a
+.else
+LDADD+= -L${.CURDIR}/../lib -linstall
+DPADD+= ${.CURDIR}/../lib/libinstall.a
+.endif
+
+LINKS= ${BINDIR}/pkg_sign ${BINDIR}/check_sign
+MANLINKS=pkg_sign.1 check_sign.1
+
+CLEANFILES=varmain.o
+
+.include <bsd.prog.mk>
+
diff --git a/usr.sbin/pkg_install/sign/README b/usr.sbin/pkg_install/sign/README
new file mode 100644
index 00000000000..57a6656c8a4
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/README
@@ -0,0 +1,21 @@
+To sign packages in a transparent way:
+gzip files can handle an EXTRA_FIELD at the beginning that
+stores anything we wish.
+
+So it's just a question to choose a format for the signature, and to
+embed it there.
+
+We put a specific cookie `S, i, g, P, G, P, length'
+at the beginning of the extra-field, so that eventually we can put
+more information in that field (like several signatures),
+followed by the signature output by PGP.
+
+The checker just needs to extract the signature, pass it off to PGP,
+followed by the uncompressed archive.
+
+* Signed archives that just look like normal .tar.gz files,
+* Possibility to grab the files off the net and extract stuff/verify
+signatures on the fly (just need to wedge the checker as an intermediate
+pipe)
+* Pretty simple, small portable code to be able to check signatures
+everywhere (the signer itself needs getpass and corresponding functionality)
diff --git a/usr.sbin/pkg_install/sign/check.c b/usr.sbin/pkg_install/sign/check.c
new file mode 100644
index 00000000000..1799b438ff3
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/check.c
@@ -0,0 +1,206 @@
+/* $OpenBSD: check.c,v 1.1 1999/09/27 21:40:03 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.
+ */
+
+/* Simple code for a stand-alone package checker */
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <errno.h>
+#include "stand.h"
+#include "pgp.h"
+#include "gzip.h"
+#include "extern.h"
+
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
+typedef /*@observer@*/char *pchar;
+
+static void
+gzcat(fdin, fdout, envp)
+ int fdin, fdout;
+ char *envp[];
+{
+ pchar argv[2];
+
+ argv[0] = GZCAT;
+ argv[1] = NULL;
+ if (dup2(fdin, fileno(stdin)) == -1 ||
+ dup2(fdout, fileno(stdout)) == -1 ||
+ execve(GZCAT, argv, envp) == -1)
+ exit(errno);
+}
+
+static void
+pgpcheck(fd, userid, envp)
+ int fd;
+ const char *userid;
+ char *envp[];
+{
+ int fdnull;
+ pchar argv[6];
+
+ argv[0] = PGP;
+ argv[1] = "+batchmode";
+ argv[2] = "-f";
+
+ if (userid) {
+ argv[3] = "-u";
+ argv[4] = (char *)userid;
+ argv[5] = NULL;
+ } else
+ argv[3] = NULL;
+
+ fdnull = open(_PATH_DEVNULL, O_RDWR);
+ if (fdnull == -1 ||
+ dup2(fd, fileno(stdin)) == -1 ||
+ dup2(fdnull, fileno(stdout)) == -1 ||
+ execve(PGP, argv, envp) == -1)
+ exit(errno);
+}
+
+static int
+reap(pid)
+ pid_t pid;
+{
+ pid_t result;
+ int pstat;
+
+ do {
+ result = waitpid(pid, &pstat, 0);
+ } while (result == -1 && errno == EINTR);
+ return result == -1 ? -1 : pstat;
+}
+
+int
+check_signature(file, userid, envp, filename)
+ /*@dependent@*/FILE *file;
+ const char *userid;
+ char *envp[];
+ /*@observer@*/const char *filename;
+{
+ FILE *file2;
+ int c;
+ char sign[SIGNSIZE];
+ struct mygzip_header h;
+ int status;
+ int togzcat[2], topgpcheck[2];
+ pid_t pgpid, gzcatid;
+
+ status = read_header_and_diagnose(file, &h, sign, filename);
+ if (status != 1)
+ return PKG_UNSIGNED;
+
+ if (pipe(topgpcheck) == -1) {
+ fprintf(stderr, "Error creating pipe\n");
+ return PKG_SIGERROR;
+ }
+ switch(pgpid = fork()) {
+ case -1:
+ fprintf(stderr, "Error creating pgp process\n");
+ return PKG_SIGERROR;
+ case 0:
+ if (close(topgpcheck[1]) == -1)
+ exit(errno);
+ pgpcheck(topgpcheck[0], userid, envp);
+ /*@notreached@*/
+ break;
+ default:
+ (void)close(topgpcheck[0]);
+ break;
+ }
+ if (write(topgpcheck[1], sign, sizeof(sign)) != sizeof(sign)) {
+ fprintf(stderr, "Error writing to pgp pipe\n");
+ (void)close(topgpcheck[1]);
+ (void)reap(pgpid);
+ return PKG_SIGERROR;
+ }
+ if (pipe(togzcat) == -1) {
+ fprintf(stderr, "Error creating pipe\n");
+ (void)close(topgpcheck[1]);
+ (void)reap(pgpid);
+ return PKG_SIGERROR;
+ }
+ switch (gzcatid=fork()) {
+ case -1:
+ fprintf(stderr, "Error creating gzcat process\n");
+ (void)reap(pgpid);
+ return PKG_SIGERROR;
+ case 0:
+ if (close(togzcat[1]) == -1)
+ exit(errno);
+ gzcat(togzcat[0], topgpcheck[1], envp);
+ /*@notreached@*/
+ break;
+ default:
+ (void)close(topgpcheck[1]);
+ (void)close(togzcat[0]);
+ }
+
+ file2 = fdopen(togzcat[1], "w");
+ if (file2 == NULL) {
+ (void)close(togzcat[1]);
+ (void)reap(gzcatid);
+ (void)reap(pgpid);
+ fprintf(stderr, "Error turning fd into FILE *\n");
+ return PKG_SIGERROR;
+ }
+
+ if (gzip_write_header(file2, &h, NULL) != 1) {
+ (void)fclose(file2);
+ (void)reap(pgpid);
+ (void)reap(gzcatid);
+ fprintf(stderr, "Error writing gzip header\n");
+ return PKG_SIGERROR;
+ }
+ while((c = fgetc(file)) != EOF) {
+ if (fputc(c, file2) == EOF) {
+ fprintf(stderr, "Problem writing to zcat\n");
+ (void)fclose(file2);
+ (void)reap(pgpid);
+ (void)reap(gzcatid);
+ return PKG_SIGERROR;
+ }
+
+ }
+ status = PKG_GOODSIG;
+ if (fclose(file2) != 0)
+ status = PKG_SIGERROR;
+ if (reap(gzcatid) != 0)
+ status = PKG_SIGERROR;
+ if (reap(pgpid) != 0)
+ status = PKG_BADSIG;
+ return status;
+}
diff --git a/usr.sbin/pkg_install/sign/common.c b/usr.sbin/pkg_install/sign/common.c
new file mode 100644
index 00000000000..adc58b69565
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/common.c
@@ -0,0 +1,88 @@
+/* $OpenBSD: common.c,v 1.1 1999/09/27 21:40:03 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 <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include "stand.h"
+#include "gzip.h"
+#include "pgp.h"
+#include "extern.h"
+
+/* Ensure consistent diagnostics */
+int
+read_header_and_diagnose(file, h, sign, filename)
+ FILE *file;
+ struct mygzip_header *h;
+ char sign[];
+ const char *filename;
+{
+ switch(gzip_read_header(file, h, sign)) {
+ case GZIP_SIGNED:
+ if (sign == NULL) {
+ fprintf(stderr, "File %s is already signed\n", filename);
+ return 0;
+ } else
+ return 1;
+ case GZIP_UNSIGNED:
+ if (sign != NULL) {
+ fprintf(stderr, "File %s is not a signed gzip file\n", filename);
+ return 0;
+ } else
+ return 1;
+ case GZIP_NOT_GZIP:
+ fprintf(stderr, "File %s is not a gzip file\n", filename);
+ return 0;
+ case GZIP_NOT_PGPSIGNED:
+ fprintf(stderr, "File %s contains an unknown extension\n", filename);
+ return 0;
+ default:
+ /* this should not happen */
+ abort();
+ }
+}
+
+/* Check command existence */
+int check_helpers()
+{
+ struct stat sbuf;
+
+ if (stat(GZCAT, &sbuf) == -1) {
+ fprintf(stderr, "Tool %s does not exist\n", GZCAT);
+ return 0;
+ }
+ if (stat(PGP, &sbuf) == -1) {
+ fprintf(stderr, "Tool %s does not exist\n", PGP);
+ return 0;
+ }
+ return 1;
+}
+
+
diff --git a/usr.sbin/pkg_install/sign/extern.h b/usr.sbin/pkg_install/sign/extern.h
new file mode 100644
index 00000000000..7cc86239a6b
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/extern.h
@@ -0,0 +1,50 @@
+/* $OpenBSD: extern.h,v 1.1 1999/09/27 21:40:03 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.
+ */
+
+struct mygzip_header;
+
+extern int read_header_and_diagnose
+ __P((FILE *file, /*@out@*/struct mygzip_header *h, /*@null@*/char sign[], const char *filename));
+extern int check_helpers __P((void));
+
+extern int sign
+ __P((/*@observer@*/const char *filename, /*@null@*/const char *userid, char *envp[]));
+
+extern int check_signature
+ __P((/*@dependent@*/FILE *file, /*@null@*/const char *userid, char *envp[], /*@observer@*/const char *filename));
+extern void handle_passphrase __P((void));
+
+#define PKG_BADSIG 0
+#define PKG_GOODSIG 1
+#define PKG_UNSIGNED 2
+#define PKG_SIGNED 4
+#define PKG_SIGERROR 8
+
+extern int simple_check __P((const char *pkg_name));
diff --git a/usr.sbin/pkg_install/sign/gzip.c b/usr.sbin/pkg_install/sign/gzip.c
new file mode 100644
index 00000000000..63f45ecf9f6
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/gzip.c
@@ -0,0 +1,136 @@
+/* $OpenBSD: gzip.c,v 1.1 1999/09/27 21:40:04 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 <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include "stand.h"
+#include "gzip.h"
+#include "pgp.h"
+
+/* For now, signatures follow a hardcoded format
+ (endianess was chosen to conform to gzip header format)
+ */
+static char tagsign[] =
+ {'S', 'i', 'g', 'P', 'G', 'P',
+ (char)(SIGNSIZE /256), (char)(SIGNSIZE & 255) };
+
+/* retrieve a gzip header, including PGP signatures */
+int
+gzip_read_header(f, h, sign)
+ FILE *f;
+ struct mygzip_header *h;
+ char sign[];
+{
+ {
+ int c, d;
+
+ c = fgetc(f);
+ d = fgetc(f);
+ if ((unsigned char)c != (unsigned char)GZIP_MAGIC0
+ || (unsigned char)d != (unsigned char)GZIP_MAGIC1)
+ return GZIP_NOT_GZIP;
+ }
+ {
+ int method, flags;
+
+ method = fgetc(f);
+ flags = fgetc(f);
+
+ if (method == EOF || flags == EOF || fread(h->stamp, 1, 6, f) != 6)
+ return GZIP_NOT_GZIP;
+ h->method = (char)method;
+ h->flags = (char)flags;
+ }
+
+ if ((h->flags & CONTINUATION) != 0)
+ if (fread(h->part, 1, 2, f) != 2)
+ return GZIP_NOT_GZIP;
+ if ((h->flags & EXTRA_FIELD) != 0) {
+ char match[sizeof(tagsign)];
+ unsigned int len;
+ int c;
+
+ c = fgetc(f);
+ if (c == EOF)
+ return GZIP_NOT_PGPSIGNED;
+ len = (unsigned)c;
+ c = fgetc(f);
+ if (c == EOF)
+ return GZIP_NOT_PGPSIGNED;
+ len |= ((unsigned) c) << 8;
+ if (len != sizeof(tagsign) + SIGNSIZE)
+ return GZIP_NOT_PGPSIGNED;
+ if (fread(match, 1, sizeof(match), f) != sizeof(match) ||
+ memcmp(match, tagsign, sizeof(match)) != 0)
+ return GZIP_NOT_PGPSIGNED;
+ if (sign != NULL) {
+ if (fread(sign, 1, SIGNSIZE, f) == SIGNSIZE)
+ return GZIP_SIGNED;
+ else
+ return GZIP_NOT_PGPSIGNED;
+ } else
+ return GZIP_UNSIGNED;
+ } else
+ return GZIP_UNSIGNED;
+}
+
+int
+gzip_write_header(f, h, sign)
+ FILE *f;
+ const struct mygzip_header *h;
+ const char sign[];
+{
+ char flags;
+
+ flags = h->flags;
+
+ if (sign != NULL)
+ flags |= EXTRA_FIELD;
+ else
+ flags &= ~EXTRA_FIELD;
+ if (fputc(GZIP_MAGIC0, f) == EOF ||
+ fputc(GZIP_MAGIC1, f) == EOF ||
+ fputc(h->method, f) == EOF ||
+ fputc(flags, f) == EOF ||
+ fwrite(h->stamp, 1, 6, f) != 6)
+ return 0;
+ if ((h->flags & CONTINUATION) != 0)
+ if (fwrite(h->part, 1, 2, f) != 2)
+ return 0;
+ if (sign != NULL) {
+ unsigned short len = sizeof(tagsign) + SIGNSIZE;
+ if (fputc(len & 255, f) == EOF ||
+ fputc(len/256, f) == EOF ||
+ fwrite(tagsign, 1, sizeof(tagsign), f) != sizeof(tagsign) ||
+ fwrite(sign, 1, SIGNSIZE, f) != SIGNSIZE)
+ return 0;
+ }
+ return 1;
+}
diff --git a/usr.sbin/pkg_install/sign/gzip.h b/usr.sbin/pkg_install/sign/gzip.h
new file mode 100644
index 00000000000..13db86fa40d
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/gzip.h
@@ -0,0 +1,63 @@
+/* $OpenBSD: gzip.h,v 1.1 1999/09/27 21:40:04 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.
+ */
+
+#define GZIP_MAGIC0 '\037'
+#define GZIP_MAGIC1 '\213'
+/* flags values */
+#define CONTINUATION 0x02
+#define EXTRA_FIELD 0x04
+
+/* meaningful fields in a gzip header, see gzip proper for details.
+ This structure should not be fiddled with outside of gzip_read_header
+ and gzip_write_header
+ */
+struct mygzip_header
+ {
+ char method;
+ char flags;
+ char stamp[6];
+ char part[2];
+ };
+
+/* returns from gzip_read_header */
+#define GZIP_UNSIGNED 0 /* gzip file, no signature */
+#define GZIP_SIGNED 1 /* gzip file, signature parsed ok */
+#define GZIP_NOT_GZIP 2 /* not a proper gzip file */
+#define GZIP_NOT_PGPSIGNED 3 /* gzip file, unknown extension */
+extern int gzip_read_header
+ __P((FILE *f, /*@out@*/struct mygzip_header *h, /*@null@*/char sign[]));
+/* gzip_write_header returns 1 for success */
+extern int gzip_write_header
+ __P((FILE *f, const struct mygzip_header *h, /*@null@*/const char sign[]));
+
+#ifndef GZCAT
+#define GZCAT "/usr/bin/gzcat"
+#endif
+
diff --git a/usr.sbin/pkg_install/sign/main.c b/usr.sbin/pkg_install/sign/main.c
new file mode 100644
index 00000000000..2792f1ad816
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/main.c
@@ -0,0 +1,144 @@
+/* $OpenBSD: main.c,v 1.1 1999/09/27 21:40:04 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 <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "stand.h"
+#include "gzip.h"
+#include "extern.h"
+
+#ifdef __OpenBSD__
+extern char *__progname;
+#define argv0 __progname
+#else
+static char *argv0;
+#endif
+
+#define NM_SIGN "pkg_sign"
+
+static void
+usage()
+{
+ fprintf(stderr, "usage: %s [-sc] [-u userid] pkg1 ...\n", argv0);
+ exit(EXIT_FAILURE);
+}
+
+#define SIGN 0
+#define CHECK 1
+
+static int
+check(filename, userid, envp)
+ /*@observer@*/const char *filename;
+ /*@null@*/const char *userid;
+ char *envp[];
+{
+ int result;
+ FILE *file;
+
+ if (strcmp(filename, "-") == 0)
+ return check_signature(stdin, userid, envp, "stdin");
+ file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Can't open %s\n", filename);
+ return 0;
+ }
+ result = check_signature(file, userid, envp, filename);
+ if (fclose(file) == 0)
+ return result;
+ else
+ return 0;
+}
+
+int
+main(argc, argv, envp)
+ int argc;
+ char *argv[];
+ char *envp[];
+{
+ int success = 1;
+ int ch;
+ char *userid = NULL;
+ int mode;
+ int i;
+
+#ifdef CHECKER_ONLY
+ mode = CHECK;
+#else
+#ifndef __OpenBSD__
+ if ((argv0 = strrchr(argv[0], '/')) != NULL)
+ argv0++;
+ else
+ argv0 = argv[0];
+#endif
+ if (strcmp(argv0, NM_SIGN) == 0)
+ mode = SIGN;
+ else
+ mode = CHECK;
+#endif
+
+ if (check_helpers() == 0)
+ exit(EXIT_FAILURE);
+ while ((ch = getopt(argc, argv, "u:sc")) != -1) {
+ switch(ch) {
+ case 'u':
+ userid = strdup(optarg);
+ break;
+#ifndef CHECKER_ONLY
+ case 's':
+ mode = SIGN;
+ break;
+#endif
+ case 'c':
+ mode = CHECK;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 0) {
+ if (mode == CHECK)
+ success &= check("-", userid, envp);
+ else
+ usage();
+ }
+
+#ifndef CHECKER_ONLY
+ if (mode == SIGN)
+ handle_passphrase();
+#endif
+ for (i = 0; i < argc; i++)
+ success &= (mode == SIGN ? sign : check)(argv[i], userid, envp);
+ exit(success == 1 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff --git a/usr.sbin/pkg_install/sign/pgp.h b/usr.sbin/pkg_install/sign/pgp.h
new file mode 100644
index 00000000000..cf91474e1c9
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/pgp.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: pgp.h,v 1.1 1999/09/27 21:40:04 espie Exp $ */
+/* Hardcode size of a pgp signature */
+#define SIGNSIZE 168
+
+#ifndef PGP
+#define PGP "/usr/local/bin/pgp"
+#endif
diff --git a/usr.sbin/pkg_install/sign/pkg_sign.1 b/usr.sbin/pkg_install/sign/pkg_sign.1
new file mode 100644
index 00000000000..2f46b9ca094
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/pkg_sign.1
@@ -0,0 +1,138 @@
+.\" $OpenBSD: pkg_sign.1,v 1.1 1999/09/27 21:40:04 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.
+
+.Dd September 24, 1999
+.Dt PKG_SIGN 1
+.Os
+.Sh NAME
+.Nm pkg_sign ,
+.Nm check_sign
+.Nd handle package signatures
+.Sh SYNOPSIS
+.Nm pkg_sign
+.Op Fl sc
+.Op Fl u Ar userid
+.Op Ar
+.Nm pkg_check
+.Op Fl sc
+.Op Fl u Ar userid
+.Op Ar
+.Sh DESCRIPTION
+.Nm pkg_sign
+embeds a cryptographic signature (currently PGP) within a gzip file
+.Ar file .
+It will always prompt you for a passphrase to unlock your private pgp key,
+even if you don't use a passphrase (which is a bad idea, anyway).
+.Nm pkg_check
+cheks that cryptographic signature.
+.Pp
+This uses a feature of the gzip format, namely that one can set a flag
+.Dv EXTRA_FIELD
+in the gzip header and store extra data between the gzip header and the
+compressed file proper.
+The OpenBSD signing scheme uses `SigPGP\\0\\xa8'
+as a magic number for its signature (this marker is conveniently 8 bytes
+long, and the `\\0\\xa8' is the length of the pgp signature proper).
+.Pp
+Options
+.Fl s
+and
+.Fl c
+can be used to force package signing or signature checking mode.
+.Pp
+The
+.Ar userid
+to use to sign the package or verify the signature can be forced with
+.Fl u .
+.Pp
+If
+.Ar file
+is a single dash
+.Pq Sq \&-
+or absent,
+.Nm check_sign
+reads from the standard input.
+.Sh RESULTS
+.Nm pkg_sign
+and
+.Nm pkg_check
+return with an exit code > 0 if anything went wrong for any
+.Ar file .
+For
+.Nm pkg_check ,
+this usually indicates that the package is not signed, or that the
+signature is forged.
+.Sh DIAGNOSTICS
+.Bl -diag
+.It "File %s is already signed"
+There is a signature embedded within the gzip file already.
+.Nm pkg_sign
+currently does not handle multiple signatures.
+.It "File %s is not a signed gzip file"
+This is an unsigned package.
+.It "File %s is not a gzip file"
+The program couldn't find a proper gzip header.
+.It "File %s contains an unknown extension"
+The extended area of the gzip file has been used for an unknown purpose.
+.El
+.Sh BUGS
+.Xr pgp 1
+is an ill-designed program, which is hard to interface with.
+For instance, the `separate signing scheme' it pretends to offer is
+useless, as it can't be used with pipes, so that
+.Nm pgp_sign
+needs to kludge it by knowing the length of a pgp signature, and invoking
+pgp in `seamless' signature mode, without compression of the main file,
+and just retrieving the signature.
+.Pp
+The checking scheme is little less convoluted, namely we rebuild the file
+that pgp expects on the fly.
+.Pp
+Paths to
+.Nm pgp
+and
+.Nm gzcat
+are hard-coded to avoid tampering and hinder flexibility.
+.Sh FILES
+.Bl -tag -width "/usr/local/bin/pgp" -compact
+.It Pa file.sign
+Temporary file built by
+.Nm pkg_sign
+from
+.Ar file .
+.It Pa /usr/local/bin/pgp
+Default path to
+.Xr pgp 1 .
+.It Pa /usr/bin/gzcat
+Default path to
+.Xr gzcat 1 .
+.El
+.Sh SEE ALSO
+.Xr pgp 1 ,
+.Xr pkg_add 1 ,
+.Xr gzip 1
diff --git a/usr.sbin/pkg_install/sign/sign.c b/usr.sbin/pkg_install/sign/sign.c
new file mode 100644
index 00000000000..6dc8ba20b5b
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/sign.c
@@ -0,0 +1,202 @@
+/* $OpenBSD: sign.c,v 1.1 1999/09/27 21:40:04 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 <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+#include <pwd.h>
+#include "stand.h"
+#include "pgp.h"
+#include "gzip.h"
+#include "extern.h"
+
+#define SIGN_TEMPLATE "%s %s | %s +batchmode +compress=off -f -s"
+#define SIGN2_TEMPLATE "%s %s | %s +batchmode +compress=off -f -u %s -s"
+#define COPY_TEMPLATE "%s.sign"
+
+static int
+retrieve_signature(filename, sign, userid)
+ const char *filename;
+ char sign[];
+ const char *userid;
+{
+ char *buffer;
+ FILE *cmd;
+
+ if (userid) {
+ buffer = malloc(strlen(GZCAT) + strlen(filename) +
+ strlen(PGP) + strlen(userid) + sizeof(SIGN2_TEMPLATE));
+ if (!buffer)
+ return 0;
+ sprintf(buffer, SIGN2_TEMPLATE, GZCAT, filename, PGP, userid);
+ } else {
+ buffer = malloc(strlen(GZCAT) + strlen(filename) +
+ strlen(PGP) + sizeof(SIGN_TEMPLATE));
+ if (!buffer)
+ return 0;
+ sprintf(buffer, SIGN_TEMPLATE, GZCAT, filename, PGP);
+ }
+ cmd = popen(buffer, "r");
+ free(buffer);
+ if (!cmd)
+ return 0;
+ if (fread(sign, 1, SIGNSIZE, cmd) != SIGNSIZE)
+ return 0;
+#ifdef DEBUG_PGP
+ printf("%d\n", pclose(cmd));
+#endif
+ return 1;
+}
+
+static int
+embed_signature_FILE(orig, dest, sign, filename)
+ /*@temp@*/FILE *orig;
+ /*@temp@*/FILE *dest;
+ const char sign[];
+ const char *filename;
+{
+ struct mygzip_header h;
+ int c;
+
+ if (read_header_and_diagnose(orig, &h, NULL, filename) == 0)
+ return 0;
+
+ if (gzip_write_header(dest, &h, sign) == 0)
+ return 0;
+ while ((c = fgetc(orig)) != EOF && fputc(c, dest) != EOF)
+ ;
+ if (ferror(dest) != 0)
+ return 0;
+ return 1;
+}
+
+static int
+embed_signature(filename, copy, sign)
+ const char *filename;
+ const char *copy;
+ const char sign[];
+{
+ FILE *orig, *dest;
+ int success;
+
+ success = 0;
+ orig= fopen(filename, "r");
+ if (orig) {
+ dest = fopen(copy, "w");
+ if (dest) {
+ success = embed_signature_FILE(orig, dest, sign, filename);
+ if (fclose(dest) != 0)
+ success = 0;
+ }
+ if (fclose(orig) != 0)
+ success = 0;
+ }
+ return success;
+}
+
+int
+sign(filename, userid, envp)
+ const char *filename;
+ const char *userid;
+ /*@unused@*/char *envp[] __attribute__((unused));
+{
+ char sign[SIGNSIZE];
+ char *copy;
+ int result;
+
+ if (retrieve_signature(filename, sign, userid) == 0) {
+ fprintf(stderr, "Problem signing %s\n", filename);
+ return 0;
+ }
+ copy = malloc(strlen(filename)+sizeof(COPY_TEMPLATE));
+ if (copy == NULL) {
+ fprintf(stderr, "Can't allocate memory\n");
+ return 0;
+ }
+ sprintf(copy, COPY_TEMPLATE, filename);
+ result = embed_signature(filename, copy, sign);
+ if (result == 0) {
+ fprintf(stderr, "Can't embed signature in %s\n", filename);
+ } else if (unlink(filename) != 0) {
+ fprintf(stderr, "Can't unlink original %s\n", filename);
+ result = 0;
+ } else if (rename(copy, filename) != 0) {
+ fprintf(stderr, "Can't rename new file %s\n", copy);
+ result = 0;
+ }
+ free(copy);
+ return result;
+}
+
+void
+handle_passphrase()
+{
+ pid_t pid;
+ int fd[2];
+ char *p;
+
+ /* Retrieve the pgp passphrase */
+ p = getpass("Enter passphrase:");
+
+ /* somewhat kludgy code to get the passphrase to pgp, see
+ pgp documentation for the gore
+ */
+ if (pipe(fd) != 0) {
+ perror("pkg_sign");
+ exit(EXIT_FAILURE);
+ }
+ switch(pid = fork()) {
+ case -1:
+ perror("pkg_sign");
+ exit(EXIT_FAILURE);
+ case 0:
+ {
+ (void)close(fd[0]);
+ /* the child fills the pipe with copies of the passphrase.
+ Expect violent death when father exits.
+ */
+ for(;;) {
+ char c = '\n';
+ (void)write(fd[1], p, strlen(p));
+ (void)write(fd[1], &c, 1);
+ }
+ }
+ default:
+ {
+ char buf[10];
+
+ (void)close(fd[1]);
+ (void)sprintf(buf, "%d", fd[0]);
+ (void)setenv("PGPPASSFD", buf, 1);
+ }
+ }
+}
+
diff --git a/usr.sbin/pkg_install/sign/simple_check.c b/usr.sbin/pkg_install/sign/simple_check.c
new file mode 100644
index 00000000000..4156042701f
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/simple_check.c
@@ -0,0 +1,72 @@
+/* $OpenBSD: simple_check.c,v 1.1 1999/09/27 21:40:04 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 <stdio.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include "extern.h"
+
+#define CHECKER_STRING "/usr/bin/fgrep \"`cd %s && /bin/sha1 %s`\" /var/db/pkg/SHA1"
+#define CHECKER2_STRING "/usr/bin/fgrep \\(%s\\) /var/db/pkg/SHA1"
+
+int
+simple_check(pkg_name)
+ const char *pkg_name;
+{
+ int result;
+ char *buffer;
+ char *dir, *file;
+
+ dir = dirname(pkg_name);
+ file = basename(pkg_name);
+ if (dir == NULL || file == NULL)
+ return PKG_SIGERROR;
+
+ buffer = malloc(sizeof(CHECKER_STRING)+strlen(dir)+strlen(file));
+ if (!buffer)
+ return PKG_SIGERROR;
+ sprintf(buffer, CHECKER_STRING, dir, file);
+ result = system(buffer);
+ free(buffer);
+ if (result == 0)
+ return PKG_GOODSIG;
+ buffer = malloc(sizeof(CHECKER2_STRING)+strlen(file));
+ if (!buffer)
+ return PKG_SIGERROR;
+ sprintf(buffer, CHECKER2_STRING, file);
+ result = system(buffer);
+ free(buffer);
+ if (result == 0)
+ return PKG_BADSIG;
+ else
+ return PKG_UNSIGNED;
+}
+
+
diff --git a/usr.sbin/pkg_install/sign/stand.h b/usr.sbin/pkg_install/sign/stand.h
new file mode 100644
index 00000000000..f90d9e53477
--- /dev/null
+++ b/usr.sbin/pkg_install/sign/stand.h
@@ -0,0 +1,16 @@
+/* $OpenBSD: stand.h,v 1.1 1999/09/27 21:40:04 espie Exp $ */
+
+/* provided to cater for BSD idiosyncrasies */
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(x) x
+#else
+#define __P(x) ()
+#endif
+#endif
+
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif