Remove the rest of the __P macros in src/usr.sbin
[dragonfly.git] / usr.sbin / pkg_install / sign / pgp_sign.c
1 /* $OpenBSD: pgp_sign.c,v 1.1 1999/10/04 21:46:29 espie Exp $ */
2 /*-
3  * Copyright (c) 1999 Marc Espie.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Marc Espie for the OpenBSD
16  * Project.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS 
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
21  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
22  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $FreeBSD: src/usr.sbin/pkg_install/sign/pgp_sign.c,v 1.1.2.3 2002/08/20 06:35:08 obrien Exp $
31  * $DragonFly: src/usr.sbin/pkg_install/sign/Attic/pgp_sign.c,v 1.2 2003/06/17 04:29:59 dillon Exp $
32  */
33
34 #include <sys/types.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <stdio.h>
38 #include <errno.h>
39 #include <signal.h>
40 #include <pwd.h>
41 #include <assert.h>
42 #include "stand.h"
43 #include "pgp.h"
44 #include "gzip.h"
45 #include "extern.h"
46
47 static void 
48 pgpsign(fdin, fdout, userid, envp) 
49         int fdin, fdout;
50         const char *userid;
51         char *envp[];
52 {
53         pchar argv[10];
54         int argc = 0;
55
56         argv[argc++] = PGP;
57         argv[argc++] = "+batchmode";
58         argv[argc++] = "+compress=off";
59         argv[argc++] = "-f";
60         argv[argc++] = "-s";
61         argv[argc++] = "-zAthlon";
62
63         if (userid) {
64                 argv[argc++] = "-u";
65                 argv[argc++] = (char *)userid;
66         }
67         argv[argc++] = NULL;
68         assert(argc <= sizeof argv / sizeof(pchar));
69
70         if (dup2(fdin, fileno(stdin)) == -1 || 
71             dup2(fdout, fileno(stdout)) == -1 ||
72             execve(PGP, argv, envp)  == -1)
73                 exit(errno);
74 }
75
76 static struct signature *
77 new_pgpsignature(old)
78         struct signature *old;
79 {
80         struct signature *n;
81
82         n = malloc(sizeof(*n));
83         if (n != NULL) {
84                 n->data = malloc(MAXPGPSIGNSIZE);
85                 if (n->data == NULL) {
86                         free(n);
87                         return NULL;
88                 }
89                 n->length = 0;
90                 n->next = old;
91                 n->type = TAG_PGP;
92                 memcpy(n->tag, pgptag, sizeof pgptag);
93         }
94         return n;
95 }
96
97 int
98 retrieve_pgp_signature(filename, sign, userid, envp)
99         const char *filename; 
100         struct signature **sign;
101         const char *userid;
102         char *envp[];
103 {
104         int topgp[2], frompgp[2];
105         pid_t pgpid;
106         struct mygzip_header h;
107         int success;
108
109         FILE *orig, *dest, *signin;
110         struct signature *old;
111
112         orig = fopen(filename, "r");
113         if (orig == NULL)
114                 return 0;
115         if (gzip_read_header(orig, &h, &old) == GZIP_NOT_GZIP) {
116                 warnx("File %s is not a gzip file\n", filename);
117                 fclose(orig);
118                 return 0;
119         }
120
121         if (pipe(topgp) == -1) {
122                 fclose(orig);
123                 return 0;
124         }
125         if (pipe(frompgp) == -1) {
126                 fclose(orig);
127                 (void)close(topgp[0]);
128                 (void)close(topgp[1]);
129                 return 0;
130         }
131         switch(pgpid = fork()) {
132         case 0:
133                 (void)close(topgp[1]);
134                 (void)close(frompgp[0]);
135                 pgpsign(topgp[0], frompgp[1], userid, envp);
136                 /*NOT REACHED */
137         case -1:
138                 (void)close(topgp[0]);
139                 (void)close(topgp[1]);
140                 (void)close(frompgp[0]);
141                 (void)close(frompgp[1]);
142                 fclose(orig);
143                 return 0;
144         default:
145                 (void)close(topgp[0]);
146                 (void)close(frompgp[1]);
147         }
148
149         dest = fdopen(topgp[1], "w");
150         if (dest == NULL) {
151                 (void)close(topgp[1]);
152                 (void)close(frompgp[0]);
153                 (void)reap(pgpid);
154                 return 0;
155         }
156
157         success = 1;
158         if (gzip_write_header(dest, &h, old) == 0)
159                 success = 0;
160         else {
161                 int c;
162
163                 while ((c = fgetc(orig)) != EOF && fputc(c, dest) != EOF)
164                         ;
165                 if (ferror(dest))
166                         success = 0;
167         }
168         if (fclose(dest) != 0)
169                 success = 0;
170
171         if (fclose(orig) != 0)
172                 success = 0;
173
174         signin = fdopen(frompgp[0], "r");
175         if (signin == NULL) {
176                 (void)close(frompgp[0]);
177         } else {
178                 enum { NONE, FIRST, DONE, COPY} magic = NONE;
179                 int c;
180 #ifdef DEBUG_DUMP
181                 FILE *out = fopen("dump", "w");
182 #endif
183
184                 if ((*sign = new_pgpsignature(old)) == NULL) 
185                         success = 0;
186                 else {
187                         while ((c = fgetc(signin)) != EOF && magic != DONE && 
188                                 (*sign)->length < MAXPGPSIGNSIZE) {
189                                 switch(magic) {
190                                 case NONE:
191                                         (*sign)->data[(*sign)->length++] = c;
192                                         if ((unsigned char)c == (unsigned char)GZIP_MAGIC0)
193                                                 magic = FIRST;
194                                         break;
195                                 case FIRST:
196                                         (*sign)->data[(*sign)->length++] = c;
197                                         if ((unsigned char)c == (unsigned char)GZIP_MAGIC1)
198 #ifdef DEBUG_DUMP
199                                                 magic = COPY;
200 #else
201                                                 magic = DONE;
202 #endif
203                                         else if ((unsigned char)c != (unsigned char)GZIP_MAGIC0)
204                                                 magic = NONE;
205                                         break;
206                                 case DONE:
207                                 case COPY:
208                                         break;
209                                 }
210 #ifdef DEBUG_DUMP
211                                 fputc(c, out);
212 #endif
213                         }
214                         if ((*sign)->length == MAXPGPSIGNSIZE)
215                                 success = 0;
216                         (*sign)->length -= 2;
217                         sign_fill_tag(*sign);
218                 }
219                 fclose(signin);
220 #ifdef DEBUG_DUMP
221                 fclose(out);
222 #endif
223                 reap(pgpid);
224         }
225         return success;
226 }
227
228 void
229 handle_pgp_passphrase()
230 {
231         pid_t pid;
232         int fd[2];
233         char *p;
234
235 printf("Short-circuiting %s\n", __func__);
236 return;
237
238                 /* Retrieve the pgp passphrase */
239         p = getpass("Enter passphrase:");
240
241                 /*
242                  * Somewhat kludgy code to get the passphrase to pgp, see 
243                  * pgp documentation for the gore
244                  */
245         if (pipe(fd) != 0)      {
246                 perror("pkg_sign");
247                 exit(EXIT_FAILURE);
248         }
249         switch(pid = fork()) {
250         case -1:
251                 perror("pkg_sign");
252                 exit(EXIT_FAILURE);
253         case 0:
254                 {
255                         (void)close(fd[0]);
256                                 /*
257                                  * The child fills the pipe with copies of the passphrase.
258                                  * Expect violent death when father exits.
259                                  */
260                         printf("Child process %d stuffing passphrase in pipe:\n", getpid());
261                         for(;;) {
262                                 char c = '\n';
263                                 (void)write(fd[1], p, strlen(p));
264                                 (void)write(fd[1], &c, 1);
265                                 putchar('.'); fflush(stdout);
266                         }
267                 }
268         default:
269                 {
270                         char buf[10];
271
272                         sleep(1);
273                         (void)close(fd[1]);
274                         (void)sprintf(buf, "%d", fd[0]);
275                         (void)setenv("PGPPASSFD", buf, 1);
276                         printf("Parent process PGPPASSFD=%d.\n", fd[0]);
277                 }
278         }
279 }
280