modules/pa/gpg.c

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

FUNCTIONS

This source file includes following functions.
  1. ParseInputFile
  2. VerifySignature
  3. PA_VerifySignature
  4. PA_Decrypt
  5. PA_ImportKey

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <string.h>
   4 #include <sys/wait.h>
   5 #include <unistd.h>
   6 #include <errno.h>
   7 #include <sys/types.h>
   8 #include <sys/stat.h>
   9 #include <fcntl.h>
  10 #include <time.h>
  11 
  12 #include "gpg.h"
  13 
  14 extern int sd1[2];
  15 extern int spawn_job (char *path, char *argv[], 
  16                       int *in_fd, int *out_fd, int *err_fd);
  17 extern time_t nfslock(char *path, char *namelock, int max_age, int notify);
  18 extern int nfsunlock(char *path, char *namelock, int max_age, time_t birth);
  19 
  20 void ParseInputFile(struct VerifySignObject *vSO) {
     /* [<][>][^][v][top][bottom][index][help] */
  21   FILE *fin, *fout;
  22   char txt[LINE_LENGTH];
  23   char keyRing[LINE_LENGTH];
  24   char outputPath[LINE_LENGTH];
  25   const char PGP_prefix[] = "-----BEGIN PGP ";
  26   const char PGP_suffix[] = "-----END PGP ";
  27   int found_prefix = 0, nMsgs = 0, outFileOpened = 0, clearTextBlock = 1;
  28   char foutName[100];
  29   struct VerifySignObject *vSOList = vSO;
  30   
  31   strcpy(keyRing, vSO->keyRing);
  32   strcpy(outputPath, vSO->outputPath);
  33 
  34   if (!strcmp(vSOList->iSigFilename, "")) {
  35     if ((fin = fopen(vSOList->iDocSigFilename, "r")) != NULL) { 
  36 
  37       while (fgets (txt, LINE_LENGTH - 1, fin) != NULL) {
  38 
  39       /* Looking for PGP prefix */
  40         if ((strstr(txt, PGP_prefix) != NULL) && !found_prefix) {
  41           clearTextBlock = 0;
  42           found_prefix = 1;
  43           /* remember to delete those files */
  44           sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs);
  45           if ((fout = fopen(foutName, "w")) == NULL ) {
  46             vSOList->isValid = vSO_NO_OUT_FILES;
  47             return;
  48           }
  49           outFileOpened = 1;
  50           vSOList->next = malloc(sizeof(struct VerifySignObject));
  51           vSOList = vSOList->next;
  52           strcpy(vSOList->iDocSigFilename, foutName);
  53           strcpy(vSOList->keyRing, keyRing);
  54           strcpy(vSOList->outputPath, outputPath);
  55           vSOList->next = NULL;
  56         } else
  57           if ((strstr(txt, PGP_suffix) != NULL ) && found_prefix) {
  58             found_prefix = 0;
  59             clearTextBlock = 1;
  60             fputs(txt, fout);
  61             fclose(fout);
  62             outFileOpened = 0;
  63             nMsgs++;
  64           } else 
  65             if (clearTextBlock && !outFileOpened) {
  66               sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs);
  67               if ((fout = fopen(foutName, "w")) == NULL ) {
  68                 vSOList->isValid = vSO_NO_OUT_FILES;
  69                 return;
  70               }
  71               outFileOpened = 1;
  72               vSOList->next = malloc(sizeof(struct VerifySignObject));
  73               vSOList = vSOList->next;
  74               strcpy(vSOList->iDocSigFilename, foutName);
  75               strcpy(vSOList->keyRing, keyRing);
  76               strcpy(vSOList->outputPath, outputPath);
  77               vSOList->next = NULL;
  78             }
  79         if (outFileOpened) {
  80           fputs(txt, fout);
  81         }       
  82       }
  83       if (outFileOpened) {
  84         fclose(fout);
  85       }
  86       fclose(fin);
  87     } else {
  88       vSOList->isValid = vSO_NO_IN_FILES;
  89     }
  90   }
  91 }
  92 
  93 void VerifySignature(struct VerifySignObject *vSO) {
     /* [<][>][^][v][top][bottom][index][help] */
  94   char *strArgs[10];
  95   char Args0[100];
  96   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100],
  97     Args6[100], Args7[100];
  98   int gpg_pid;
  99   int gpg_in_fd, out_fd, err_fd;
 100   int status;
 101   static int nMsgs = 0;
 102   char txt[LINE_LENGTH];
 103   char *keyStr;
 104   struct VerifySignObject *pvSO = vSO->next, *ptmp;
 105 
 106   while (pvSO != NULL) {
 107     nMsgs++;
 108     /* Copy the incoming object on the internal global object */
 109     /* memmove( &verifySignObj, pvSO, sizeof(struct VerifySignObject) ); */
 110 
 111     sprintf(pvSO->oStream, "%s/PAtmp.%ld.%ld.%d", pvSO->outputPath, 
 112             labs(gethostid()), getpid(), nMsgs);
 113 
 114     strcpy(Args0, "--no-secmem-warning");
 115     strcpy(Args1, "--keyring");
 116     strcpy(Args2, pvSO->keyRing);
 117     strcpy(Args3, "-o");
 118     strcpy(Args4, pvSO->oStream);
 119     strcpy(Args5, "-d");
 120     if (!strcmp(pvSO->iSigFilename, "")) {
 121       strcpy(Args6, pvSO->iDocSigFilename);
 122       strArgs[6] = Args6;
 123       strArgs[7] = (char *)0;
 124     } else {
 125       strcpy(Args6, pvSO->iSigFilename);
 126       strcpy(Args7, pvSO->iDocSigFilename);
 127       strArgs[6] = Args6;
 128       strArgs[7] = Args7;
 129       strArgs[8] = (char *)0;
 130     }
 131 
 132     strArgs[0] = Args0;
 133     strArgs[1] = Args1;  
 134     strArgs[2] = Args2;  
 135     strArgs[3] = Args3;
 136     strArgs[4] = Args4;
 137     strArgs[5] = Args5;
 138   
 139     gpg_in_fd = INPUT_FD;
 140     out_fd = OUTPUT_FD;
 141     err_fd = ERROR_FD;
 142     if ( ( gpg_pid = spawn_job ("gpg", strArgs,
 143                                 &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
 144       {
 145         printf ("could not spawn gpg");
 146       }
 147   
 148     if (waitpid (gpg_pid, &status, 0) < 0)
 149       {
 150         fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
 151         printf ("could not reap gpg process");
 152       }
 153     if (WIFEXITED(status) == 0)
 154       {
 155         fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
 156         printf ("gpg failure\n");
 157       }
 158 
 159 
 160     /* Parsing gpg output */
 161     pvSO->isValid = vSO_KO;
 162     while (fgets (txt, LINE_LENGTH - 1, stdin) != NULL)
 163       {
 164         /*      printf ( "GPG output : %s\n", txt );  */
 165         if (strstr(txt, "Good signature") != NULL)
 166           pvSO->isValid = vSO_IS_VALID;
 167 
 168         if (strstr(txt, "CRC error") != NULL)
 169           pvSO->isValid = vSO_CRC_ERROR;
 170 
 171         if (strstr(txt, "public key not found") != NULL)
 172           pvSO->isValid = vSO_NO_PUBLIC_KEY;
 173 
 174         if (strstr(txt, "no valid OpenPGP data found") != NULL)
 175           pvSO->isValid = vSO_NO_OPENPGP_DATA;
 176 
 177         if ((keyStr = strstr(txt, "key ID")) != NULL) {
 178           keyStr += 7;
 179           sscanf(keyStr, "%8X\n", &pvSO->keyID);
 180         }
 181       }
 182     
 183     unlink(pvSO->iDocSigFilename);
 184     pvSO = pvSO->next;
 185   }
 186   if (sd1[0] != 0)  close ( sd1[0] ); 
 187 }
 188 
 189 
 190 /* ------------------------------------------------- */
 191 void PA_VerifySignature(struct VerifySignObject *vSO) {
     /* [<][>][^][v][top][bottom][index][help] */
 192   
 193   /* split input file if there are multiple signed messages */
 194   ParseInputFile( vSO );
 195 
 196   /* Verify each single PGP mesg */
 197   VerifySignature( vSO );
 198 
 199 }
 200 
 201 /* ------------------------------------------------- */
 202 void PA_Decrypt(struct ReadCryptedObject *rDO) {
     /* [<][>][^][v][top][bottom][index][help] */
 203   
 204   char *strArgs[9];
 205   char clearTextExtension[4] = ".gpg";
 206   char Args0[100] = "abracadabra";
 207   char Args1[100];
 208   char Args2[100];
 209   char Args3[100];
 210   char Args4[100];
 211   char Args5[100];
 212   char Args6[100];
 213   int gpg_pid;
 214   int gpg_in_fd, out_fd, err_fd;
 215   int status;
 216   char txt[LINE_LENGTH];
 217 
 218 
 219   strcpy(Args0, "--no-tty");
 220   strcpy(Args1, "--no-secmem-warning");
 221   strcpy(Args2, "--keyring");
 222   strcpy(Args3, rDO->keyRing);
 223   strcpy(Args4, "--output");
 224   strcpy(Args5, strcat(rDO->iFilename, clearTextExtension));
 225   strcpy(Args6, rDO->iFilename);
 226   
 227   strArgs[0] = Args0;
 228   strArgs[1] = Args1;  
 229   strArgs[2] = Args2;  
 230   strArgs[3] = Args3;  
 231   strArgs[4] = Args4;  
 232   strArgs[5] = Args5;  
 233   strArgs[6] = Args6;  
 234   strArgs[7] = (char *) 0;   
 235 
 236   gpg_in_fd = INPUT_FD;
 237   out_fd = OUTPUT_FD;
 238   err_fd = ERROR_FD;
 239   if ( ( gpg_pid = spawn_job ("gpg", strArgs,
 240                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
 241     {
 242       printf ("could not spawn gpg");
 243     }
 244   
 245   if (waitpid (gpg_pid, &status, 0) < 0)
 246     {
 247       fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
 248       printf ("could not reap gpg process");
 249     }
 250   if (WIFEXITED(status) == 0)
 251     {
 252       fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
 253       printf ("gpg failure");
 254     }
 255 
 256 
 257   /* Parsing gpg output */
 258   while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL)
 259     {
 260       
 261     }
 262   
 263   if (sd1[0] != 0)  close ( sd1[0] ); 
 264 }
 265 
 266 
 267 /* ------------------------------------------------- */
 268 void PA_ImportKey(struct ImportKeyObject *iKO) {
     /* [<][>][^][v][top][bottom][index][help] */
 269   
 270   char *strArgs[9];
 271   char Args0[100] = "abracadabra";
 272   char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
 273   int gpg_pid;
 274   int gpg_in_fd, out_fd, err_fd;
 275   int status;
 276   char txt[LINE_LENGTH];
 277   char *keyStr, *pos;
 278   const char lockFilename[] = ".PAlock";
 279   char keyRingLockFile[1000], keyRingPath[1000];
 280   time_t lockBirthDate;
 281   FILE *mystdin;
 282 
 283   iKO->rc = iKO_GENERALFAILURE;
 284 
 285   strcpy(Args0, "--no-tty");
 286   strcpy(Args1, "--no-secmem-warning");
 287   strcpy(Args2, "--keyring");
 288   strcpy(Args3, iKO->keyRing);
 289   strcpy(Args4, "--import");
 290   strcpy(Args5, iKO->iFilename);
 291 
 292   strArgs[0] = Args0;  
 293   strArgs[1] = Args1;  
 294   strArgs[2] = Args2;  
 295   strArgs[3] = Args3;  
 296   strArgs[4] = Args4;  
 297   strArgs[5] = Args5;
 298   strArgs[6] = (char *)0;
 299 
 300   gpg_in_fd = INPUT_FD;
 301   out_fd = OUTPUT_FD;
 302   err_fd = ERROR_FD;
 303 
 304   /* create lock file filenames for NFS */
 305 
 306   strcpy(keyRingLockFile, iKO->keyRing);
 307   if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
 308     strcpy(pos + 1, lockFilename);
 309     strcpy(keyRingPath, keyRingLockFile);
 310     keyRingPath[pos - keyRingLockFile] = 0;
 311   } else {
 312     strcpy(keyRingLockFile, lockFilename);
 313     strcpy(keyRingPath, "");
 314   }
 315   
 316   lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
 317 
 318   if ( ( gpg_pid = spawn_job ("gpg", strArgs,
 319                               &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
 320     printf ("could not spawn gpg");
 321   }
 322   
 323   if (waitpid (gpg_pid, &status, 0) < 0)
 324     {
 325       fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
 326       printf ("could not reap gpg process");
 327     }
 328 
 329   nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
 330 
 331   if (WIFEXITED(status) == 0)
 332     {
 333       fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
 334       printf ("gpg failure");
 335     }
 336 
 337 
 338   /* Parsing gpg output */
 339   /*   while (read(0, txt, 1000) != 0)
 340        fprintf(stderr, "child read %s\n", txt); */
 341 
 342   mystdin = fdopen(0, "r");
 343   iKO->rc = iKO_GENERALFAILURE;
 344   while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
 345     {
 346           printf ( "GPG output : %s\n", txt );     
 347 
 348       if ((keyStr = strstr(txt, "imported")) != NULL) {
 349         iKO->rc = iKO_OK;
 350       }
 351 
 352       if ((keyStr = strstr(txt, "CRC error")) != NULL) {
 353         iKO->rc = iKO_CRC_ERROR;
 354       }
 355 
 356       if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) {
 357         iKO->rc = iKO_NO_OPENPGP_DATA;
 358       }
 359 
 360       if ((keyStr = strstr(txt, "unchanged")) != NULL) {
 361         iKO->rc = iKO_UNCHANGED;
 362       }
 363 
 364       if ((keyStr = strstr(txt, "key")) != NULL) {
 365          keyStr += 4;
 366          sscanf(keyStr, "%8X\n", &iKO->keyID); 
 367       } 
 368     }
 369 
 370   if (sd1[0] != 0)  close ( sd1[0] ); 
 371 }
 372 
 373 

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