## 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] */