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 | /* ------------------------------------------------- */ 21 | void GetFingerPrint(struct ImportKeyObject *iKO) { 22 | 23 | char *strArgs[9]; 24 | char Args0[100] ; 25 | char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100]; 26 | int gpg_pid; 27 | int gpg_in_fd, out_fd, err_fd; 28 | int status; 29 | char txt[LINE_LENGTH]; 30 | char *keyStr; 31 | FILE *mystdin; 32 | int childRC; 33 | 34 | strcpy(Args0, "--no-tty"); 35 | strcpy(Args1, "--no-secmem-warning"); 36 | strcpy(Args2, "--keyring"); 37 | strcpy(Args3, iKO->keyRing); 38 | strcpy(Args4, "--fingerprint"); 39 | sprintf(Args5, "%08lX", iKO->keyID); 40 | 41 | strArgs[0] = Args0; 42 | strArgs[1] = Args1; 43 | strArgs[2] = Args2; 44 | strArgs[3] = Args3; 45 | strArgs[4] = Args4; 46 | strArgs[5] = Args5; 47 | strArgs[6] = (char *)0; 48 | 49 | gpg_in_fd = INPUT_FD; 50 | out_fd = OUTPUT_FD; 51 | err_fd = ERROR_FD; 52 | 53 | /* create lock file filenames for NFS */ 54 | 55 | if ( ( gpg_pid = spawn_job ("gpg", strArgs, 56 | &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) { 57 | printf ("could not spawn gpg"); 58 | exit(1); 59 | } 60 | 61 | if (waitpid (gpg_pid, &status, 0) < 0) 62 | { 63 | fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING); 64 | printf ("could not reap gpg process"); 65 | exit(1); 66 | } 67 | 68 | if (WIFEXITED(status) == 0) 69 | { 70 | fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING); 71 | printf ("gpg failure"); 72 | exit(1); 73 | } else { 74 | /* Child exited, checking return code */ 75 | childRC = (status & 0xF00) >> 8; 76 | if (childRC == 1) { 77 | fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC); 78 | printf ("gpg failure\n"); 79 | exit(1); 80 | } 81 | } 82 | 83 | 84 | mystdin = fdopen(0, "r"); 85 | while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL) 86 | { 87 | /* printf ( "GPG output : %s\n", txt ); */ 88 | 89 | if ((keyStr = strstr(txt, "Key fingerprint =")) != NULL) { 90 | strcpy(iKO->fingerPrint, keyStr + 18); 91 | iKO->fingerPrint[strlen(iKO->fingerPrint)-1] = 0; 92 | } 93 | 94 | if ((keyStr = strstr(txt, "key")) != NULL) { 95 | keyStr += 4; 96 | sscanf(keyStr, "%8X\n", &iKO->keyID); 97 | } 98 | } 99 | 100 | if (sd1[0] != 0) close ( sd1[0] ); 101 | } 102 | 103 | /* ------------------------------------------------- */ 104 | 105 | void ParseInputFile(struct VerifySignObject *vSO) { 106 | FILE *fin, *fout; 107 | char txt[LINE_LENGTH]; 108 | char keyRing[LINE_LENGTH]; 109 | char outputPath[LINE_LENGTH]; 110 | const char PGP_prefix[] = "-----BEGIN PGP "; 111 | const char PGP_suffix[] = "-----END PGP "; 112 | int found_prefix = 0, nMsgs = 0, outFileOpened = 0, clearTextBlock = 1; 113 | char foutName[100]; 114 | struct VerifySignObject *vSOList = vSO; 115 | 116 | strcpy(keyRing, vSO->keyRing); 117 | strcpy(outputPath, vSO->outputPath); 118 | 119 | if (!strcmp(vSOList->iSigFilename, "")) { 120 | if ((fin = fopen(vSOList->iDocSigFilename, "r")) != NULL) { 121 | 122 | while (fgets (txt, LINE_LENGTH - 1, fin) != NULL) { 123 | 124 | /* Looking for PGP prefix */ 125 | if ((strstr(txt, PGP_prefix) != NULL) && !found_prefix) { 126 | clearTextBlock = 0; 127 | found_prefix = 1; 128 | /* remember to delete those files */ 129 | sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs); 130 | if ((fout = fopen(foutName, "w")) == NULL ) { 131 | vSOList->isValid = vSO_NO_OUT_FILES; 132 | return; 133 | } 134 | outFileOpened = 1; 135 | vSOList->next = malloc(sizeof(struct VerifySignObject)); 136 | vSOList = vSOList->next; 137 | strcpy(vSOList->iDocSigFilename, foutName); 138 | strcpy(vSOList->keyRing, keyRing); 139 | strcpy(vSOList->outputPath, outputPath); 140 | vSOList->next = NULL; 141 | } else 142 | if ((strstr(txt, PGP_suffix) != NULL ) && found_prefix) { 143 | found_prefix = 0; 144 | clearTextBlock = 1; 145 | fputs(txt, fout); 146 | fclose(fout); 147 | outFileOpened = 0; 148 | nMsgs++; 149 | } else 150 | if (clearTextBlock && !outFileOpened) { 151 | sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs); 152 | if ((fout = fopen(foutName, "w")) == NULL ) { 153 | vSOList->isValid = vSO_NO_OUT_FILES; 154 | return; 155 | } 156 | outFileOpened = 1; 157 | vSOList->next = malloc(sizeof(struct VerifySignObject)); 158 | vSOList = vSOList->next; 159 | strcpy(vSOList->iDocSigFilename, foutName); 160 | strcpy(vSOList->keyRing, ""); 161 | strcpy(vSOList->outputPath, outputPath); 162 | vSOList->next = NULL; 163 | } 164 | if (outFileOpened) { 165 | fputs(txt, fout); 166 | } 167 | } 168 | if (outFileOpened) { 169 | fclose(fout); 170 | } 171 | fclose(fin); 172 | } else { 173 | vSOList->isValid = vSO_NO_IN_FILES; 174 | } 175 | } 176 | } 177 | 178 | /* ------------------------------------------------- */ 179 | 180 | void VerifySignature(struct VerifySignObject *vSO) { 181 | char *strArgs[10]; 182 | char Args0[100]; 183 | char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100], 184 | Args6[100], Args7[100]; 185 | int gpg_pid; 186 | int gpg_in_fd, out_fd, err_fd; 187 | int status; 188 | static int nMsgs = 0; 189 | char txt[LINE_LENGTH]; 190 | char *keyStr; 191 | struct VerifySignObject *pvSO = vSO->next; 192 | int childRC; 193 | 194 | while (pvSO != NULL) { 195 | nMsgs++; 196 | /* Copy the incoming object on the internal global object */ 197 | /* memmove( &verifySignObj, pvSO, sizeof(struct VerifySignObject) ); */ 198 | 199 | sprintf(pvSO->oStream, "%s/PAtmp.%ld.%ld.%d", pvSO->outputPath, 200 | labs(gethostid()), getpid(), nMsgs); 201 | 202 | strcpy(Args0, "--no-secmem-warning"); 203 | strcpy(Args1, "--keyring"); 204 | strcpy(Args2, pvSO->keyRing); 205 | strcpy(Args3, "-o"); 206 | strcpy(Args4, pvSO->oStream); 207 | strcpy(Args5, "-d"); 208 | if (!strcmp(pvSO->iSigFilename, "")) { 209 | strcpy(Args6, pvSO->iDocSigFilename); 210 | strArgs[6] = Args6; 211 | strArgs[7] = (char *)0; 212 | } else { 213 | strcpy(Args6, pvSO->iSigFilename); 214 | strcpy(Args7, pvSO->iDocSigFilename); 215 | strArgs[6] = Args6; 216 | strArgs[7] = Args7; 217 | strArgs[8] = (char *)0; 218 | } 219 | 220 | strArgs[0] = Args0; 221 | strArgs[1] = Args1; 222 | strArgs[2] = Args2; 223 | strArgs[3] = Args3; 224 | strArgs[4] = Args4; 225 | strArgs[5] = Args5; 226 | 227 | gpg_in_fd = INPUT_FD; 228 | out_fd = OUTPUT_FD; 229 | err_fd = ERROR_FD; 230 | if ( ( gpg_pid = spawn_job ("gpg", strArgs, 231 | &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) 232 | { 233 | printf ("could not spawn gpg"); 234 | exit(1); 235 | } 236 | 237 | if (waitpid (gpg_pid, &status, 0) < 0) 238 | { 239 | fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING); 240 | printf ("could not reap gpg process"); 241 | exit(1); 242 | } 243 | if (WIFEXITED(status) == 0) 244 | { 245 | fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING); 246 | printf ("gpg failure\n"); 247 | exit(1); 248 | } else { 249 | /* Child exited, checking return code */ 250 | childRC = (status & 0xF00) >> 8; 251 | if (childRC == 1) { 252 | fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC); 253 | printf ("gpg failure\n"); 254 | exit(1); 255 | } 256 | } 257 | 258 | 259 | /* Parsing gpg output */ 260 | pvSO->isValid = vSO_KO; 261 | while (fgets (txt, LINE_LENGTH - 1, stdin) != NULL) 262 | { 263 | /* printf ( "GPG output : %s\n", txt ); */ 264 | if (strstr(txt, "Good signature") != NULL) 265 | pvSO->isValid = vSO_IS_VALID; 266 | 267 | if (strstr(txt, "CRC error") != NULL) 268 | pvSO->isValid = vSO_CRC_ERROR; 269 | 270 | if (strstr(txt, "public key not found") != NULL) 271 | pvSO->isValid = vSO_NO_PUBLIC_KEY; 272 | 273 | if (strstr(txt, "no valid OpenPGP data found") != NULL) 274 | pvSO->isValid = vSO_NO_OPENPGP_DATA; 275 | 276 | if ((keyStr = strstr(txt, "key ID")) != NULL) { 277 | keyStr += 7; 278 | sscanf(keyStr, "%8X\n", &pvSO->keyID); 279 | } 280 | } 281 | 282 | unlink(pvSO->iDocSigFilename); 283 | pvSO = pvSO->next; 284 | } 285 | if (sd1[0] != 0) close ( sd1[0] ); 286 | } 287 | 288 | /* ------------------------------------------------- */ 289 | 290 | void PA_VerifySignature(struct VerifySignObject *vSO) { 291 | 292 | /* split input file if there are multiple signed messages */ 293 | ParseInputFile( vSO ); 294 | 295 | /* Verify each single PGP mesg */ 296 | VerifySignature( vSO ); 297 | 298 | } 299 | 300 | /* ------------------------------------------------- */ 301 | 302 | void PA_Decrypt(struct ReadCryptedObject *rDO) { 303 | 304 | char *strArgs[9]; 305 | char clearTextExtension[4] = ".gpg"; 306 | char Args0[100]; 307 | char Args1[100]; 308 | char Args2[100]; 309 | char Args3[100]; 310 | char Args4[100]; 311 | char Args5[100]; 312 | char Args6[100]; 313 | int gpg_pid; 314 | int gpg_in_fd, out_fd, err_fd; 315 | int status; 316 | char txt[LINE_LENGTH]; 317 | int childRC; 318 | 319 | strcpy(Args0, "--no-tty"); 320 | strcpy(Args1, "--no-secmem-warning"); 321 | strcpy(Args2, "--keyring"); 322 | strcpy(Args3, rDO->keyRing); 323 | strcpy(Args4, "--output"); 324 | strcpy(Args5, strcat(rDO->iFilename, clearTextExtension)); 325 | strcpy(Args6, rDO->iFilename); 326 | 327 | strArgs[0] = Args0; 328 | strArgs[1] = Args1; 329 | strArgs[2] = Args2; 330 | strArgs[3] = Args3; 331 | strArgs[4] = Args4; 332 | strArgs[5] = Args5; 333 | strArgs[6] = Args6; 334 | strArgs[7] = (char *) 0; 335 | 336 | gpg_in_fd = INPUT_FD; 337 | out_fd = OUTPUT_FD; 338 | err_fd = ERROR_FD; 339 | if ( ( gpg_pid = spawn_job ("gpg", strArgs, 340 | &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) 341 | { 342 | printf ("could not spawn gpg"); 343 | exit(1); 344 | } 345 | 346 | if (waitpid (gpg_pid, &status, 0) < 0) 347 | { 348 | fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING); 349 | printf ("could not reap gpg process"); 350 | exit(1); 351 | } 352 | if (WIFEXITED(status) == 0) 353 | { 354 | fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING); 355 | printf ("gpg failure"); 356 | exit(1); 357 | } else { 358 | /* Child exited, checking return code */ 359 | childRC = (status & 0xF00) >> 8; 360 | if (childRC == 1) { 361 | fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC); 362 | printf ("gpg failure\n"); 363 | exit(1); 364 | } 365 | } 366 | 367 | 368 | /* Parsing gpg output */ 369 | while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL) 370 | { 371 | 372 | } 373 | 374 | if (sd1[0] != 0) close ( sd1[0] ); 375 | } 376 | 377 | 378 | /* ------------------------------------------------- */ 379 | 380 | void PA_ImportKey(struct ImportKeyObject *iKO) { 381 | 382 | char *strArgs[9]; 383 | char Args0[100]; 384 | char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100]; 385 | int gpg_pid; 386 | int gpg_in_fd, out_fd, err_fd; 387 | int status; 388 | char txt[LINE_LENGTH]; 389 | char *keyStr, *pos; 390 | const char lockFilename[] = ".PAlock"; 391 | char keyRingLockFile[1000], keyRingPath[1000]; 392 | time_t lockBirthDate; 393 | FILE *mystdin; 394 | int childRC; 395 | 396 | iKO->rc = iKO_GENERALFAILURE; 397 | 398 | strcpy(Args0, "--no-tty"); 399 | strcpy(Args1, "--no-secmem-warning"); 400 | strcpy(Args2, "--keyring"); 401 | strcpy(Args3, iKO->keyRing); 402 | strcpy(Args4, "--import"); 403 | strcpy(Args5, iKO->iFilename); 404 | 405 | strArgs[0] = Args0; 406 | strArgs[1] = Args1; 407 | strArgs[2] = Args2; 408 | strArgs[3] = Args3; 409 | strArgs[4] = Args4; 410 | strArgs[5] = Args5; 411 | strArgs[6] = (char *)0; 412 | 413 | gpg_in_fd = INPUT_FD; 414 | out_fd = OUTPUT_FD; 415 | err_fd = ERROR_FD; 416 | 417 | /* create lock file filenames for NFS */ 418 | 419 | strcpy(keyRingLockFile, iKO->keyRing); 420 | if ((pos = strrchr(keyRingLockFile, '/')) != NULL) { 421 | strcpy(pos + 1, lockFilename); 422 | strcpy(keyRingPath, keyRingLockFile); 423 | keyRingPath[pos - keyRingLockFile] = 0; 424 | } else { 425 | strcpy(keyRingLockFile, lockFilename); 426 | strcpy(keyRingPath, ""); 427 | } 428 | 429 | lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0); 430 | 431 | if ( ( gpg_pid = spawn_job ("gpg", strArgs, 432 | &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) { 433 | printf ("could not spawn gpg"); 434 | exit(1); 435 | } 436 | 437 | if (waitpid (gpg_pid, &status, 0) < 0) 438 | { 439 | fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING); 440 | nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate); 441 | printf ("could not reap gpg process"); 442 | exit(1); 443 | } 444 | 445 | nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate); 446 | 447 | if (WIFEXITED(status) == 0) 448 | { 449 | fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING); 450 | printf ("gpg failure"); 451 | } else { 452 | /* Child exited, checking return code */ 453 | childRC = (status & 0xF00) >> 8; 454 | if (childRC == 1) { 455 | fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC); 456 | printf ("gpg failure\n"); 457 | exit(1); 458 | } 459 | } 460 | 461 | 462 | /* Parsing gpg output */ 463 | /* while (read(0, txt, 1000) != 0) 464 | fprintf(stderr, "child read %s\n", txt); */ 465 | 466 | mystdin = fdopen(0, "r"); 467 | iKO->rc = iKO_GENERALFAILURE; 468 | while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL) 469 | { 470 | /* printf ( "GPG output : %s\n", txt ); */ 471 | 472 | if ((keyStr = strstr(txt, "imported")) != NULL) { 473 | iKO->rc = iKO_OK; 474 | } 475 | 476 | if ((keyStr = strstr(txt, "CRC error")) != NULL) { 477 | iKO->rc = iKO_CRC_ERROR; 478 | } 479 | 480 | if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) { 481 | iKO->rc = iKO_NO_OPENPGP_DATA; 482 | } 483 | 484 | if (((keyStr = strstr(txt, "unchanged")) != NULL) || 485 | ((keyStr = strstr(txt, "not changed")) != NULL)) { 486 | iKO->rc = iKO_UNCHANGED; 487 | } 488 | 489 | if ((keyStr = strstr(txt, "key")) != NULL) { 490 | keyStr += 4; 491 | sscanf(keyStr, "%8X\n", &iKO->keyID); 492 | } 493 | } 494 | 495 | if (sd1[0] != 0) close ( sd1[0] ); 496 | 497 | /* Get the finger print */ 498 | 499 | GetFingerPrint(iKO); 500 | } 501 | 502 | /* ------------------------------------------------- */ 503 | 504 | void GetKeyID(struct ImportKeyObject *iKO) { 505 | 506 | char *strArgs[9]; 507 | char Args0[100]; 508 | char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100]; 509 | int gpg_pid; 510 | int gpg_in_fd, out_fd, err_fd; 511 | int status; 512 | char txt[LINE_LENGTH]; 513 | char *keyStr, *pos; 514 | const char lockFilename[] = ".PAlock"; 515 | char keyRingLockFile[1000], keyRingPath[1000]; 516 | time_t lockBirthDate; 517 | FILE *mystdin; 518 | int childRC; 519 | 520 | iKO->rc = iKO_GENERALFAILURE; 521 | 522 | strcpy(Args0, "--no-tty"); 523 | strcpy(Args1, "--no-secmem-warning"); 524 | strcpy(Args2, "--keyring"); 525 | strcpy(Args3, iKO->keyRing); 526 | strcpy(Args4, "--import"); 527 | strcpy(Args5, iKO->iFilename); 528 | 529 | strArgs[0] = Args0; 530 | strArgs[1] = Args1; 531 | strArgs[2] = Args2; 532 | strArgs[3] = Args3; 533 | strArgs[4] = Args4; 534 | strArgs[5] = Args5; 535 | strArgs[6] = (char *)0; 536 | 537 | gpg_in_fd = INPUT_FD; 538 | out_fd = OUTPUT_FD; 539 | err_fd = ERROR_FD; 540 | 541 | /* create lock file filenames for NFS */ 542 | 543 | strcpy(keyRingLockFile, iKO->keyRing); 544 | if ((pos = strrchr(keyRingLockFile, '/')) != NULL) { 545 | strcpy(pos + 1, lockFilename); 546 | strcpy(keyRingPath, keyRingLockFile); 547 | keyRingPath[pos - keyRingLockFile] = 0; 548 | } else { 549 | strcpy(keyRingLockFile, lockFilename); 550 | strcpy(keyRingPath, ""); 551 | } 552 | 553 | lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0); 554 | 555 | if ( ( gpg_pid = spawn_job ("gpg", strArgs, 556 | &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) { 557 | printf ("could not spawn gpg"); 558 | exit(1); 559 | } 560 | 561 | if (waitpid (gpg_pid, &status, 0) < 0) 562 | { 563 | fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING); 564 | printf ("could not reap gpg process"); 565 | nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate); 566 | exit(1); 567 | } 568 | 569 | nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate); 570 | 571 | if (WIFEXITED(status) == 0) 572 | { 573 | fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING); 574 | printf ("gpg failure"); 575 | exit(1); 576 | } else { 577 | /* Child exited, checking return code */ 578 | childRC = (status & 0xF00) >> 8; 579 | if (childRC == 1) { 580 | fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC); 581 | printf ("gpg failure\n"); 582 | exit(1); 583 | } 584 | } 585 | 586 | 587 | /* Parsing gpg output */ 588 | /* while (read(0, txt, 1000) != 0) 589 | fprintf(stderr, "child read %s\n", txt); */ 590 | 591 | mystdin = fdopen(0, "r"); 592 | iKO->rc = iKO_GENERALFAILURE; 593 | while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL) 594 | { 595 | /* printf ( "GPG output : %s\n", txt ); */ 596 | 597 | if ((keyStr = strstr(txt, "imported")) != NULL) { 598 | iKO->rc = iKO_OK; 599 | } 600 | 601 | if ((keyStr = strstr(txt, "CRC error")) != NULL) { 602 | iKO->rc = iKO_CRC_ERROR; 603 | } 604 | 605 | if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) { 606 | iKO->rc = iKO_NO_OPENPGP_DATA; 607 | } 608 | 609 | if (((keyStr = strstr(txt, "unchanged")) != NULL) || 610 | ((keyStr = strstr(txt, "not changed")) != NULL)) { 611 | iKO->rc = iKO_UNCHANGED; 612 | } 613 | 614 | if ((keyStr = strstr(txt, "gpg: key ")) != NULL) { 615 | keyStr += 9; 616 | sscanf(keyStr, "%8X\n", &iKO->keyID); 617 | } 618 | } 619 | 620 | if (sd1[0] != 0) close ( sd1[0] ); 621 | 622 | } 623 | 624 | /* ------------------------------------------------- */ 625 | 626 | void PA_RemoveKey(struct ImportKeyObject *iKO) { 627 | 628 | char *strArgs[9]; 629 | char Args0[100]= "gpg"; 630 | char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100], Args6[100], Args7[100]; 631 | int gpg_pid; 632 | int gpg_in_fd, out_fd, err_fd; 633 | int status; 634 | char txt[LINE_LENGTH]; 635 | char *keyStr, *pos; 636 | const char lockFilename[] = ".PAlock"; 637 | char keyRingLockFile[1000], keyRingPath[1000]; 638 | time_t lockBirthDate; 639 | FILE *mystdin; 640 | int childRC; 641 | 642 | iKO->rc = iKO_GENERALFAILURE; 643 | 644 | GetKeyID(iKO); /* getting key-id */ 645 | 646 | /* printf("Key id = %08lX\n", iKO->keyID); */ 647 | 648 | if ((iKO->rc == iKO_OK) || (iKO->rc == iKO_UNCHANGED)) { 649 | strcpy(Args1, "--batch"); 650 | strcpy(Args2, "--yes"); 651 | strcpy(Args3, "--no-secmem-warning"); 652 | strcpy(Args4, "--keyring"); 653 | strcpy(Args5, iKO->keyRing); 654 | strcpy(Args6, "--delete-key"); 655 | sprintf(Args7, "%08lX", iKO->keyID); 656 | 657 | strArgs[0] = Args0; 658 | strArgs[1] = Args1; 659 | strArgs[2] = Args2; 660 | strArgs[3] = Args3; 661 | strArgs[4] = Args4; 662 | strArgs[5] = Args5; 663 | strArgs[6] = Args6; 664 | strArgs[7] = Args7; 665 | strArgs[8] = (char *)0; 666 | 667 | 668 | gpg_in_fd = INPUT_FD; 669 | out_fd = OUTPUT_FD; 670 | err_fd = ERROR_FD; 671 | 672 | /* create lock file filenames for NFS */ 673 | 674 | strcpy(keyRingLockFile, iKO->keyRing); 675 | if ((pos = strrchr(keyRingLockFile, '/')) != NULL) { 676 | strcpy(pos + 1, lockFilename); 677 | strcpy(keyRingPath, keyRingLockFile); 678 | keyRingPath[pos - keyRingLockFile] = 0; 679 | } else { 680 | strcpy(keyRingLockFile, lockFilename); 681 | strcpy(keyRingPath, ""); 682 | } 683 | 684 | lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0); 685 | 686 | if ( ( gpg_pid = spawn_job ("/usr/local/bin/gpg", strArgs, 687 | &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) { 688 | printf ("could not spawn gpg"); 689 | exit(1); 690 | } 691 | 692 | /* printf("Child pid = %d\n", gpg_pid); */ 693 | 694 | if (waitpid (gpg_pid, &status, 0) < 0) 695 | { 696 | fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING); 697 | printf ("could not reap gpg process"); 698 | exit(1); 699 | } 700 | 701 | nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate); 702 | 703 | if (WIFEXITED(status) == 0) 704 | { 705 | fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING); 706 | printf ("gpg failure"); 707 | exit(1); 708 | } else { 709 | /* Child exited, checking return code */ 710 | childRC = (status & 0xF00) >> 8; 711 | if (childRC == 1) { 712 | fprintf (stderr, "Fatal: gpg child return code: %d\n", childRC); 713 | printf ("gpg failure\n"); 714 | exit(1); 715 | } 716 | } 717 | 718 | 719 | mystdin = fdopen(0, "r"); 720 | iKO->rc = iKO_OK; 721 | while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL) 722 | { 723 | /* printf ( "GPG output : %s\n", txt ); */ 724 | 725 | if ((keyStr = strstr(txt, "delete key failed")) != NULL) { 726 | iKO->rc = iKO_GENERALFAILURE; 727 | } 728 | if ((keyStr = strstr(txt, "there is a secret key for this public key")) != NULL) { 729 | iKO->rc = iKO_SECRET_KEY_PRESENT; 730 | } 731 | 732 | } 733 | 734 | if (sd1[0] != 0) close ( sd1[0] ); 735 | } 736 | }