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