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) { 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) { 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) { 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) { 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) { 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 |