modules/pa/gpg.c

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

DEFINITIONS

This source file includes following functions.
  1. pa_strcpy
  2. PA_SetTmpDir
  3. PA_SetGPGCmd
  4. PA_SetKeyRing
  5. PA_SetOutputPrefix
  6. PA_VerifySignature
  7. PA_Decrypt
  8. PA_ImportKey
  9. PA_RemoveKey
  10. PA_RemoveKey_withKeyID
  11. PA_ParseMessage
  12. GetFingerPrint
  13. GetKeyOwner
  14. VerifySignAndExplodeFile
  15. GetKeyID

   1 /***************************************
   2   $Revision: 1.43 $
   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 Portera, Daniele Arena
  12   OSs Tested          : Solaris 7
  13   ******************/ /******************
  14   Copyright (c) 2000,2001,2002                    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 #include "rip.h"
  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 
  51 extern int  EP_TreeHeight;
  52 extern int  EP_Node_ID;
  53 extern int  EP_Debug;
  54 
  55 
  56 /* static int parseMailBlock_nMsg;
  57    static int parseRecursionLevel; */
  58 
  59 extern int sd1[2];
  60 extern int spawn_job (char *path, char *argv[], 
  61                       int *in_fd, int *out_fd, int *err_fd);
  62 extern time_t nfslock(char *path, char *namelock, int max_age, int notify);
  63 extern int nfsunlock(char *path, char *namelock, int max_age, time_t birth);
  64 
  65 
  66 static char* outputPrefix = NULL;
  67 static char* keyRing = NULL;
  68 static char* gpgCmd = NULL;
  69 static char *tmpdir = NULL;
  70 
  71 static void VerifySignAndExplodeFile(EPNodePtr ptr);
  72 static void GetKeyID(struct ImportKeyObject *iKO);
  73 
  74 
  75 /**************************************
  76  *
  77  * API functions
  78  *
  79  **************************************/
  80 
  81 /*++++++++++++++++++++++++++++
  82 
  83 Copies a string with memory allocation care.
  84 
  85 char* dest The destination string
  86 char* orig The origin string
  87 
  88 
  89 ++++++++++++++++++++++++++++*/
  90 
  91 void pa_strcpy(char** dest, char* orig) {
     /* [<][>][^][v][top][bottom][index][help] */
  92   if (*dest) {
  93     free(*dest);
  94   }
  95 
  96   *dest = malloc(strlen(orig) + 1);
  97   strcpy(*dest, orig);
  98 }
  99 
 100 /*++++++++++++++++++++++++++++
 101 
 102 Set the GPG temporary directory.
 103 
 104 char* dir The directory
 105 
 106 
 107 This memory allocated is never freed, maybe a PA_end function?
 108 
 109 ++++++++++++++++++++++++++++*/
 110 
 111 void PA_SetTmpDir(char* dir) {
     /* [<][>][^][v][top][bottom][index][help] */
 112   pa_strcpy(&tmpdir, dir);
 113 }
 114 
 115 /*++++++++++++++++++++++++++++
 116 
 117 Set the GPG command line.
 118 
 119 char* path The path including command name
 120 
 121 
 122 This memory allocated is never freed, maybe a PA_end function?
 123 
 124 ++++++++++++++++++++++++++++*/
 125 
 126 void PA_SetGPGCmd(char* path) {
     /* [<][>][^][v][top][bottom][index][help] */
 127   pa_strcpy(&gpgCmd, path);
 128 }
 129 
 130 /*++++++++++++++++++++++++++++
 131 
 132 Set the path to the Keyring.
 133 
 134 char* path The path including file name
 135 
 136 ++++++++++++++++++++++++++++*/
 137 
 138 void PA_SetKeyRing(char* path) {
     /* [<][>][^][v][top][bottom][index][help] */
 139   pa_strcpy(&keyRing, path);
 140 }
 141 
 142 /*++++++++++++++++++++++++++++
 143 
 144 Set the path to the output file.
 145 
 146 char* path The path including file name
 147 
 148 ++++++++++++++++++++++++++++*/
 149 
 150 void PA_SetOutputPrefix(char* path) {
     /* [<][>][^][v][top][bottom][index][help] */
 151   pa_strcpy(&outputPrefix, path);
 152 }
 153 
 154 /*++++++++++++++++++++++++++++
 155 
 156 Verify a detached PGP signature.
 157 
 158 struct VerifySignObject *vSO    The signed object structure to be verified.
 159 
 160 ++++++++++++++++++++++++++++*/
 161 
 162 void PA_VerifySignature(struct VerifySignObject *vSO) {
     /* [<][>][^][v][top][bottom][index][help] */
 163   char *strArgs[10];
 164   char Args0[100];
 165   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100],
 166     Args6[100], Args7[100];
 167   int gpg_pid;
 168   int gpg_in_fd, out_fd, err_fd;
 169   int status;
 170   /* static int nMsgs = 0; */
 171   char txt[LINE_LENGTH];
 172   char *keyStr;
 173   /* int childRC; */
 174 
 175   int fIn,fOut;
 176   char tmpFileName[100],lfcrStr[10],strIn[10];
 177   char prevChar;
 178   FILE *mystdin;
 179 
 180   vSO->type = vSO_Type_Signed;
 181 
 182   strcpy(Args0, "--no-secmem-warning");
 183   strcpy(Args1, "--keyring");
 184   strcpy(Args2, keyRing);
 185   strcpy(Args3, "-o");
 186   if (!strcmp(vSO->iSigFilename, "")) {
 187     strcpy(Args4, vSO->oStream);
 188     strcpy(Args5, "-d");
 189     strcpy(Args6, vSO->iDocSigFilename);
 190     strArgs[6] = Args6;
 191     strArgs[7] = (char *)0;
 192   } else {
 193     /* change <cr> to <lf>+<cr> to be related-rfc compliant */
 194     fIn=open(vSO->iDocSigFilename,O_RDONLY);
 195     if (fIn==-1) {
 196       ER_perror(FAC_PA, PA_CANTREAD, "can't open %s for reading", vSO->iDocSigFilename);
 197       exit(1);
 198     }
 199     strcpy(tmpFileName,tmpdir);
 200     strcat(tmpFileName,"/patmpXXXXXXX");
 201     fOut=mkstemp(tmpFileName);
 202     if (fOut==-1) {
 203       ER_perror(FAC_PA, PA_NOTEMP, "%s", tmpFileName);
 204       exit(1);
 205     }
 206     prevChar=0;
 207     sprintf(lfcrStr,"%c%c%c",13,10,0);
 208     while(read(fIn,strIn,1)>0)
 209     {
 210       if ((strIn[0]==10)&&(prevChar!=13)) {
 211         write(fOut,lfcrStr,2);
 212       } else {
 213         write(fOut,strIn,1);
 214       }
 215       prevChar=strIn[0];
 216     }
 217     close(fOut);
 218     close(fIn);
 219     /* end change <cr> to <lf>+<cr> to be related-rfc compliant */
 220 
 221     strcpy(Args5, "--verify");
 222     strcpy(Args6, vSO->iSigFilename);
 223     strcpy(Args7, tmpFileName);
 224     
 225     strArgs[6] = Args6;
 226     strArgs[7] = Args7;
 227     strArgs[8] = (char *)0;
 228     strcpy(vSO->oStream, vSO->iDocSigFilename);
 229   }
 230 
 231   strArgs[0] = Args0;
 232   strArgs[1] = Args1;  
 233   strArgs[2] = Args2;  
 234   strArgs[3] = Args3;
 235   strArgs[4] = Args4;
 236   strArgs[5] = Args5;
 237   
 238   gpg_in_fd = INPUT_FD;
 239   out_fd = OUTPUT_FD;
 240   err_fd = ERROR_FD;
 241   if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
 242                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
 243     {
 244       ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
 245       exit(1);
 246     }
 247   
 248   if (waitpid (gpg_pid, &status, 0) < 0)
 249     {
 250       ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
 251       exit(1);
 252     }
 253   unlink(tmpFileName);
 254   if (WIFEXITED(status) == 0)
 255     {
 256       ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
 257       exit(1);
 258     } else {
 259       /* Child exited, checking return code */
 260       /* childRC = (status & 0xF00) >> 8;
 261       if (childRC == 1) {
 262         fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC);
 263         printf ("gpg failure\n");
 264         exit(1);
 265         } */
 266     }
 267 
 268 
 269   /* Parsing gpg output */
 270   mystdin = fdopen(0, "r");
 271   vSO->isValid = vSO_KO;
 272   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
 273     {
 274       /*        printf ( "GPG output : %s\n", txt );   */
 275       if (strstr(txt, "Good signature") != NULL)
 276         vSO->isValid = vSO_IS_VALID;
 277 
 278       if (strstr(txt, "CRC error") != NULL)
 279         vSO->isValid = vSO_CRC_ERROR;
 280 
 281       if (strstr(txt, "public key not found") != NULL)
 282         vSO->isValid = vSO_NO_PUBLIC_KEY;
 283 
 284       if (strstr(txt, "no valid OpenPGP data found") != NULL)
 285         vSO->isValid = vSO_NO_OPENPGP_DATA;
 286 
 287       if ((keyStr = strstr(txt, "key ID")) != NULL) {
 288         keyStr += 7;
 289         sscanf(keyStr, "%8X\n", &vSO->keyID);
 290       }
 291     }
 292     
 293   if (sd1[0] != 0)  close ( sd1[0] ); 
 294 }
 295 
 296 
 297 
 298 /*++++++++++++++++++++++++++++
 299 
 300 Decrypt a PGP-encrypted file.
 301 
 302 struct ReadCryptedObject *rDO   The object to be decrypted
 303 
 304 
 305 Note:
 306   This functions is not used by PA/EP/MM
 307   It can be useful in the future....  (FP)
 308 
 309 ++++++++++++++++++++++++++++*/
 310 
 311 void PA_Decrypt(struct ReadCryptedObject *rDO) {
     /* [<][>][^][v][top][bottom][index][help] */
 312   
 313   char *strArgs[9];
 314   char clearTextExtension[4] = ".gpg";
 315   char Args0[100];
 316   char Args1[100];
 317   char Args2[100];
 318   char Args3[100];
 319   char Args4[100];
 320   char Args5[100];
 321   char Args6[100];
 322   int gpg_pid;
 323   int gpg_in_fd, out_fd, err_fd;
 324   int status;
 325   char txt[LINE_LENGTH];
 326   int childRC;
 327   FILE *mystdin;
 328 
 329   strcpy(Args0, "--no-tty");
 330   strcpy(Args1, "--no-secmem-warning");
 331   strcpy(Args2, "--keyring");
 332   strcpy(Args3, rDO->keyRing);
 333   strcpy(Args4, "--output");
 334   strcpy(Args5, strcat(rDO->iFilename, clearTextExtension));
 335   strcpy(Args6, rDO->iFilename);
 336   
 337   strArgs[0] = Args0;
 338   strArgs[1] = Args1;  
 339   strArgs[2] = Args2;  
 340   strArgs[3] = Args3;  
 341   strArgs[4] = Args4;  
 342   strArgs[5] = Args5;  
 343   strArgs[6] = Args6;  
 344   strArgs[7] = (char *) 0;   
 345 
 346   gpg_in_fd = INPUT_FD;
 347   out_fd = OUTPUT_FD;
 348   err_fd = ERROR_FD;
 349   if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
 350                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
 351     {
 352       ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
 353       exit(1);
 354     }
 355   
 356   if (waitpid (gpg_pid, &status, 0) < 0)
 357     {
 358       ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
 359       exit(1);
 360     }
 361   if (WIFEXITED(status) == 0)
 362     {
 363       ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
 364       exit(1);
 365     } else {
 366       /* Child exited, checking return code */
 367       childRC = (status & 0xF00) >> 8;
 368       if (childRC == 1) {
 369         ER_perror(FAC_PA, PA_CHRC, "%d", childRC);
 370         exit(1);
 371       } 
 372     }
 373 
 374 
 375   /* Parsing gpg output */
 376   mystdin = fdopen(0, "r");
 377   while (fgets (txt, STRING_LENGTH - 1, mystdin) != NULL)
 378     {
 379       
 380     }
 381   
 382   if (sd1[0] != 0)  close ( sd1[0] ); 
 383 }
 384 
 385 
 386 
 387 /*++++++++++++++++++++++++++++
 388 
 389 Import a PGP key.
 390 
 391 struct ImportKeyObject *iKO     The structure where the imported key goes
 392 
 393 ++++++++++++++++++++++++++++*/
 394 
 395 void PA_ImportKey(struct ImportKeyObject *iKO) {
     /* [<][>][^][v][top][bottom][index][help] */
 396   
 397   char *strArgs[9];
 398   char Args0[100];
 399   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
 400   int gpg_pid;
 401   int gpg_in_fd, out_fd, err_fd;
 402   int status;
 403   char txt[LINE_LENGTH];
 404   char *keyStr, *pos;
 405   const char lockFilename[] = ".PAlock";
 406   char keyRingLockFile[1000], keyRingPath[1000];
 407   time_t lockBirthDate;
 408   FILE *mystdin;
 409   int childRC;
 410   int key_count;
 411   GList *key_list = NULL;
 412   GList *next = NULL;
 413   struct ImportKeyObject iKO_toBeRemoved;
 414 
 415   iKO->rc = iKO_GENERALFAILURE;
 416 
 417   strcpy(Args0, "--no-tty");
 418   strcpy(Args1, "--no-secmem-warning");
 419   strcpy(Args2, "--keyring");
 420   strcpy(Args3, iKO->keyRing);
 421   strcpy(Args4, "--import");
 422   strcpy(Args5, iKO->iFilename);
 423 
 424   strArgs[0] = Args0;  
 425   strArgs[1] = Args1;  
 426   strArgs[2] = Args2;  
 427   strArgs[3] = Args3;  
 428   strArgs[4] = Args4;  
 429   strArgs[5] = Args5;
 430   strArgs[6] = (char *)0;
 431 
 432   gpg_in_fd = INPUT_FD;
 433   out_fd = OUTPUT_FD;
 434   err_fd = ERROR_FD;
 435 
 436   /* create lock file filenames for NFS */
 437 
 438   strcpy(keyRingLockFile, iKO->keyRing);
 439   if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
 440     strcpy(pos + 1, lockFilename);
 441     strcpy(keyRingPath, keyRingLockFile);
 442     keyRingPath[pos - keyRingLockFile] = 0;
 443   } else {
 444     strcpy(keyRingLockFile, lockFilename);
 445     strcpy(keyRingPath, "");
 446   }
 447   
 448   lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
 449 
 450   if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
 451                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
 452     ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
 453     exit(1);
 454   }
 455   
 456   if (waitpid (gpg_pid, &status, 0) < 0)
 457     {
 458       ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
 459       nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
 460       exit(1);
 461     }
 462 
 463   nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
 464 
 465   if (WIFEXITED(status) == 0)
 466     {
 467       ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
 468     } 
 469     else 
 470     {
 471       /* Child exited, checking return code */
 472       childRC = (status & 0xF00) >> 8;
 473       if (tracing)
 474         printf("TRACING: PA_ImportKey child return code [%d]\n", childRC);
 475       if (childRC == 1) 
 476       {
 477         ER_perror(FAC_PA, PA_CHRC, "%d", childRC);
 478         /*  exit(1);  */
 479       }
 480     }
 481 
 482 
 483   /* Parsing gpg output */
 484   /*   while (read(0, txt, 1000) != 0)
 485        fprintf(stderr, "child read %s\n", txt); */
 486 
 487   mystdin = fdopen(0, "r");
 488   iKO->rc = iKO_GENERALFAILURE;
 489   key_count = 0;
 490   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
 491   {
 492     /* printf ( "GPG output : %s\n", txt );      */
 493 
 494     if ((keyStr = strstr(txt, "imported")) != NULL)
 495     {
 496           iKO->rc = iKO_OK;
 497     }
 498 
 499     if ((keyStr = strstr(txt, "CRC error")) != NULL)
 500     {
 501           iKO->rc = iKO_CRC_ERROR;
 502     }
 503 
 504     if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL)
 505     {
 506           iKO->rc = iKO_NO_OPENPGP_DATA;
 507     }
 508 
 509     if ((keyStr = strstr(txt, "invalid armor header")) != NULL)
 510     {
 511           iKO->rc = iKO_INVALID_ARMOR_HEADER;
 512     }
 513 
 514     if (((keyStr = strstr(txt, "unchanged")) != NULL) || 
 515           ((keyStr = strstr(txt, "not changed")) != NULL))
 516     {
 517           iKO->rc = iKO_UNCHANGED;
 518     }
 519 
 520     if ((keyStr = strstr(txt, "key")) != NULL)
 521     {
 522           keyStr += 4;
 523           sscanf(keyStr, "%8X\n", &iKO->keyID); 
 524       key_count++;
 525       /* and put the key ID into the keys list (if it was new to the keyring)*/
 526       if(strstr(txt, "imported") != NULL)
 527       {
 528         key_list = g_list_append(key_list, GINT_TO_POINTER(iKO->keyID));
 529       }
 530     } 
 531   }
 532 
 533   if (sd1[0] != 0)  close ( sd1[0] ); 
 534 
 535   if(key_count > 1){/* if there were more than one keys imported */
 536     iKO->rc = iKO_MULTIPLE_KEYS; /* this is an error */
 537     /* now, roll-back, remove the added keys from key-ring */
 538     for( next = key_list; next != NULL; next = g_list_next(next) ){
 539       strcpy(iKO_toBeRemoved.keyRing, 
 540           iKO->keyRing);
 541       iKO_toBeRemoved.keyID = (u32)(next->data);
 542       PA_RemoveKey_withKeyID(&iKO_toBeRemoved);
 543     }
 544     
 545   }else{
 546     /* Get the finger print */
 547     GetFingerPrint(iKO);
 548     GetKeyOwner(iKO);
 549   }
 550 }
 551 
 552 
 553 
 554 /*++++++++++++++++++++++++++++
 555 
 556 Remove a PGP key.
 557 
 558 struct ImportKeyObject *iKO     The structure containing the key to be removed
 559 
 560 ++++++++++++++++++++++++++++*/
 561 
 562 void PA_RemoveKey(struct ImportKeyObject *iKO) {
     /* [<][>][^][v][top][bottom][index][help] */
 563   
 564   char *strArgs[9];
 565   char Args0[100]= "gpg";
 566   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100], Args6[100], Args7[100];
 567   int gpg_pid;
 568   int gpg_in_fd, out_fd, err_fd;
 569   int status;
 570   char txt[LINE_LENGTH];
 571   char *keyStr, *pos;
 572   const char lockFilename[] = ".PAlock";
 573   char keyRingLockFile[1000], keyRingPath[1000];
 574   time_t lockBirthDate;
 575   FILE *mystdin;
 576   int childRC;
 577 
 578   iKO->rc = iKO_GENERALFAILURE;
 579 
 580   GetKeyID(iKO);   /* getting key-id */
 581 
 582   /*   printf("Key id = %08lX\n", iKO->keyID); */
 583 
 584   if ((iKO->rc == iKO_OK) || (iKO->rc == iKO_UNCHANGED)) {    
 585     strcpy(Args1, "--batch");
 586     strcpy(Args2, "--yes");
 587     strcpy(Args3, "--no-secmem-warning");
 588     strcpy(Args4, "--keyring");
 589     strcpy(Args5, iKO->keyRing); 
 590     strcpy(Args6, "--delete-key");
 591     sprintf(Args7, "%08X", iKO->keyID);
 592 
 593     strArgs[0] = Args0;  
 594     strArgs[1] = Args1;  
 595     strArgs[2] = Args2;  
 596     strArgs[3] = Args3;  
 597     strArgs[4] = Args4;  
 598     strArgs[5] = Args5;
 599     strArgs[6] = Args6;
 600     strArgs[7] = Args7;
 601     strArgs[8] = (char *)0;  
 602   
 603 
 604     gpg_in_fd = INPUT_FD;
 605     out_fd = OUTPUT_FD;
 606     err_fd = ERROR_FD;
 607 
 608   /* create lock file filenames for NFS */
 609 
 610     strcpy(keyRingLockFile, iKO->keyRing);
 611     if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
 612       strcpy(pos + 1, lockFilename);
 613       strcpy(keyRingPath, keyRingLockFile);
 614       keyRingPath[pos - keyRingLockFile] = 0;
 615     } else {
 616       strcpy(keyRingLockFile, lockFilename);
 617       strcpy(keyRingPath, "");
 618     }
 619   
 620     lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
 621 
 622     if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
 623                                 &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
 624       ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
 625       exit(1);
 626     }
 627 
 628     /*    printf("Child pid = %d\n", gpg_pid); */
 629   
 630     if (waitpid (gpg_pid, &status, 0) < 0)
 631       {
 632         ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
 633         exit(1);
 634       }
 635 
 636     nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
 637 
 638     if (WIFEXITED(status) == 0)
 639     {
 640         ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
 641         exit(1);
 642     }
 643     else
 644     {
 645           /* Child exited, checking return code */
 646           childRC = (status & 0xF00) >> 8;
 647           if (childRC == 1)
 648       {
 649             ER_perror(FAC_PA, PA_CHRC, "%d", childRC);
 650           }
 651     }
 652 
 653 
 654     mystdin = fdopen(0, "r");
 655     iKO->rc = iKO_OK;
 656     while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
 657     {
 658           /* printf ( "GPG output : %s\n", txt );        */
 659 
 660           if ((keyStr = strstr(txt, "delete key failed")) != NULL)
 661       {
 662             iKO->rc = iKO_GENERALFAILURE;
 663           }
 664           if ((keyStr = strstr(txt, "there is a secret key for this public key")) != NULL)
 665       {
 666             iKO->rc = iKO_SECRET_KEY_PRESENT;
 667           }
 668     }
 669 
 670     if (sd1[0] != 0)  close ( sd1[0] ); 
 671   }
 672 }
 673 
 674 /*++++++++++++++++++++++++++++
 675 
 676 Remove a PGP key, using its KeyID (otherwise it's the same as PA_RemoveKey
 677 
 678 struct ImportKeyObject *iKO     The structure containing the key to be removed
 679 
 680 ++++++++++++++++++++++++++++*/
 681 
 682 void PA_RemoveKey_withKeyID(struct ImportKeyObject *iKO) {
     /* [<][>][^][v][top][bottom][index][help] */
 683   
 684   char *strArgs[9];
 685   char Args0[100]= "gpg";
 686   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100], Args6[100], Args7[100];
 687   int gpg_pid;
 688   int gpg_in_fd, out_fd, err_fd;
 689   int status;
 690   char txt[LINE_LENGTH];
 691   char *keyStr, *pos;
 692   const char lockFilename[] = ".PAlock";
 693   char keyRingLockFile[1000], keyRingPath[1000];
 694   time_t lockBirthDate;
 695   FILE *mystdin;
 696   int childRC;
 697 
 698   iKO->rc = iKO_GENERALFAILURE;
 699 
 700 
 701     strcpy(Args1, "--batch");
 702     strcpy(Args2, "--yes");
 703     strcpy(Args3, "--no-secmem-warning");
 704     strcpy(Args4, "--keyring");
 705     strcpy(Args5, iKO->keyRing); 
 706     strcpy(Args6, "--delete-key");
 707     sprintf(Args7, "%08X", iKO->keyID);
 708 
 709     strArgs[0] = Args0;  
 710     strArgs[1] = Args1;  
 711     strArgs[2] = Args2;  
 712     strArgs[3] = Args3;  
 713     strArgs[4] = Args4;  
 714     strArgs[5] = Args5;
 715     strArgs[6] = Args6;
 716     strArgs[7] = Args7;
 717     strArgs[8] = (char *)0;  
 718   
 719 
 720     gpg_in_fd = INPUT_FD;
 721     out_fd = OUTPUT_FD;
 722     err_fd = ERROR_FD;
 723 
 724   /* create lock file filenames for NFS */
 725 
 726     strcpy(keyRingLockFile, iKO->keyRing);
 727     if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
 728       strcpy(pos + 1, lockFilename);
 729       strcpy(keyRingPath, keyRingLockFile);
 730       keyRingPath[pos - keyRingLockFile] = 0;
 731     } else {
 732       strcpy(keyRingLockFile, lockFilename);
 733       strcpy(keyRingPath, "");
 734     }
 735   
 736     lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
 737 
 738 
 739     if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
 740                                 &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
 741       ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
 742       exit(1);
 743     }
 744 
 745     /*    printf("Child pid = %d\n", gpg_pid); */
 746   
 747     if (waitpid (gpg_pid, &status, 0) < 0)
 748       {
 749         ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
 750         exit(1);
 751       }
 752 
 753     nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
 754 
 755     if (WIFEXITED(status) == 0)
 756       {
 757         ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
 758         exit(1);
 759       }  else {
 760         /* Child exited, checking return code */
 761         childRC = (status & 0xF00) >> 8;
 762         if (childRC == 1) {
 763           ER_perror(FAC_PA, PA_CHRC, "%d", childRC);
 764         }
 765       }
 766 
 767 
 768     mystdin = fdopen(0, "r");
 769     iKO->rc = iKO_OK;
 770     while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
 771       {
 772         /* printf ( "GPG output : %s\n", txt );        */
 773 
 774         if ((keyStr = strstr(txt, "delete key failed")) != NULL) {
 775           iKO->rc = iKO_GENERALFAILURE;
 776         }
 777         if ((keyStr = strstr(txt, "there is a secret key for this public key")) != NULL) {
 778           iKO->rc = iKO_SECRET_KEY_PRESENT;
 779         }
 780 
 781       }
 782 
 783     if (sd1[0] != 0)  close ( sd1[0] ); 
 784   
 785 }
 786 
 787 
 788 
 789 
 790 /*++++++++++++++++++++++++++++
 791 
 792 Parse a file and look for PGP-signed elements inside. 
 793 
 794 EPNodePtr ptr   The pointer to the EP treenode containing the file to be parsed.
 795 
 796 ++++++++++++++++++++++++++++*/
 797 
 798 EPNodePtr PA_ParseMessage(EPNodePtr ptr) {
     /* [<][>][^][v][top][bottom][index][help] */
 799 
 800   /* Assumptions:
 801      - ptr is describing a text file, not MIME
 802      - input file is broken down to pieces, plain text or PGP blocks  
 803      - if input file is doesn't have any PGP block, this is a leaf
 804      - otherwise send each block to the proper handler.
 805   */
 806 
 807   FILE *fin, *fout;
 808   char txt[MAX_LINE_BUF], *strptr;
 809   /* char blockFilename[LINE_LENGTH]; */
 810   const char PGP_prefix_msg[] =       "-----BEGIN PGP MESSAGE";
 811   const char PGP_suffix_msg[] =       "-----END PGP MESSAGE";
 812   const char PGP_prefix_signed[] =    "-----BEGIN PGP SIGNED MESSAGE";
 813   const char PGP_suffix_signature[] = "-----END PGP SIGNATURE";
 814   int found_prefix = 0, found_suffix = 0;
 815   EPNodePtr p = ptr, prev = ptr;
 816   int end_of_fin = 0, text_block = 1;
 817 
 818 
 819   ER_dbg_va (FAC_PA, ASP_PA_GEN, "Entering PA_ParseMessage...");
 820   
 821 
 822   if ((fin = fopen(ptr->file, "r")) != NULL) { 
 823 
 824     do {
 825       /* this is needed because a text block parser ends when it finds
 826          a PGP prefix, so we already have a txt buffer.   */ 
 827       
 828       if (!text_block || (prev == ptr)) {
 829         strptr = fgets(txt, MAX_LINE_BUF, fin);
 830         if (strptr == NULL ) end_of_fin = 1;
 831       }
 832 
 833       if (!end_of_fin && (found_prefix || (strstr(txt, PGP_prefix_msg) != NULL) ||
 834                           (strstr(txt, PGP_prefix_signed) != NULL))) {
 835         /* PGP block */
 836         found_prefix = 1;
 837         text_block = 0;
 838         
 839         p = EP_DefineNewNode(++EP_Node_ID, vS_TO_BE_PGPVERIFIED, 
 840                              ptr->MIMEContentType, ptr->strMIMEContentType, 0);
 841         
 842         if (prev != ptr)
 843           prev->next = p;
 844         else
 845           ptr->inner = p;
 846         
 847         if ((fout = fopen(p->file, "w")) != NULL ) {
 848           fputs(txt, fout);
 849           /* To be replaced by fwrite(), more efficient */
 850           while ((found_prefix != found_suffix) && 
 851                  ((strptr = fgets(txt, MAX_LINE_BUF, fin)) != NULL)) {
 852             if (strstr(txt, PGP_prefix_msg) != NULL) found_prefix++;
 853             if (strstr(txt, PGP_prefix_signed) != NULL) found_prefix++;
 854             if (strstr(txt, PGP_suffix_msg) != NULL) found_suffix++;
 855             if (strstr(txt, PGP_suffix_signature) != NULL) found_suffix++;
 856             fputs(txt, fout);
 857           }
 858           if (strptr == NULL ) end_of_fin = 1;
 859           
 860           fclose(fout);
 861           
 862           if (found_prefix == found_suffix) {
 863             found_prefix = found_suffix = 0;
 864             
 865             VerifySignAndExplodeFile(p);
 866             
 867             /* Called form EP_ParseMail or EP_PArseText ? */
 868             
 869             if (strstr(outputPrefix, "EPMtmp") != NULL)
 870               {
 871                 ER_dbg_va (FAC_PA, ASP_PA_GEN, "Found prefix and suffix; calling EP_MIMEParse...");
 872                 EP_MIMEParse(p);
 873               }
 874             else {
 875               PA_ParseMessage(p);
 876             }
 877             prev = p;
 878           } else {
 879             /* Wrong PGP delimiters order. */
 880             p->isValidPGPSignature = vS_UNMATCHED_PGP_DELIMITERS;
 881           }
 882         } else {
 883           p->isValidPGPSignature = vS_UNABLE_TO_WRITE_FILE;
 884           return p;
 885         }
 886         
 887       } else {
 888         /* Clear text block */
 889 
 890         text_block = 1;
 891 
 892         if (strptr == NULL) end_of_fin = 1;
 893         else {
 894           p = EP_DefineNewNode(++EP_Node_ID, vS_IS_NOT_PGP, 
 895                                ptr->MIMEContentType, 
 896                                ptr->strMIMEContentType, 0);
 897         
 898           if (prev != ptr)
 899             prev->next = p;
 900           else
 901             ptr->inner = p;
 902 
 903           if ((fout = fopen(p->file, "w")) != NULL ) {
 904             fputs(txt, fout);
 905             /* To be replaced by fwrite(), more efficient */
 906             while ((!found_prefix && 
 907                     (strptr = fgets(txt, MAX_LINE_BUF, fin)) != NULL)) {
 908               if ((strstr(txt, PGP_prefix_msg) != NULL) ||
 909                   (strstr(txt, PGP_prefix_signed) != NULL)) found_prefix++;
 910               else 
 911                 fputs(txt, fout);
 912             }
 913             if (strptr == NULL ) end_of_fin = 1;
 914 
 915             fclose(fout);
 916 
 917             /* Check if the blockfile is finished and this is the first
 918                segment. If so this is a text leaf */
 919             if (found_prefix || (prev != p)) {
 920               if (prev->MIMEContentType == -1)
 921                 {
 922                   if (strstr(outputPrefix, "EPMtmp") != NULL)
 923                     {
 924                       ER_dbg_va (FAC_PA, ASP_PA_GEN, "PA_ParseMessage: sending to EP_MIMEParse");
 925                       EP_MIMEParse(p);
 926                     }
 927                   else {
 928                     PA_ParseMessage(p);
 929                   }
 930                 }
 931             
 932               prev = p;
 933             }
 934             
 935           } else {
 936             p->isValidPGPSignature = vS_UNABLE_TO_WRITE_FILE;
 937             return p;
 938           }
 939         }
 940       }
 941     } while (!end_of_fin);
 942   } else {
 943     p->isValidPGPSignature = vS_NO_IN_FILES;
 944   }
 945 
 946   return ptr;
 947 }
 948 
 949 
 950 /**************************************
 951  *
 952  * Internal functions
 953  *
 954  **************************************/
 955 
 956 
 957 
 958 /*++++++++++++++++++++++++++++
 959 
 960 Get the fingerprint of a PGP key.
 961 
 962 ImportKeyObject *iKO    The imported key object
 963 
 964 ++++++++++++++++++++++++++++*/
 965 
 966 void GetFingerPrint(struct ImportKeyObject *iKO) {
     /* [<][>][^][v][top][bottom][index][help] */
 967   
 968   char *strArgs[9];
 969   char Args0[100] ;
 970   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
 971   int gpg_pid;
 972   int gpg_in_fd, out_fd, err_fd;
 973   int status;
 974   char txt[LINE_LENGTH];
 975   char *keyStr;
 976   FILE *mystdin;
 977   int childRC;
 978 
 979   strcpy(Args0, "--no-tty");
 980   strcpy(Args1, "--no-secmem-warning");
 981   strcpy(Args2, "--keyring");
 982   strcpy(Args3, iKO->keyRing);
 983   strcpy(Args4, "--fingerprint");
 984   sprintf(Args5, "%08X", iKO->keyID);
 985 
 986   strArgs[0] = Args0;  
 987   strArgs[1] = Args1;  
 988   strArgs[2] = Args2;  
 989   strArgs[3] = Args3;  
 990   strArgs[4] = Args4;  
 991   strArgs[5] = Args5;
 992   strArgs[6] = (char *)0;
 993 
 994   gpg_in_fd = INPUT_FD;
 995   out_fd = OUTPUT_FD;
 996   err_fd = ERROR_FD;
 997 
 998   /* create lock file filenames for NFS */
 999 
1000   if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
1001                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
1002     ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
1003     exit(1);
1004   }
1005   
1006   if (waitpid (gpg_pid, &status, 0) < 0)
1007     {
1008       ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
1009       exit(1);
1010     }
1011 
1012   if (WIFEXITED(status) == 0)
1013     {
1014       ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
1015       exit(1);
1016     } else {
1017       /* Child exited, checking return code */
1018       childRC = (status & 0xF00) >> 8;
1019       if (childRC == 1) {
1020         ER_perror(FAC_PA, PA_CHRC, "%d", childRC);
1021         exit(1);
1022       }
1023     }
1024 
1025 
1026   mystdin = fdopen(0, "r");
1027   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
1028     {
1029       /* printf ( "GPG output : %s\n", txt );      */
1030 
1031       if ((keyStr = strstr(txt, "Key fingerprint =")) != NULL) {
1032         strcpy(iKO->fingerPrint, keyStr + 18);
1033         iKO->fingerPrint[strlen(iKO->fingerPrint)-1] = 0;
1034       }
1035 
1036       if ((keyStr = strstr(txt, "key")) != NULL) {
1037          keyStr += 4;
1038          sscanf(keyStr, "%8X\n", &iKO->keyID); 
1039       } 
1040     }
1041 
1042   if (sd1[0] != 0)  close ( sd1[0] ); 
1043 }
1044 
1045 
1046 
1047 /*++++++++++++++++++++++++++++
1048 
1049 Get the owner of a PGP key.
1050 
1051 ImportKeyObject *iKO    The imported key object
1052 
1053 ++++++++++++++++++++++++++++*/
1054 
1055 void GetKeyOwner(struct ImportKeyObject *iKO) {
     /* [<][>][^][v][top][bottom][index][help] */
1056   
1057   char *strArgs[9];
1058   char Args0[100] ;
1059   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
1060   int gpg_pid;
1061   int gpg_in_fd, out_fd, err_fd;
1062   int status;
1063   char txt[LINE_LENGTH];
1064   char *keyStr;
1065   FILE *mystdin;
1066   int childRC;
1067 
1068   strcpy(Args0, "--no-tty");
1069   strcpy(Args1, "--no-secmem-warning");
1070   strcpy(Args2, "--keyring");
1071   strcpy(Args3, iKO->keyRing);
1072   strcpy(Args4, "--fingerprint");
1073   sprintf(Args5, "%08X", iKO->keyID);
1074 
1075   strArgs[0] = Args0;  
1076   strArgs[1] = Args1;  
1077   strArgs[2] = Args2;  
1078   strArgs[3] = Args3;  
1079   strArgs[4] = Args4;  
1080   strArgs[5] = Args5;
1081   strArgs[6] = (char *)0;
1082 
1083   gpg_in_fd = INPUT_FD;
1084   out_fd = OUTPUT_FD;
1085   err_fd = ERROR_FD;
1086 
1087   /* create lock file filenames for NFS */
1088 
1089   if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
1090                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
1091     ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
1092     exit(1);
1093   }
1094   
1095   if (waitpid (gpg_pid, &status, 0) < 0)
1096     {
1097       ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
1098       exit(1);
1099     }
1100 
1101   if (WIFEXITED(status) == 0)
1102     {
1103       ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
1104       exit(1);
1105     } else {
1106       /* Child exited, checking return code */
1107       childRC = (status & 0xF00) >> 8;
1108       if (childRC == 1) {
1109         ER_perror(FAC_PA, PA_CHRC, "%d", childRC);
1110         exit(1);
1111       }
1112     }
1113 
1114 
1115   mystdin = fdopen(0, "r");
1116   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
1117     {
1118       /* printf ( "GPG output : %s\n", txt );      */
1119 
1120       if ((keyStr = strstr(txt, "pub "/*"Key fingerprint ="*/)) == txt /*!= NULL*/) {
1121         strcpy(iKO->keyOwner, keyStr + 30);
1122         iKO->keyOwner[strlen(iKO->keyOwner)-1] = 0;
1123       }
1124 
1125       if ((keyStr = strstr(txt, "key")) != NULL) {
1126          keyStr += 4;
1127          sscanf(keyStr, "%8X\n", &iKO->keyID); 
1128       } 
1129     }
1130 
1131   if (sd1[0] != 0)  close ( sd1[0] ); 
1132 }
1133 
1134 
1135 
1136 /*++++++++++++++++++++++++++++
1137 
1138 Verify the PGP signature and extract the signed part in a file.
1139 
1140 EPNodePtr ptr   The pointer to the EP treenode containing the originating file
1141 
1142 ++++++++++++++++++++++++++++*/
1143 
1144 void VerifySignAndExplodeFile(EPNodePtr ptr) {
     /* [<][>][^][v][top][bottom][index][help] */
1145   char *strArgs[10];
1146   char Args0[100];
1147   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100],
1148     Args6[100];
1149   int gpg_pid;
1150   int gpg_in_fd, out_fd, err_fd;
1151   int status;
1152   char txt[LINE_LENGTH];
1153   /* char hostname[MAXHOSTNAMELEN]; */
1154   char oFile[FILENAME_LENGTH];
1155   char *keyStr;
1156   /* int childRC; */
1157   FILE *mystdin;
1158 
1159   sprintf(oFile, "%s.%d.exp", ptr->file, ptr->nodeID);
1160 
1161   strcpy(Args0, "--no-secmem-warning");
1162   strcpy(Args1, "--keyring");
1163   strcpy(Args2, keyRing);
1164   strcpy(Args3, "-o");
1165   strcpy(Args4, oFile);
1166   strcpy(Args5, "-d");
1167   strcpy(Args6, ptr->file);
1168   strArgs[6] = Args6;
1169   strArgs[7] = (char *)0;
1170   
1171   strArgs[0] = Args0;
1172   strArgs[1] = Args1;  
1173   strArgs[2] = Args2;  
1174   strArgs[3] = Args3;
1175   strArgs[4] = Args4;
1176   strArgs[5] = Args5;
1177   
1178   gpg_in_fd = INPUT_FD;
1179   out_fd = OUTPUT_FD;
1180   err_fd = ERROR_FD;
1181 
1182   if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
1183                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
1184       ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
1185       exit(1);
1186   }
1187   
1188   if (waitpid (gpg_pid, &status, 0) < 0) {
1189     ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
1190     exit(1);
1191   }
1192   if (WIFEXITED(status) == 0) {
1193     ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
1194     exit(1);
1195   }
1196   else {
1197   }
1198 
1199 
1200   /* Parsing gpg output */
1201   mystdin = fdopen(0, "r");
1202   ptr->isValidPGPSignature = vS_KO;
1203   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
1204     {
1205       /*        printf ( "GPG output : %s\n", txt );   */
1206       if (strstr(txt, "Good signature") != NULL)
1207         ptr->isValidPGPSignature = vS_IS_VALID;
1208 
1209       if (strstr(txt, "CRC error") != NULL)
1210         ptr->isValidPGPSignature = vS_CRC_ERROR;
1211 
1212       if (strstr(txt, "public key not found") != NULL)
1213         ptr->isValidPGPSignature = vS_NO_PUBLIC_KEY;
1214 
1215       if (strstr(txt, "no valid OpenPGP data found") != NULL)
1216         ptr->isValidPGPSignature = vS_NO_OPENPGP_DATA;
1217 
1218       if ((keyStr = strstr(txt, "key ID")) != NULL) {
1219         keyStr += 7;
1220         sscanf(keyStr, "%8X\n", &ptr->keyID);
1221       }
1222     }
1223     
1224   if (ptr->isValidPGPSignature == vS_NO_OPENPGP_DATA) {
1225     FILE* f;
1226     f= fopen(oFile, "w");
1227     fprintf(f, " \n");
1228     fclose(f);
1229   }
1230 
1231   unlink(ptr->file);
1232   UT_free(ptr->file);
1233   ptr->file = UT_strdup(oFile);
1234   if (sd1[0] != 0)  close ( sd1[0] ); 
1235 }
1236 
1237 
1238 /*++++++++++++++++++++++++++++
1239 
1240 Get the KeyID of a PGP key.
1241 
1242 struct ImportKeyObject *iKO     The structure containing the key of which we want the KeyID
1243 
1244 ++++++++++++++++++++++++++++*/
1245 
1246 void GetKeyID(struct ImportKeyObject *iKO) {
     /* [<][>][^][v][top][bottom][index][help] */
1247   
1248   char *strArgs[9];
1249   char Args0[100];
1250   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
1251   int gpg_pid;
1252   int gpg_in_fd, out_fd, err_fd;
1253   int status;
1254   char txt[LINE_LENGTH];
1255   char *keyStr, *pos;
1256   const char lockFilename[] = ".PAlock";
1257   char keyRingLockFile[1000], keyRingPath[1000];
1258   time_t lockBirthDate;
1259   FILE *mystdin;
1260   int childRC;
1261 
1262   iKO->rc = iKO_GENERALFAILURE;
1263 
1264   strcpy(Args0, "--no-tty");
1265   strcpy(Args1, "--no-secmem-warning");
1266   strcpy(Args2, "--keyring");
1267   strcpy(Args3, iKO->keyRing);
1268   strcpy(Args4, "--import");
1269   strcpy(Args5, iKO->iFilename);
1270 
1271   strArgs[0] = Args0;  
1272   strArgs[1] = Args1;  
1273   strArgs[2] = Args2;  
1274   strArgs[3] = Args3;  
1275   strArgs[4] = Args4;  
1276   strArgs[5] = Args5;
1277   strArgs[6] = (char *)0;
1278 
1279   gpg_in_fd = INPUT_FD;
1280   out_fd = OUTPUT_FD;
1281   err_fd = ERROR_FD;
1282 
1283   /* create lock file filenames for NFS */
1284 
1285   strcpy(keyRingLockFile, iKO->keyRing);
1286   if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
1287     strcpy(pos + 1, lockFilename);
1288     strcpy(keyRingPath, keyRingLockFile);
1289     keyRingPath[pos - keyRingLockFile] = 0;
1290   } else {
1291     strcpy(keyRingLockFile, lockFilename);
1292     strcpy(keyRingPath, "");
1293   }
1294   
1295   lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
1296 
1297   if ( ( gpg_pid = spawn_job (gpgCmd, strArgs,
1298                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
1299     ER_perror(FAC_PA, PA_CANTSPWN, "gpg");
1300     exit(1);
1301   }
1302   
1303   if (waitpid (gpg_pid, &status, 0) < 0)
1304     {
1305       ER_perror(FAC_PA, PA_REAP, "gpg process: %s", ERRSTRING);
1306       nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
1307       exit(1);
1308     }
1309 
1310   nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
1311 
1312   if (WIFEXITED(status) == 0)
1313     {
1314       ER_perror(FAC_PA, PA_CHST, "%d - %s", status, ERRSTRING);
1315       exit(1);
1316     } else {
1317       /* Child exited, checking return code */
1318       childRC = (status & 0xF00) >> 8;
1319       if (childRC == 1) {
1320         ER_perror(FAC_PA, PA_CHRC, "%d", childRC);
1321         exit(1);
1322       }
1323     }
1324 
1325 
1326   /* Parsing gpg output */
1327   /*   while (read(0, txt, 1000) != 0)
1328        fprintf(stderr, "child read %s\n", txt); */
1329 
1330   mystdin = fdopen(0, "r");
1331   iKO->rc = iKO_GENERALFAILURE;
1332   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
1333     {
1334       /*          printf ( "GPG output : %s\n", txt );      */
1335 
1336       if ((keyStr = strstr(txt, "imported")) != NULL) {
1337         iKO->rc = iKO_OK;
1338       }
1339 
1340       if ((keyStr = strstr(txt, "CRC error")) != NULL) {
1341         iKO->rc = iKO_CRC_ERROR;
1342       }
1343 
1344       if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) {
1345         iKO->rc = iKO_NO_OPENPGP_DATA;
1346       }
1347 
1348       if (((keyStr = strstr(txt, "unchanged")) != NULL) || 
1349           ((keyStr = strstr(txt, "not changed")) != NULL)) {
1350         iKO->rc = iKO_UNCHANGED;
1351       }
1352 
1353       if ((keyStr = strstr(txt, "gpg: key ")) != NULL) {
1354          keyStr += 9;
1355          sscanf(keyStr, "%8X\n", &iKO->keyID); 
1356       } 
1357     }
1358 
1359   if (sd1[0] != 0)  close ( sd1[0] ); 
1360 
1361 }
1362 

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