modules/pa/gpg.c

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

FUNCTIONS

This source file includes following functions.
  1. PA_VerifySignature
  2. PA_Decrypt
  3. PA_ImportKey
  4. PA_RemoveKey
  5. PA_RemoveKey_withKeyID
  6. PA_ParseMessage
  7. GetFingerPrint
  8. GetKeyOwner
  9. VerifySignAndExplodeFile
  10. GetKeyID

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

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