1    | #include <stdio.h>
2    | #include <stdlib.h>
3    | #include <string.h>
4    | #include <sys/wait.h>
5    | #include <unistd.h>
6    | #include <errno.h>
7    | #include <sys/types.h>
8    | #include <sys/stat.h>
9    | #include <fcntl.h>
10   | #include <time.h>
11   | 
12   | #include "gpg.h"
13   | 
14   | extern int sd1[2];
15   | extern int spawn_job (char *path, char *argv[], 
16   | 		      int *in_fd, int *out_fd, int *err_fd);
17   | extern time_t nfslock(char *path, char *namelock, int max_age, int notify);
18   | extern int nfsunlock(char *path, char *namelock, int max_age, time_t birth);
19   | 
20   | /* ------------------------------------------------- */
21   | void GetFingerPrint(struct ImportKeyObject *iKO) {
22   |   
23   |   char *strArgs[9];
24   |   char Args0[100] ;
25   |   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
26   |   int gpg_pid;
27   |   int gpg_in_fd, out_fd, err_fd;
28   |   int status;
29   |   char txt[LINE_LENGTH];
30   |   char *keyStr;
31   |   FILE *mystdin;
32   |   int childRC;
33   | 
34   |   strcpy(Args0, "--no-tty");
35   |   strcpy(Args1, "--no-secmem-warning");
36   |   strcpy(Args2, "--keyring");
37   |   strcpy(Args3, iKO->keyRing);
38   |   strcpy(Args4, "--fingerprint");
39   |   sprintf(Args5, "%08lX", iKO->keyID);
40   | 
41   |   strArgs[0] = Args0;  
42   |   strArgs[1] = Args1;  
43   |   strArgs[2] = Args2;  
44   |   strArgs[3] = Args3;  
45   |   strArgs[4] = Args4;  
46   |   strArgs[5] = Args5;
47   |   strArgs[6] = (char *)0;
48   | 
49   |   gpg_in_fd = INPUT_FD;
50   |   out_fd = OUTPUT_FD;
51   |   err_fd = ERROR_FD;
52   | 
53   |   /* create lock file filenames for NFS */
54   | 
55   |   if ( ( gpg_pid = spawn_job ("gpg", strArgs,
56   | 			      &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
57   |     printf ("could not spawn gpg");
58   |     exit(1);
59   |   }
60   |   
61   |   if (waitpid (gpg_pid, &status, 0) < 0)
62   |     {
63   |       fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
64   |       printf ("could not reap gpg process");
65   |       exit(1);
66   |     }
67   | 
68   |   if (WIFEXITED(status) == 0)
69   |     {
70   |       fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
71   |       printf ("gpg failure");
72   |       exit(1);
73   |     } else {
74   |       /* Child exited, checking return code */
75   |       childRC = (status & 0xF00) >> 8;
76   |       if (childRC == 1) {
77   | 	fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
78   | 	printf ("gpg failure\n");
79   | 	exit(1);
80   |       }
81   |     }
82   | 
83   | 
84   |   mystdin = fdopen(0, "r");
85   |   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
86   |     {
87   |       /* printf ( "GPG output : %s\n", txt );      */
88   | 
89   |       if ((keyStr = strstr(txt, "Key fingerprint =")) != NULL) {
90   | 	strcpy(iKO->fingerPrint, keyStr + 18);
91   | 	iKO->fingerPrint[strlen(iKO->fingerPrint)-1] = 0;
92   |       }
93   | 
94   |       if ((keyStr = strstr(txt, "key")) != NULL) {
95   | 	 keyStr += 4;
96   | 	 sscanf(keyStr, "%8X\n", &iKO->keyID); 
97   |       } 
98   |     }
99   | 
100  |   if (sd1[0] != 0)  close ( sd1[0] ); 
101  | }
102  | 
103  | /* ------------------------------------------------- */
104  | 
105  | void ParseInputFile(struct VerifySignObject *vSO) {
106  |   FILE *fin, *fout;
107  |   char txt[LINE_LENGTH];
108  |   char keyRing[LINE_LENGTH];
109  |   char outputPath[LINE_LENGTH];
110  |   const char PGP_prefix[] = "-----BEGIN PGP ";
111  |   const char PGP_suffix[] = "-----END PGP ";
112  |   int found_prefix = 0, nMsgs = 0, outFileOpened = 0, clearTextBlock = 1;
113  |   char foutName[100];
114  |   struct VerifySignObject *vSOList = vSO;
115  |   
116  |   strcpy(keyRing, vSO->keyRing);
117  |   strcpy(outputPath, vSO->outputPath);
118  | 
119  |   if (!strcmp(vSOList->iSigFilename, "")) {
120  |     if ((fin = fopen(vSOList->iDocSigFilename, "r")) != NULL) { 
121  | 
122  |       while (fgets (txt, LINE_LENGTH - 1, fin) != NULL) {
123  | 
124  |       /* Looking for PGP prefix */
125  | 	if ((strstr(txt, PGP_prefix) != NULL) && !found_prefix) {
126  | 	  clearTextBlock = 0;
127  | 	  found_prefix = 1;
128  | 	  /* remember to delete those files */
129  | 	  sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs);
130  | 	  if ((fout = fopen(foutName, "w")) == NULL ) {
131  | 	    vSOList->isValid = vSO_NO_OUT_FILES;
132  | 	    return;
133  | 	  }
134  | 	  outFileOpened = 1;
135  | 	  vSOList->next = malloc(sizeof(struct VerifySignObject));
136  | 	  vSOList = vSOList->next;
137  | 	  strcpy(vSOList->iDocSigFilename, foutName);
138  | 	  strcpy(vSOList->keyRing, keyRing);
139  | 	  strcpy(vSOList->outputPath, outputPath);
140  | 	  vSOList->next = NULL;
141  | 	} else
142  | 	  if ((strstr(txt, PGP_suffix) != NULL ) && found_prefix) {
143  | 	    found_prefix = 0;
144  | 	    clearTextBlock = 1;
145  | 	    fputs(txt, fout);
146  | 	    fclose(fout);
147  | 	    outFileOpened = 0;
148  | 	    nMsgs++;
149  | 	  } else 
150  | 	    if (clearTextBlock && !outFileOpened) {
151  | 	      sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs);
152  | 	      if ((fout = fopen(foutName, "w")) == NULL ) {
153  | 		vSOList->isValid = vSO_NO_OUT_FILES;
154  | 		return;
155  | 	      }
156  | 	      outFileOpened = 1;
157  | 	      vSOList->next = malloc(sizeof(struct VerifySignObject));
158  | 	      vSOList = vSOList->next;
159  | 	      strcpy(vSOList->iDocSigFilename, foutName);
160  | 	      strcpy(vSOList->keyRing, "");
161  | 	      strcpy(vSOList->outputPath, outputPath);
162  | 	      vSOList->next = NULL;
163  | 	    }
164  | 	if (outFileOpened) {
165  | 	  fputs(txt, fout);
166  | 	}       
167  |       }
168  |       if (outFileOpened) {
169  | 	fclose(fout);
170  |       }
171  |       fclose(fin);
172  |     } else {
173  |       vSOList->isValid = vSO_NO_IN_FILES;
174  |     }
175  |   }
176  | }
177  | 
178  | /* ------------------------------------------------- */
179  | 
180  | void VerifySignature(struct VerifySignObject *vSO) {
181  |   char *strArgs[10];
182  |   char Args0[100];
183  |   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100],
184  |     Args6[100], Args7[100];
185  |   int gpg_pid;
186  |   int gpg_in_fd, out_fd, err_fd;
187  |   int status;
188  |   static int nMsgs = 0;
189  |   char txt[LINE_LENGTH];
190  |   char *keyStr;
191  |   struct VerifySignObject *pvSO = vSO->next;
192  |   int childRC;
193  | 
194  |   while (pvSO != NULL) {
195  |     nMsgs++;
196  |     /* Copy the incoming object on the internal global object */
197  |     /* memmove( &verifySignObj, pvSO, sizeof(struct VerifySignObject) ); */
198  | 
199  |     sprintf(pvSO->oStream, "%s/PAtmp.%ld.%ld.%d", pvSO->outputPath, 
200  | 	    labs(gethostid()), getpid(), nMsgs);
201  | 
202  |     strcpy(Args0, "--no-secmem-warning");
203  |     strcpy(Args1, "--keyring");
204  |     strcpy(Args2, pvSO->keyRing);
205  |     strcpy(Args3, "-o");
206  |     strcpy(Args4, pvSO->oStream);
207  |     strcpy(Args5, "-d");
208  |     if (!strcmp(pvSO->iSigFilename, "")) {
209  |       strcpy(Args6, pvSO->iDocSigFilename);
210  |       strArgs[6] = Args6;
211  |       strArgs[7] = (char *)0;
212  |     } else {
213  |       strcpy(Args6, pvSO->iSigFilename);
214  |       strcpy(Args7, pvSO->iDocSigFilename);
215  |       strArgs[6] = Args6;
216  |       strArgs[7] = Args7;
217  |       strArgs[8] = (char *)0;
218  |     }
219  | 
220  |     strArgs[0] = Args0;
221  |     strArgs[1] = Args1;  
222  |     strArgs[2] = Args2;  
223  |     strArgs[3] = Args3;
224  |     strArgs[4] = Args4;
225  |     strArgs[5] = Args5;
226  |   
227  |     gpg_in_fd = INPUT_FD;
228  |     out_fd = OUTPUT_FD;
229  |     err_fd = ERROR_FD;
230  |     if ( ( gpg_pid = spawn_job ("gpg", strArgs,
231  | 				&gpg_in_fd, &out_fd, &err_fd) ) < 0 )
232  |       {
233  | 	printf ("could not spawn gpg");
234  | 	exit(1);
235  |       }
236  |   
237  |     if (waitpid (gpg_pid, &status, 0) < 0)
238  |       {
239  | 	fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
240  | 	printf ("could not reap gpg process");
241  | 	exit(1);
242  |       }
243  |     if (WIFEXITED(status) == 0)
244  |       {
245  | 	fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
246  | 	printf ("gpg failure\n");
247  | 	exit(1);
248  |       } else {
249  | 	/* Child exited, checking return code */
250  | 	childRC = (status & 0xF00) >> 8;
251  | 	if (childRC == 1) {
252  | 	  fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
253  | 	  printf ("gpg failure\n");
254  | 	  exit(1);
255  | 	}
256  |       }
257  | 
258  | 
259  |     /* Parsing gpg output */
260  |     pvSO->isValid = vSO_KO;
261  |     while (fgets (txt, LINE_LENGTH - 1, stdin) != NULL)
262  |       {
263  | 	/* 	printf ( "GPG output : %s\n", txt );   */
264  | 	if (strstr(txt, "Good signature") != NULL)
265  | 	  pvSO->isValid = vSO_IS_VALID;
266  | 
267  | 	if (strstr(txt, "CRC error") != NULL)
268  | 	  pvSO->isValid = vSO_CRC_ERROR;
269  | 
270  | 	if (strstr(txt, "public key not found") != NULL)
271  | 	  pvSO->isValid = vSO_NO_PUBLIC_KEY;
272  | 
273  | 	if (strstr(txt, "no valid OpenPGP data found") != NULL)
274  | 	  pvSO->isValid = vSO_NO_OPENPGP_DATA;
275  | 
276  | 	if ((keyStr = strstr(txt, "key ID")) != NULL) {
277  | 	  keyStr += 7;
278  | 	  sscanf(keyStr, "%8X\n", &pvSO->keyID);
279  | 	}
280  |       }
281  |     
282  |     unlink(pvSO->iDocSigFilename);
283  |     pvSO = pvSO->next;
284  |   }
285  |   if (sd1[0] != 0)  close ( sd1[0] ); 
286  | }
287  | 
288  | /* ------------------------------------------------- */
289  | 
290  | void PA_VerifySignature(struct VerifySignObject *vSO) {
291  |   
292  |   /* split input file if there are multiple signed messages */
293  |   ParseInputFile( vSO );
294  | 
295  |   /* Verify each single PGP mesg */
296  |   VerifySignature( vSO );
297  | 
298  | }
299  | 
300  | /* ------------------------------------------------- */
301  | 
302  | void PA_Decrypt(struct ReadCryptedObject *rDO) {
303  |   
304  |   char *strArgs[9];
305  |   char clearTextExtension[4] = ".gpg";
306  |   char Args0[100];
307  |   char Args1[100];
308  |   char Args2[100];
309  |   char Args3[100];
310  |   char Args4[100];
311  |   char Args5[100];
312  |   char Args6[100];
313  |   int gpg_pid;
314  |   int gpg_in_fd, out_fd, err_fd;
315  |   int status;
316  |   char txt[LINE_LENGTH];
317  |   int childRC;
318  | 
319  |   strcpy(Args0, "--no-tty");
320  |   strcpy(Args1, "--no-secmem-warning");
321  |   strcpy(Args2, "--keyring");
322  |   strcpy(Args3, rDO->keyRing);
323  |   strcpy(Args4, "--output");
324  |   strcpy(Args5, strcat(rDO->iFilename, clearTextExtension));
325  |   strcpy(Args6, rDO->iFilename);
326  |   
327  |   strArgs[0] = Args0;
328  |   strArgs[1] = Args1;  
329  |   strArgs[2] = Args2;  
330  |   strArgs[3] = Args3;  
331  |   strArgs[4] = Args4;  
332  |   strArgs[5] = Args5;  
333  |   strArgs[6] = Args6;  
334  |   strArgs[7] = (char *) 0;   
335  | 
336  |   gpg_in_fd = INPUT_FD;
337  |   out_fd = OUTPUT_FD;
338  |   err_fd = ERROR_FD;
339  |   if ( ( gpg_pid = spawn_job ("gpg", strArgs,
340  | 			      &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
341  |     {
342  |       printf ("could not spawn gpg");
343  |       exit(1);
344  |     }
345  |   
346  |   if (waitpid (gpg_pid, &status, 0) < 0)
347  |     {
348  |       fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
349  |       printf ("could not reap gpg process");
350  |       exit(1);
351  |     }
352  |   if (WIFEXITED(status) == 0)
353  |     {
354  |       fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
355  |       printf ("gpg failure");
356  |       exit(1);
357  |     } else {
358  |       /* Child exited, checking return code */
359  |       childRC = (status & 0xF00) >> 8;
360  |       if (childRC == 1) {
361  | 	fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
362  | 	printf ("gpg failure\n");
363  | 	exit(1);
364  |       }
365  |     }
366  | 
367  | 
368  |   /* Parsing gpg output */
369  |   while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL)
370  |     {
371  |       
372  |     }
373  |   
374  |   if (sd1[0] != 0)  close ( sd1[0] ); 
375  | }
376  | 
377  | 
378  | /* ------------------------------------------------- */
379  | 
380  | void PA_ImportKey(struct ImportKeyObject *iKO) {
381  |   
382  |   char *strArgs[9];
383  |   char Args0[100];
384  |   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
385  |   int gpg_pid;
386  |   int gpg_in_fd, out_fd, err_fd;
387  |   int status;
388  |   char txt[LINE_LENGTH];
389  |   char *keyStr, *pos;
390  |   const char lockFilename[] = ".PAlock";
391  |   char keyRingLockFile[1000], keyRingPath[1000];
392  |   time_t lockBirthDate;
393  |   FILE *mystdin;
394  |   int childRC;
395  | 
396  |   iKO->rc = iKO_GENERALFAILURE;
397  | 
398  |   strcpy(Args0, "--no-tty");
399  |   strcpy(Args1, "--no-secmem-warning");
400  |   strcpy(Args2, "--keyring");
401  |   strcpy(Args3, iKO->keyRing);
402  |   strcpy(Args4, "--import");
403  |   strcpy(Args5, iKO->iFilename);
404  | 
405  |   strArgs[0] = Args0;  
406  |   strArgs[1] = Args1;  
407  |   strArgs[2] = Args2;  
408  |   strArgs[3] = Args3;  
409  |   strArgs[4] = Args4;  
410  |   strArgs[5] = Args5;
411  |   strArgs[6] = (char *)0;
412  | 
413  |   gpg_in_fd = INPUT_FD;
414  |   out_fd = OUTPUT_FD;
415  |   err_fd = ERROR_FD;
416  | 
417  |   /* create lock file filenames for NFS */
418  | 
419  |   strcpy(keyRingLockFile, iKO->keyRing);
420  |   if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
421  |     strcpy(pos + 1, lockFilename);
422  |     strcpy(keyRingPath, keyRingLockFile);
423  |     keyRingPath[pos - keyRingLockFile] = 0;
424  |   } else {
425  |     strcpy(keyRingLockFile, lockFilename);
426  |     strcpy(keyRingPath, "");
427  |   }
428  |   
429  |   lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
430  | 
431  |   if ( ( gpg_pid = spawn_job ("gpg", strArgs,
432  | 			      &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
433  |     printf ("could not spawn gpg");
434  |     exit(1);
435  |   }
436  |   
437  |   if (waitpid (gpg_pid, &status, 0) < 0)
438  |     {
439  |       fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
440  |       nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
441  |       printf ("could not reap gpg process");
442  |       exit(1);
443  |     }
444  | 
445  |   nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
446  | 
447  |   if (WIFEXITED(status) == 0)
448  |     {
449  |       fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
450  |       printf ("gpg failure");
451  |     } else {
452  |       /* Child exited, checking return code */
453  |       childRC = (status & 0xF00) >> 8;
454  |       if (childRC == 1) {
455  | 	fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
456  | 	printf ("gpg failure\n");
457  | 	exit(1);
458  |       }
459  |     }
460  | 
461  | 
462  |   /* Parsing gpg output */
463  |   /*   while (read(0, txt, 1000) != 0)
464  |        fprintf(stderr, "child read %s\n", txt); */
465  | 
466  |   mystdin = fdopen(0, "r");
467  |   iKO->rc = iKO_GENERALFAILURE;
468  |   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
469  |     {
470  |       /*          printf ( "GPG output : %s\n", txt );      */
471  | 
472  |       if ((keyStr = strstr(txt, "imported")) != NULL) {
473  | 	iKO->rc = iKO_OK;
474  |       }
475  | 
476  |       if ((keyStr = strstr(txt, "CRC error")) != NULL) {
477  | 	iKO->rc = iKO_CRC_ERROR;
478  |       }
479  | 
480  |       if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) {
481  | 	iKO->rc = iKO_NO_OPENPGP_DATA;
482  |       }
483  | 
484  |       if (((keyStr = strstr(txt, "unchanged")) != NULL) || 
485  | 	  ((keyStr = strstr(txt, "not changed")) != NULL)) {
486  | 	iKO->rc = iKO_UNCHANGED;
487  |       }
488  | 
489  |       if ((keyStr = strstr(txt, "key")) != NULL) {
490  | 	 keyStr += 4;
491  | 	 sscanf(keyStr, "%8X\n", &iKO->keyID); 
492  |       } 
493  |     }
494  | 
495  |   if (sd1[0] != 0)  close ( sd1[0] ); 
496  | 
497  |   /* Get the finger print */
498  | 
499  |   GetFingerPrint(iKO);
500  | }
501  | 
502  | /* ------------------------------------------------- */
503  | 
504  | void GetKeyID(struct ImportKeyObject *iKO) {
505  |   
506  |   char *strArgs[9];
507  |   char Args0[100];
508  |   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
509  |   int gpg_pid;
510  |   int gpg_in_fd, out_fd, err_fd;
511  |   int status;
512  |   char txt[LINE_LENGTH];
513  |   char *keyStr, *pos;
514  |   const char lockFilename[] = ".PAlock";
515  |   char keyRingLockFile[1000], keyRingPath[1000];
516  |   time_t lockBirthDate;
517  |   FILE *mystdin;
518  |   int childRC;
519  | 
520  |   iKO->rc = iKO_GENERALFAILURE;
521  | 
522  |   strcpy(Args0, "--no-tty");
523  |   strcpy(Args1, "--no-secmem-warning");
524  |   strcpy(Args2, "--keyring");
525  |   strcpy(Args3, iKO->keyRing);
526  |   strcpy(Args4, "--import");
527  |   strcpy(Args5, iKO->iFilename);
528  | 
529  |   strArgs[0] = Args0;  
530  |   strArgs[1] = Args1;  
531  |   strArgs[2] = Args2;  
532  |   strArgs[3] = Args3;  
533  |   strArgs[4] = Args4;  
534  |   strArgs[5] = Args5;
535  |   strArgs[6] = (char *)0;
536  | 
537  |   gpg_in_fd = INPUT_FD;
538  |   out_fd = OUTPUT_FD;
539  |   err_fd = ERROR_FD;
540  | 
541  |   /* create lock file filenames for NFS */
542  | 
543  |   strcpy(keyRingLockFile, iKO->keyRing);
544  |   if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
545  |     strcpy(pos + 1, lockFilename);
546  |     strcpy(keyRingPath, keyRingLockFile);
547  |     keyRingPath[pos - keyRingLockFile] = 0;
548  |   } else {
549  |     strcpy(keyRingLockFile, lockFilename);
550  |     strcpy(keyRingPath, "");
551  |   }
552  |   
553  |   lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
554  | 
555  |   if ( ( gpg_pid = spawn_job ("gpg", strArgs,
556  | 			      &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
557  |     printf ("could not spawn gpg");
558  |     exit(1);
559  |   }
560  |   
561  |   if (waitpid (gpg_pid, &status, 0) < 0)
562  |     {
563  |       fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
564  |       printf ("could not reap gpg process");
565  |       nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
566  |       exit(1);
567  |     }
568  | 
569  |   nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
570  | 
571  |   if (WIFEXITED(status) == 0)
572  |     {
573  |       fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
574  |       printf ("gpg failure");
575  |       exit(1);
576  |     } else {
577  |       /* Child exited, checking return code */
578  |       childRC = (status & 0xF00) >> 8;
579  |       if (childRC == 1) {
580  | 	fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
581  | 	printf ("gpg failure\n");
582  | 	exit(1);
583  |       }
584  |     }
585  | 
586  | 
587  |   /* Parsing gpg output */
588  |   /*   while (read(0, txt, 1000) != 0)
589  |        fprintf(stderr, "child read %s\n", txt); */
590  | 
591  |   mystdin = fdopen(0, "r");
592  |   iKO->rc = iKO_GENERALFAILURE;
593  |   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
594  |     {
595  |       /*          printf ( "GPG output : %s\n", txt );      */
596  | 
597  |       if ((keyStr = strstr(txt, "imported")) != NULL) {
598  | 	iKO->rc = iKO_OK;
599  |       }
600  | 
601  |       if ((keyStr = strstr(txt, "CRC error")) != NULL) {
602  | 	iKO->rc = iKO_CRC_ERROR;
603  |       }
604  | 
605  |       if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) {
606  | 	iKO->rc = iKO_NO_OPENPGP_DATA;
607  |       }
608  | 
609  |       if (((keyStr = strstr(txt, "unchanged")) != NULL) || 
610  | 	  ((keyStr = strstr(txt, "not changed")) != NULL)) {
611  | 	iKO->rc = iKO_UNCHANGED;
612  |       }
613  | 
614  |       if ((keyStr = strstr(txt, "gpg: key ")) != NULL) {
615  | 	 keyStr += 9;
616  | 	 sscanf(keyStr, "%8X\n", &iKO->keyID); 
617  |       } 
618  |     }
619  | 
620  |   if (sd1[0] != 0)  close ( sd1[0] ); 
621  | 
622  | }
623  | 
624  | /* ------------------------------------------------- */
625  | 
626  | void PA_RemoveKey(struct ImportKeyObject *iKO) {
627  |   
628  |   char *strArgs[9];
629  |   char Args0[100]= "gpg";
630  |   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100], Args6[100], Args7[100];
631  |   int gpg_pid;
632  |   int gpg_in_fd, out_fd, err_fd;
633  |   int status;
634  |   char txt[LINE_LENGTH];
635  |   char *keyStr, *pos;
636  |   const char lockFilename[] = ".PAlock";
637  |   char keyRingLockFile[1000], keyRingPath[1000];
638  |   time_t lockBirthDate;
639  |   FILE *mystdin;
640  |   int childRC;
641  | 
642  |   iKO->rc = iKO_GENERALFAILURE;
643  | 
644  |   GetKeyID(iKO);   /* getting key-id */
645  | 
646  |   /*   printf("Key id = %08lX\n", iKO->keyID); */
647  | 
648  |   if ((iKO->rc == iKO_OK) || (iKO->rc == iKO_UNCHANGED)) {    
649  |     strcpy(Args1, "--batch");
650  |     strcpy(Args2, "--yes");
651  |     strcpy(Args3, "--no-secmem-warning");
652  |     strcpy(Args4, "--keyring");
653  |     strcpy(Args5, iKO->keyRing); 
654  |     strcpy(Args6, "--delete-key");
655  |     sprintf(Args7, "%08lX", iKO->keyID);
656  | 
657  |     strArgs[0] = Args0;  
658  |     strArgs[1] = Args1;  
659  |     strArgs[2] = Args2;  
660  |     strArgs[3] = Args3;  
661  |     strArgs[4] = Args4;  
662  |     strArgs[5] = Args5;
663  |     strArgs[6] = Args6;
664  |     strArgs[7] = Args7;
665  |     strArgs[8] = (char *)0;  
666  |   
667  | 
668  |     gpg_in_fd = INPUT_FD;
669  |     out_fd = OUTPUT_FD;
670  |     err_fd = ERROR_FD;
671  | 
672  |   /* create lock file filenames for NFS */
673  | 
674  |     strcpy(keyRingLockFile, iKO->keyRing);
675  |     if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
676  |       strcpy(pos + 1, lockFilename);
677  |       strcpy(keyRingPath, keyRingLockFile);
678  |       keyRingPath[pos - keyRingLockFile] = 0;
679  |     } else {
680  |       strcpy(keyRingLockFile, lockFilename);
681  |       strcpy(keyRingPath, "");
682  |     }
683  |   
684  |     lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
685  | 
686  |     if ( ( gpg_pid = spawn_job ("/usr/local/bin/gpg", strArgs,
687  | 				&gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
688  |       printf ("could not spawn gpg");
689  |       exit(1);
690  |     }
691  | 
692  |     /*    printf("Child pid = %d\n", gpg_pid); */
693  |   
694  |     if (waitpid (gpg_pid, &status, 0) < 0)
695  |       {
696  | 	fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
697  | 	printf ("could not reap gpg process");
698  | 	exit(1);
699  |       }
700  | 
701  |     nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
702  | 
703  |     if (WIFEXITED(status) == 0)
704  |       {
705  | 	fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
706  | 	printf ("gpg failure");
707  | 	exit(1);
708  |       }  else {
709  | 	/* Child exited, checking return code */
710  | 	childRC = (status & 0xF00) >> 8;
711  | 	if (childRC == 1) {
712  | 	  fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
713  | 	  printf ("gpg failure\n");
714  | 	  exit(1);
715  | 	}
716  |       }
717  | 
718  | 
719  |     mystdin = fdopen(0, "r");
720  |     iKO->rc = iKO_OK;
721  |     while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
722  |       {
723  | 	/* printf ( "GPG output : %s\n", txt );        */
724  | 
725  | 	if ((keyStr = strstr(txt, "delete key failed")) != NULL) {
726  | 	  iKO->rc = iKO_GENERALFAILURE;
727  | 	}
728  | 	if ((keyStr = strstr(txt, "there is a secret key for this public key")) != NULL) {
729  | 	  iKO->rc = iKO_SECRET_KEY_PRESENT;
730  | 	}
731  | 
732  |       }
733  | 
734  |     if (sd1[0] != 0)  close ( sd1[0] ); 
735  |   }
736  | }