modules/pa/gpg.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- GetFingerPrint
- VerifySignAndExplodeFile
- PA_VerifySignature
- PA_Decrypt
- PA_ImportKey
- GetKeyID
- PA_RemoveKey
- GetLineFromFile3
- GetLineFromFile2
- PA_ParseMessage
1 /***************************************
2 $Revision: 1.21 $
3
4 gpg.c - core of the PA module. Contains functions that are used
5 to check the PGP authentication in a message.
6
7 Status: COMPLETE, REVUED, TESTED
8
9 ******************/ /******************
10 Filename : gpg.c
11 Authors : filippo@ripe.net
12 OSs Tested : Solaris 7
13 ******************/ /******************
14 Copyright (c) 2000 RIPE NCC
15
16 All Rights Reserved
17
18 Permission to use, copy, modify, and distribute this software and its
19 documentation for any purpose and without fee is hereby granted,
20 provided that the above copyright notice appear in all copies and that
21 both that copyright notice and this permission notice appear in
22 supporting documentation, and that the name of the author not be
23 used in advertising or publicity pertaining to distribution of the
24 software without specific, written prior permission.
25
26 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
28 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
29 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
30 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 ***************************************/
33
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/wait.h>
40 #include <unistd.h>
41 #include <errno.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <time.h>
46 #include <signal.h>
47 #include <sys/time.h>
48 #include <sys/param.h>
49
50 #include "mm.h"
51 /*#include "misc.h"*/ /* isMIME functions need case insensitive string search()*/
52 #include "gpg.h"
53 #include "erroutines.h"
54
55 extern char EP_outputPrefix[FILENAME_LENGTH];
56 extern char EP_keyRing[FILENAME_LENGTH];
57 extern int EP_TreeHeight;
58 extern int EP_Node_ID;
59 extern int EP_Debug;
60
61 extern int sd1[2];
62 extern int spawn_job (char *path, char *argv[],
63 int *in_fd, int *out_fd, int *err_fd);
64 extern time_t nfslock(char *path, char *namelock, int max_age, int notify);
65 extern int nfsunlock(char *path, char *namelock, int max_age, time_t birth);
66
67
68 /* static int parseMailBlock_nMsg;
69 static int parseRecursionLevel; */
70
71 /* ------------------------------------------------- */
72
73 void GetFingerPrint(struct ImportKeyObject *iKO) {
/* [<][>][^][v][top][bottom][index][help] */
74
75 char *strArgs[9];
76 char Args0[100] ;
77 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
78 int gpg_pid;
79 int gpg_in_fd, out_fd, err_fd;
80 int status;
81 char txt[LINE_LENGTH];
82 char *keyStr;
83 FILE *mystdin;
84 int childRC;
85
86 strcpy(Args0, "--no-tty");
87 strcpy(Args1, "--no-secmem-warning");
88 strcpy(Args2, "--keyring");
89 strcpy(Args3, iKO->keyRing);
90 strcpy(Args4, "--fingerprint");
91 sprintf(Args5, "%08lX", iKO->keyID);
92
93 strArgs[0] = Args0;
94 strArgs[1] = Args1;
95 strArgs[2] = Args2;
96 strArgs[3] = Args3;
97 strArgs[4] = Args4;
98 strArgs[5] = Args5;
99 strArgs[6] = (char *)0;
100
101 gpg_in_fd = INPUT_FD;
102 out_fd = OUTPUT_FD;
103 err_fd = ERROR_FD;
104
105 /* create lock file filenames for NFS */
106
107 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
108 &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
109 printf ("could not spawn gpg");
110 exit(1);
111 }
112
113 if (waitpid (gpg_pid, &status, 0) < 0)
114 {
115 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
116 printf ("could not reap gpg process");
117 exit(1);
118 }
119
120 if (WIFEXITED(status) == 0)
121 {
122 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
123 printf ("gpg failure");
124 exit(1);
125 } else {
126 /* Child exited, checking return code */
127 childRC = (status & 0xF00) >> 8;
128 if (childRC == 1) {
129 fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
130 printf ("gpg failure\n");
131 exit(1);
132 }
133 }
134
135
136 mystdin = fdopen(0, "r");
137 while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
138 {
139 /* printf ( "GPG output : %s\n", txt ); */
140
141 if ((keyStr = strstr(txt, "Key fingerprint =")) != NULL) {
142 strcpy(iKO->fingerPrint, keyStr + 18);
143 iKO->fingerPrint[strlen(iKO->fingerPrint)-1] = 0;
144 }
145
146 if ((keyStr = strstr(txt, "key")) != NULL) {
147 keyStr += 4;
148 sscanf(keyStr, "%8X\n", &iKO->keyID);
149 }
150 }
151
152 if (sd1[0] != 0) close ( sd1[0] );
153 }
154
155 /* ------------------------------------------------- */
156
157 void VerifySignAndExplodeFile(EPNodePtr ptr) {
/* [<][>][^][v][top][bottom][index][help] */
158 char *strArgs[10];
159 char Args0[100];
160 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100],
161 Args6[100];
162 int gpg_pid;
163 int gpg_in_fd, out_fd, err_fd;
164 int status;
165 char txt[LINE_LENGTH];
166 /* char hostname[MAXHOSTNAMELEN]; */
167 char oFile[FILENAME_LENGTH];
168 char *keyStr;
169 /* int childRC; */
170
171 sprintf(oFile, "%s.%d.exp", ptr->file, ptr->nodeID);
172
173 strcpy(Args0, "--no-secmem-warning");
174 strcpy(Args1, "--keyring");
175 strcpy(Args2, EP_keyRing);
176 strcpy(Args3, "-o");
177 strcpy(Args4, oFile);
178 strcpy(Args5, "-d");
179 strcpy(Args6, ptr->file);
180 strArgs[6] = Args6;
181 strArgs[7] = (char *)0;
182
183 strArgs[0] = Args0;
184 strArgs[1] = Args1;
185 strArgs[2] = Args2;
186 strArgs[3] = Args3;
187 strArgs[4] = Args4;
188 strArgs[5] = Args5;
189
190 gpg_in_fd = INPUT_FD;
191 out_fd = OUTPUT_FD;
192 err_fd = ERROR_FD;
193 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
194 &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
195 {
196 printf ("could not spawn gpg");
197 exit(1);
198 }
199
200 if (waitpid (gpg_pid, &status, 0) < 0)
201 {
202 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
203 printf ("could not reap gpg process");
204 exit(1);
205 }
206 if (WIFEXITED(status) == 0)
207 {
208 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
209 printf ("gpg failure\n");
210 exit(1);
211 } else {
212 /* Child exited, checking return code */
213 /* childRC = (status & 0xF00) >> 8;
214 if (childRC == 1) {
215 fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
216 printf ("gpg failure\n");
217 exit(1);
218 } */
219 }
220
221
222 /* Parsing gpg output */
223 ptr->isValidPGPSignature = vS_KO;
224 while (fgets (txt, LINE_LENGTH - 1, stdin) != NULL)
225 {
226 /* printf ( "GPG output : %s\n", txt ); */
227 if (strstr(txt, "Good signature") != NULL)
228 ptr->isValidPGPSignature = vS_IS_VALID;
229
230 if (strstr(txt, "CRC error") != NULL)
231 ptr->isValidPGPSignature = vS_CRC_ERROR;
232
233 if (strstr(txt, "public key not found") != NULL)
234 ptr->isValidPGPSignature = vS_NO_PUBLIC_KEY;
235
236 if (strstr(txt, "no valid OpenPGP data found") != NULL)
237 ptr->isValidPGPSignature = vS_NO_OPENPGP_DATA;
238
239 if ((keyStr = strstr(txt, "key ID")) != NULL) {
240 keyStr += 7;
241 sscanf(keyStr, "%8X\n", &ptr->keyID);
242 }
243 }
244
245 unlink(ptr->file);
246 free(ptr->file);
247 ptr->file = strdup(oFile);
248 if (sd1[0] != 0) close ( sd1[0] );
249 }
250
251 /* ------------------------------------------------- */
252
253 void PA_VerifySignature(struct VerifySignObject *vSO) {
/* [<][>][^][v][top][bottom][index][help] */
254 char *strArgs[10];
255 char Args0[100];
256 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100],
257 Args6[100], Args7[100];
258 int gpg_pid;
259 int gpg_in_fd, out_fd, err_fd;
260 int status;
261 /* static int nMsgs = 0; */
262 char txt[LINE_LENGTH];
263 char *keyStr;
264 /* int childRC; */
265
266 vSO->type = vSO_Type_Signed;
267
268 strcpy(Args0, "--no-secmem-warning");
269 strcpy(Args1, "--keyring");
270 strcpy(Args2, vSO->keyRing);
271 strcpy(Args3, "-o");
272 if (!strcmp(vSO->iSigFilename, "")) {
273 strcpy(Args4, vSO->oStream);
274 strcpy(Args5, "-d");
275 strcpy(Args6, vSO->iDocSigFilename);
276 strArgs[6] = Args6;
277 strArgs[7] = (char *)0;
278 } else {
279 strcpy(Args5, "--verify");
280 strcpy(Args6, vSO->iSigFilename);
281 strcpy(Args7, vSO->iDocSigFilename);
282
283 strArgs[6] = Args6;
284 strArgs[7] = Args7;
285 strArgs[8] = (char *)0;
286 strcpy(vSO->oStream, vSO->iDocSigFilename);
287 }
288
289 strArgs[0] = Args0;
290 strArgs[1] = Args1;
291 strArgs[2] = Args2;
292 strArgs[3] = Args3;
293 strArgs[4] = Args4;
294 strArgs[5] = Args5;
295
296 gpg_in_fd = INPUT_FD;
297 out_fd = OUTPUT_FD;
298 err_fd = ERROR_FD;
299 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
300 &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
301 {
302 printf ("could not spawn gpg");
303 exit(1);
304 }
305
306 if (waitpid (gpg_pid, &status, 0) < 0)
307 {
308 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
309 printf ("could not reap gpg process");
310 exit(1);
311 }
312 if (WIFEXITED(status) == 0)
313 {
314 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
315 printf ("gpg failure\n");
316 exit(1);
317 } else {
318 /* Child exited, checking return code */
319 /* childRC = (status & 0xF00) >> 8;
320 if (childRC == 1) {
321 fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
322 printf ("gpg failure\n");
323 exit(1);
324 } */
325 }
326
327
328 /* Parsing gpg output */
329 vSO->isValid = vSO_KO;
330 while (fgets (txt, LINE_LENGTH - 1, stdin) != NULL)
331 {
332 /* printf ( "GPG output : %s\n", txt ); */
333 if (strstr(txt, "Good signature") != NULL)
334 vSO->isValid = vSO_IS_VALID;
335
336 if (strstr(txt, "CRC error") != NULL)
337 vSO->isValid = vSO_CRC_ERROR;
338
339 if (strstr(txt, "public key not found") != NULL)
340 vSO->isValid = vSO_NO_PUBLIC_KEY;
341
342 if (strstr(txt, "no valid OpenPGP data found") != NULL)
343 vSO->isValid = vSO_NO_OPENPGP_DATA;
344
345 if ((keyStr = strstr(txt, "key ID")) != NULL) {
346 keyStr += 7;
347 sscanf(keyStr, "%8X\n", &vSO->keyID);
348 }
349 }
350
351 if (sd1[0] != 0) close ( sd1[0] );
352 }
353
354 /* ------------------------------------------------- */
355 /* This functions is not used by PA/EP/MM
356 can be useful in the future .... FP */
357 void PA_Decrypt(struct ReadCryptedObject *rDO) {
/* [<][>][^][v][top][bottom][index][help] */
358
359 char *strArgs[9];
360 char clearTextExtension[4] = ".gpg";
361 char Args0[100];
362 char Args1[100];
363 char Args2[100];
364 char Args3[100];
365 char Args4[100];
366 char Args5[100];
367 char Args6[100];
368 int gpg_pid;
369 int gpg_in_fd, out_fd, err_fd;
370 int status;
371 char txt[LINE_LENGTH];
372 int childRC;
373
374 strcpy(Args0, "--no-tty");
375 strcpy(Args1, "--no-secmem-warning");
376 strcpy(Args2, "--keyring");
377 strcpy(Args3, rDO->keyRing);
378 strcpy(Args4, "--output");
379 strcpy(Args5, strcat(rDO->iFilename, clearTextExtension));
380 strcpy(Args6, rDO->iFilename);
381
382 strArgs[0] = Args0;
383 strArgs[1] = Args1;
384 strArgs[2] = Args2;
385 strArgs[3] = Args3;
386 strArgs[4] = Args4;
387 strArgs[5] = Args5;
388 strArgs[6] = Args6;
389 strArgs[7] = (char *) 0;
390
391 gpg_in_fd = INPUT_FD;
392 out_fd = OUTPUT_FD;
393 err_fd = ERROR_FD;
394 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
395 &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
396 {
397 printf ("could not spawn gpg");
398 exit(1);
399 }
400
401 if (waitpid (gpg_pid, &status, 0) < 0)
402 {
403 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
404 printf ("could not reap gpg process");
405 exit(1);
406 }
407 if (WIFEXITED(status) == 0)
408 {
409 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
410 printf ("gpg failure");
411 exit(1);
412 } else {
413 /* Child exited, checking return code */
414 childRC = (status & 0xF00) >> 8;
415 if (childRC == 1) {
416 fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
417 printf ("gpg failure\n");
418 exit(1);
419 }
420 }
421
422
423 /* Parsing gpg output */
424 while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL)
425 {
426
427 }
428
429 if (sd1[0] != 0) close ( sd1[0] );
430 }
431
432
433 /* ------------------------------------------------- */
434
435 void PA_ImportKey(struct ImportKeyObject *iKO) {
/* [<][>][^][v][top][bottom][index][help] */
436
437 char *strArgs[9];
438 char Args0[100];
439 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
440 int gpg_pid;
441 int gpg_in_fd, out_fd, err_fd;
442 int status;
443 char txt[LINE_LENGTH];
444 char *keyStr, *pos;
445 const char lockFilename[] = ".PAlock";
446 char keyRingLockFile[1000], keyRingPath[1000];
447 time_t lockBirthDate;
448 FILE *mystdin;
449 int childRC;
450
451 iKO->rc = iKO_GENERALFAILURE;
452
453 strcpy(Args0, "--no-tty");
454 strcpy(Args1, "--no-secmem-warning");
455 strcpy(Args2, "--keyring");
456 strcpy(Args3, iKO->keyRing);
457 strcpy(Args4, "--import");
458 strcpy(Args5, iKO->iFilename);
459
460 strArgs[0] = Args0;
461 strArgs[1] = Args1;
462 strArgs[2] = Args2;
463 strArgs[3] = Args3;
464 strArgs[4] = Args4;
465 strArgs[5] = Args5;
466 strArgs[6] = (char *)0;
467
468 gpg_in_fd = INPUT_FD;
469 out_fd = OUTPUT_FD;
470 err_fd = ERROR_FD;
471
472 /* create lock file filenames for NFS */
473
474 strcpy(keyRingLockFile, iKO->keyRing);
475 if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
476 strcpy(pos + 1, lockFilename);
477 strcpy(keyRingPath, keyRingLockFile);
478 keyRingPath[pos - keyRingLockFile] = 0;
479 } else {
480 strcpy(keyRingLockFile, lockFilename);
481 strcpy(keyRingPath, "");
482 }
483
484 lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
485
486 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
487 &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
488 printf ("could not spawn gpg");
489 exit(1);
490 }
491
492 if (waitpid (gpg_pid, &status, 0) < 0)
493 {
494 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
495 nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
496 printf ("could not reap gpg process");
497 exit(1);
498 }
499
500 nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
501
502 if (WIFEXITED(status) == 0)
503 {
504 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
505 printf ("gpg failure");
506 } else {
507 /* Child exited, checking return code */
508 childRC = (status & 0xF00) >> 8;
509 if (childRC == 1) {
510 fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
511 printf ("gpg failure\n");
512 exit(1);
513 }
514 }
515
516
517 /* Parsing gpg output */
518 /* while (read(0, txt, 1000) != 0)
519 fprintf(stderr, "child read %s\n", txt); */
520
521 mystdin = fdopen(0, "r");
522 iKO->rc = iKO_GENERALFAILURE;
523 while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
524 {
525 /* printf ( "GPG output : %s\n", txt ); */
526
527 if ((keyStr = strstr(txt, "imported")) != NULL) {
528 iKO->rc = iKO_OK;
529 }
530
531 if ((keyStr = strstr(txt, "CRC error")) != NULL) {
532 iKO->rc = iKO_CRC_ERROR;
533 }
534
535 if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) {
536 iKO->rc = iKO_NO_OPENPGP_DATA;
537 }
538
539 if (((keyStr = strstr(txt, "unchanged")) != NULL) ||
540 ((keyStr = strstr(txt, "not changed")) != NULL)) {
541 iKO->rc = iKO_UNCHANGED;
542 }
543
544 if ((keyStr = strstr(txt, "key")) != NULL) {
545 keyStr += 4;
546 sscanf(keyStr, "%8X\n", &iKO->keyID);
547 }
548 }
549
550 if (sd1[0] != 0) close ( sd1[0] );
551
552 /* Get the finger print */
553
554 GetFingerPrint(iKO);
555 }
556
557 /* ------------------------------------------------- */
558
559 void GetKeyID(struct ImportKeyObject *iKO) {
/* [<][>][^][v][top][bottom][index][help] */
560
561 char *strArgs[9];
562 char Args0[100];
563 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
564 int gpg_pid;
565 int gpg_in_fd, out_fd, err_fd;
566 int status;
567 char txt[LINE_LENGTH];
568 char *keyStr, *pos;
569 const char lockFilename[] = ".PAlock";
570 char keyRingLockFile[1000], keyRingPath[1000];
571 time_t lockBirthDate;
572 FILE *mystdin;
573 int childRC;
574
575 iKO->rc = iKO_GENERALFAILURE;
576
577 strcpy(Args0, "--no-tty");
578 strcpy(Args1, "--no-secmem-warning");
579 strcpy(Args2, "--keyring");
580 strcpy(Args3, iKO->keyRing);
581 strcpy(Args4, "--import");
582 strcpy(Args5, iKO->iFilename);
583
584 strArgs[0] = Args0;
585 strArgs[1] = Args1;
586 strArgs[2] = Args2;
587 strArgs[3] = Args3;
588 strArgs[4] = Args4;
589 strArgs[5] = Args5;
590 strArgs[6] = (char *)0;
591
592 gpg_in_fd = INPUT_FD;
593 out_fd = OUTPUT_FD;
594 err_fd = ERROR_FD;
595
596 /* create lock file filenames for NFS */
597
598 strcpy(keyRingLockFile, iKO->keyRing);
599 if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
600 strcpy(pos + 1, lockFilename);
601 strcpy(keyRingPath, keyRingLockFile);
602 keyRingPath[pos - keyRingLockFile] = 0;
603 } else {
604 strcpy(keyRingLockFile, lockFilename);
605 strcpy(keyRingPath, "");
606 }
607
608 lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
609
610 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
611 &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
612 printf ("could not spawn gpg");
613 exit(1);
614 }
615
616 if (waitpid (gpg_pid, &status, 0) < 0)
617 {
618 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
619 printf ("could not reap gpg process");
620 nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
621 exit(1);
622 }
623
624 nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
625
626 if (WIFEXITED(status) == 0)
627 {
628 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
629 printf ("gpg failure");
630 exit(1);
631 } else {
632 /* Child exited, checking return code */
633 childRC = (status & 0xF00) >> 8;
634 if (childRC == 1) {
635 fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
636 printf ("gpg failure\n");
637 exit(1);
638 }
639 }
640
641
642 /* Parsing gpg output */
643 /* while (read(0, txt, 1000) != 0)
644 fprintf(stderr, "child read %s\n", txt); */
645
646 mystdin = fdopen(0, "r");
647 iKO->rc = iKO_GENERALFAILURE;
648 while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
649 {
650 /* printf ( "GPG output : %s\n", txt ); */
651
652 if ((keyStr = strstr(txt, "imported")) != NULL) {
653 iKO->rc = iKO_OK;
654 }
655
656 if ((keyStr = strstr(txt, "CRC error")) != NULL) {
657 iKO->rc = iKO_CRC_ERROR;
658 }
659
660 if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) {
661 iKO->rc = iKO_NO_OPENPGP_DATA;
662 }
663
664 if (((keyStr = strstr(txt, "unchanged")) != NULL) ||
665 ((keyStr = strstr(txt, "not changed")) != NULL)) {
666 iKO->rc = iKO_UNCHANGED;
667 }
668
669 if ((keyStr = strstr(txt, "gpg: key ")) != NULL) {
670 keyStr += 9;
671 sscanf(keyStr, "%8X\n", &iKO->keyID);
672 }
673 }
674
675 if (sd1[0] != 0) close ( sd1[0] );
676
677 }
678
679 /* ------------------------------------------------- */
680
681 void PA_RemoveKey(struct ImportKeyObject *iKO) {
/* [<][>][^][v][top][bottom][index][help] */
682
683 char *strArgs[9];
684 char Args0[100]= "gpg";
685 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100], Args6[100], Args7[100];
686 int gpg_pid;
687 int gpg_in_fd, out_fd, err_fd;
688 int status;
689 char txt[LINE_LENGTH];
690 char *keyStr, *pos;
691 const char lockFilename[] = ".PAlock";
692 char keyRingLockFile[1000], keyRingPath[1000];
693 time_t lockBirthDate;
694 FILE *mystdin;
695 int childRC;
696
697 iKO->rc = iKO_GENERALFAILURE;
698
699 GetKeyID(iKO); /* getting key-id */
700
701 /* printf("Key id = %08lX\n", iKO->keyID); */
702
703 if ((iKO->rc == iKO_OK) || (iKO->rc == iKO_UNCHANGED)) {
704 strcpy(Args1, "--batch");
705 strcpy(Args2, "--yes");
706 strcpy(Args3, "--no-secmem-warning");
707 strcpy(Args4, "--keyring");
708 strcpy(Args5, iKO->keyRing);
709 strcpy(Args6, "--delete-key");
710 sprintf(Args7, "%08lX", iKO->keyID);
711
712 strArgs[0] = Args0;
713 strArgs[1] = Args1;
714 strArgs[2] = Args2;
715 strArgs[3] = Args3;
716 strArgs[4] = Args4;
717 strArgs[5] = Args5;
718 strArgs[6] = Args6;
719 strArgs[7] = Args7;
720 strArgs[8] = (char *)0;
721
722
723 gpg_in_fd = INPUT_FD;
724 out_fd = OUTPUT_FD;
725 err_fd = ERROR_FD;
726
727 /* create lock file filenames for NFS */
728
729 strcpy(keyRingLockFile, iKO->keyRing);
730 if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
731 strcpy(pos + 1, lockFilename);
732 strcpy(keyRingPath, keyRingLockFile);
733 keyRingPath[pos - keyRingLockFile] = 0;
734 } else {
735 strcpy(keyRingLockFile, lockFilename);
736 strcpy(keyRingPath, "");
737 }
738
739 lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
740
741 if ( ( gpg_pid = spawn_job ("/usr/local/bin/gpg", strArgs,
742 &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
743 printf ("could not spawn gpg");
744 exit(1);
745 }
746
747 /* printf("Child pid = %d\n", gpg_pid); */
748
749 if (waitpid (gpg_pid, &status, 0) < 0)
750 {
751 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
752 printf ("could not reap gpg process");
753 exit(1);
754 }
755
756 nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
757
758 if (WIFEXITED(status) == 0)
759 {
760 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
761 printf ("gpg failure");
762 exit(1);
763 } else {
764 /* Child exited, checking return code */
765 childRC = (status & 0xF00) >> 8;
766 if (childRC == 1) {
767 fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
768 printf ("gpg failure\n");
769 exit(1);
770 }
771 }
772
773
774 mystdin = fdopen(0, "r");
775 iKO->rc = iKO_OK;
776 while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
777 {
778 /* printf ( "GPG output : %s\n", txt ); */
779
780 if ((keyStr = strstr(txt, "delete key failed")) != NULL) {
781 iKO->rc = iKO_GENERALFAILURE;
782 }
783 if ((keyStr = strstr(txt, "there is a secret key for this public key")) != NULL) {
784 iKO->rc = iKO_SECRET_KEY_PRESENT;
785 }
786
787 }
788
789 if (sd1[0] != 0) close ( sd1[0] );
790 }
791 }
792
793 /* ------------------------------------------------- */
794
795
796 /* Get the next file line of an arbitrary length */
797
798 #define BUFSIZE 1024
799
800 char * GetLineFromFile3(FILE *fin) {
/* [<][>][^][v][top][bottom][index][help] */
801 int i;
802 char buffer;
803 static char line[BUFSIZE + 1];
804 char *p = NULL;
805 int p_size = BUFSIZE, eol = 0;
806
807 i = 0;
808 while (!eol && fread((void*) &buffer, 1, 1, fin)) {
809 if (i < BUFSIZE ) {
810 line[i] = buffer;
811 } else
812 if (i == BUFSIZE ) {
813
814 } else
815 if (i % BUFSIZE == 0) {
816 p = realloc(p, p_size+BUFSIZE + 1);
817 memcpy(p+p_size, line, BUFSIZE);
818 p_size += BUFSIZE;
819 p[i] = buffer;
820 }
821 i++;
822 if (buffer == '\n') eol = 1;
823 }
824
825 if (i == 0) return NULL;
826
827 if (p != NULL) {
828 p[i] = '\0';
829 return p;
830 } else {
831 line[i] = '\0';
832 return line;
833 }
834 }
835
836 char * GetLineFromFile2(FILE *fin) {
/* [<][>][^][v][top][bottom][index][help] */
837 static char * p = NULL;
838 static char buffer[BUFSIZE+1];
839 static char line[BUFSIZE+1];
840 static int eol_pos = -1, eof_pos = BUFSIZE+10;
841 char *nl, *startStr;
842 /* int i; */
843 int strSize, nBytesRead;
844 short eol = 0;
845
846
847 buffer[BUFSIZE] = '\0';
848 if (eol_pos == -1) {
849 /* this occurs in the beginning of a file */
850 nBytesRead = fread((void*) &buffer, 1, BUFSIZE, fin);
851 if (nBytesRead < BUFSIZE) {
852 eof_pos = nBytesRead;
853 }
854
855 startStr = buffer;
856 nl = strchr(startStr, '\n');
857 if ((nl != NULL) && (nl - startStr < nBytesRead)) {
858 eol_pos = nl - startStr;
859 memcpy(line, startStr, eol_pos+1);
860 line[eol_pos+1] = '\0';
861 return line;
862 } else
863 if ((nl == NULL) && (nl - startStr < nBytesRead)) {
864 p = malloc(BUFSIZE);
865 memcpy(p, buffer, BUFSIZE);
866 strSize = BUFSIZE;
867 while (!eol) {
868 nBytesRead = fread((void*) &buffer, 1, BUFSIZE, fin);
869 if (nBytesRead < BUFSIZE) {
870 eof_pos = nBytesRead;
871 }
872 startStr = buffer;
873 nl = strchr(startStr, '\n');
874 if ((nl == NULL) && (nl - startStr < nBytesRead)) {
875 p = realloc(p, strSize + BUFSIZE);
876 memcpy(p + strSize, buffer, BUFSIZE);
877 strSize += BUFSIZE;
878 } else
879 if ((nl != NULL) && (nl - startStr < nBytesRead)) {
880 p = realloc(p, strSize + (nl - startStr ));
881 memcpy(p + strSize, buffer, (nl - startStr + 1));
882 eol_pos = nl - buffer;
883 p[strSize + (nl - startStr )] = '\0';
884 return p;
885 } else {
886 p = realloc(p, strSize + nBytesRead + 1);
887 memcpy(p + strSize, buffer, nBytesRead );
888 p[strSize + nBytesRead] = '\0';
889 return p;
890 }
891 }
892 } else {
893 buffer[eof_pos]='\0';
894 eol_pos = -1;
895 return startStr;
896 }
897 } else
898 if (eof_pos > eol_pos) {
899 startStr = buffer + eol_pos + 1;
900 nl = strchr(startStr, '\n');
901 if (nl == NULL) {
902 strSize = BUFSIZE - (eol_pos + 1);
903 if (p != NULL) free(p);
904 p = malloc(strSize);
905 memcpy(p, buffer + eol_pos + 1, strSize);
906
907 /* Could not find '\n' on this block, proceed until find one */
908 while (!eol) {
909 nBytesRead = fread((void*) &buffer, 1, BUFSIZE, fin);
910 if (nBytesRead < BUFSIZE) {
911 eof_pos = nBytesRead;
912 }
913
914 startStr = buffer;
915 nl = strchr(startStr, '\n');
916 if ((nl == NULL) && (nl - startStr < nBytesRead)) {
917 p = realloc(p, strSize + BUFSIZE);
918 memcpy(p + strSize, buffer, BUFSIZE);
919 strSize += BUFSIZE;
920 } else
921 if ((nl != NULL) && (nl - startStr < nBytesRead)) {
922 p = realloc(p, strSize + (nl - startStr ) + 1);
923 memcpy(p + strSize, buffer, (nl - startStr + 1));
924 eol_pos = nl - buffer;
925 p[strSize + (nl - startStr )] = '\0';
926 return p;
927 } else {
928 p = realloc(p, strSize + nBytesRead + 2);
929 memcpy(p + strSize, buffer, nBytesRead);
930 eol_pos = -1;
931 p[strSize + nBytesRead + 1] = '\0';
932 return p;
933 }
934 }
935 } else {
936 if (p != NULL) free(p);
937 eol_pos = nl - buffer;
938 memcpy(line, startStr, nl - startStr + 1);
939 line[nl - startStr + 1] = '\0';
940 return line;
941 }
942 } else {
943 /* EOF */
944 eol_pos = -1;
945 return NULL;
946 }
947
948 return NULL;
949
950 }
951
952 /* ------------------------------------------------- */
953 EPNodePtr PA_ParseMessage(EPNodePtr ptr) {
/* [<][>][^][v][top][bottom][index][help] */
954
955 /* Assumptions:
956 - ptr is describing a text file, not MIME
957 - input file is broken down to pieces, plain text or PGP blocks
958 - if input file is doesn't have any PGP block, this is a leaf
959 - otherwise send each block to the proper handler.
960 */
961
962 FILE *fin, *fout;
963 char txt[MAX_LINE_BUF], *strptr;
964 /* char blockFilename[LINE_LENGTH]; */
965 const char PGP_prefix_msg[] = "-----BEGIN PGP MESSAGE";
966 const char PGP_suffix_msg[] = "-----END PGP MESSAGE";
967 const char PGP_prefix_signed[] = "-----BEGIN PGP SIGNED MESSAGE";
968 const char PGP_suffix_signature[] = "-----END PGP SIGNATURE";
969 int found_prefix = 0, found_suffix = 0;
970 EPNodePtr p = ptr, prev = ptr;
971 int end_of_fin = 0, text_block = 1;
972
973 if ((fin = fopen(ptr->file, "r")) != NULL) {
974
975 do {
976 /* this is needed because a text block parser ends when it finds
977 a PGP prefix, so we already have a txt buffer. */
978
979 if (!text_block || (prev == ptr)) {
980 strptr = fgets(txt, MAX_LINE_BUF, fin);
981 if (strptr == NULL ) end_of_fin = 1;
982 }
983
984 if (!end_of_fin && (found_prefix || (strstr(txt, PGP_prefix_msg) != NULL) ||
985 (strstr(txt, PGP_prefix_signed) != NULL))) {
986 /* PGP block */
987 found_prefix = 1;
988 text_block = 0;
989
990 p = EP_DefineNewNode(++EP_Node_ID, vS_TO_BE_PGPVERIFIED,
991 ptr->MIMEContentType, ptr->strMIMEContentType, 0);
992
993 if (prev != ptr)
994 prev->next = p;
995 else
996 ptr->inner = p;
997
998 if ((fout = fopen(p->file, "w")) != NULL ) {
999 fputs(txt, fout);
1000 /* To be replaced by fwrite(), more efficient */
1001 while ((found_prefix != found_suffix) &&
1002 ((strptr = fgets(txt, MAX_LINE_BUF, fin)) != NULL)) {
1003 if (strstr(txt, PGP_prefix_msg) != NULL) found_prefix++;
1004 if (strstr(txt, PGP_prefix_signed) != NULL) found_prefix++;
1005 if (strstr(txt, PGP_suffix_msg) != NULL) found_suffix++;
1006 if (strstr(txt, PGP_suffix_signature) != NULL) found_suffix++;
1007 fputs(txt, fout);
1008 }
1009 if (strptr == NULL ) end_of_fin = 1;
1010
1011 fclose(fout);
1012
1013 if (found_prefix == found_suffix) {
1014 found_prefix = found_suffix = 0;
1015
1016 VerifySignAndExplodeFile(p);
1017
1018 /* Called form EP_ParseMail or EP_PArseText ? */
1019
1020 if (strstr(EP_outputPrefix, "EPMtmp") != NULL)
1021 EP_MIMEParse(p);
1022 else
1023 PA_ParseMessage(p);
1024
1025 prev = p;
1026 } else {
1027 /* Wrong PGP delimiters order. */
1028 p->isValidPGPSignature = vS_UNMATCHED_PGP_DELIMITERS;
1029 }
1030 } else {
1031 p->isValidPGPSignature = vS_UNABLE_TO_WRITE_FILE;
1032 return p;
1033 }
1034
1035 } else {
1036 /* Clear text block */
1037
1038 text_block = 1;
1039
1040 if (strptr == NULL) end_of_fin = 1;
1041 else {
1042 p = EP_DefineNewNode(++EP_Node_ID, vS_IS_NOT_PGP,
1043 ptr->MIMEContentType,
1044 ptr->strMIMEContentType, 0);
1045
1046 if (prev != ptr)
1047 prev->next = p;
1048 else
1049 ptr->inner = p;
1050
1051 if ((fout = fopen(p->file, "w")) != NULL ) {
1052 fputs(txt, fout);
1053 /* To be replaced by fwrite(), more efficient */
1054 while ((!found_prefix &&
1055 (strptr = fgets(txt, MAX_LINE_BUF, fin)) != NULL)) {
1056 if ((strstr(txt, PGP_prefix_msg) != NULL) ||
1057 (strstr(txt, PGP_prefix_signed) != NULL)) found_prefix++;
1058 else
1059 fputs(txt, fout);
1060 }
1061 if (strptr == NULL ) end_of_fin = 1;
1062
1063 fclose(fout);
1064
1065 /* Check if the blockfile is finished and this is the first
1066 segment. If so this is a text leaf */
1067 if (found_prefix || (prev != p)) {
1068 if (prev->MIMEContentType == -1)
1069 {
1070 if (strstr(EP_outputPrefix, "EPMtmp") != NULL)
1071 EP_MIMEParse(p);
1072 else
1073 PA_ParseMessage(p);
1074 }
1075
1076 prev = p;
1077 }
1078
1079 } else {
1080 p->isValidPGPSignature = vS_UNABLE_TO_WRITE_FILE;
1081 return p;
1082 }
1083 }
1084 }
1085 } while (!end_of_fin);
1086 } else {
1087 p->isValidPGPSignature = vS_NO_IN_FILES;
1088 }
1089
1090 return ptr;
1091 }