modules/pa/gpg.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. GetFingerPrint
  2. VerifySignAndExplodeFile
  3. PA_VerifySignature
  4. PA_Decrypt
  5. PA_ImportKey
  6. GetKeyID
  7. PA_RemoveKey
  8. GetLineFromFile3
  9. GetLineFromFile2
  10. 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 }

/* [<][>][^][v][top][bottom][index][help] */