diff options
| author | guenther <> | 2015-02-22 22:29:40 +0000 |
|---|---|---|
| committer | guenther <> | 2015-02-22 22:29:40 +0000 |
| commit | 2820d04ee847cb7bede0b25e49194c3ade7ebdbf (patch) | |
| tree | 3c525a8cd1f84e7ea69c4187584960c6859caf30 | |
| parent | b88519f93bce16ae710fb69c935df87dc60ea8f4 (diff) | |
| download | openbsd-2820d04ee847cb7bede0b25e49194c3ade7ebdbf.tar.gz openbsd-2820d04ee847cb7bede0b25e49194c3ade7ebdbf.tar.bz2 openbsd-2820d04ee847cb7bede0b25e49194c3ade7ebdbf.zip | |
While slick, this isn't accessing multiple directories concurrently, so
using *at functions is equivalent to chdir()ing, which eases portability.
Tested with mixes of absolute and relative paths.
Eliminate a FILE leak too.
prodded by jsing@
Diffstat (limited to '')
| -rw-r--r-- | src/usr.bin/openssl/certhash.c | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/src/usr.bin/openssl/certhash.c b/src/usr.bin/openssl/certhash.c index 2e64ffaac7..992ef31cd5 100644 --- a/src/usr.bin/openssl/certhash.c +++ b/src/usr.bin/openssl/certhash.c | |||
| @@ -470,21 +470,21 @@ certhash_merge(struct hashinfo **links, struct hashinfo **certs, | |||
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | static int | 472 | static int |
| 473 | certhash_link(int dfd, struct dirent *dep, struct hashinfo **links) | 473 | certhash_link(struct dirent *dep, struct hashinfo **links) |
| 474 | { | 474 | { |
| 475 | struct hashinfo *hi = NULL; | 475 | struct hashinfo *hi = NULL; |
| 476 | char target[MAXPATHLEN]; | 476 | char target[MAXPATHLEN]; |
| 477 | struct stat sb; | 477 | struct stat sb; |
| 478 | int n; | 478 | int n; |
| 479 | 479 | ||
| 480 | if (fstatat(dfd, dep->d_name, &sb, AT_SYMLINK_NOFOLLOW) == -1) { | 480 | if (lstat(dep->d_name, &sb) == -1) { |
| 481 | fprintf(stderr, "failed to stat %s\n", dep->d_name); | 481 | fprintf(stderr, "failed to stat %s\n", dep->d_name); |
| 482 | return (-1); | 482 | return (-1); |
| 483 | } | 483 | } |
| 484 | if (!S_ISLNK(sb.st_mode)) | 484 | if (!S_ISLNK(sb.st_mode)) |
| 485 | return (0); | 485 | return (0); |
| 486 | 486 | ||
| 487 | n = readlinkat(dfd, dep->d_name, target, sizeof(target) - 1); | 487 | n = readlink(dep->d_name, target, sizeof(target) - 1); |
| 488 | if (n == -1) { | 488 | if (n == -1) { |
| 489 | fprintf(stderr, "failed to readlink %s\n", dep->d_name); | 489 | fprintf(stderr, "failed to readlink %s\n", dep->d_name); |
| 490 | return (-1); | 490 | return (-1); |
| @@ -503,27 +503,24 @@ certhash_link(int dfd, struct dirent *dep, struct hashinfo **links) | |||
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | static int | 505 | static int |
| 506 | certhash_file(int dfd, struct dirent *dep, struct hashinfo **certs, | 506 | certhash_file(struct dirent *dep, struct hashinfo **certs, |
| 507 | struct hashinfo **crls) | 507 | struct hashinfo **crls) |
| 508 | { | 508 | { |
| 509 | struct hashinfo *hi = NULL; | 509 | struct hashinfo *hi = NULL; |
| 510 | int has_cert, has_crl; | 510 | int has_cert, has_crl; |
| 511 | int ffd, ret = -1; | 511 | int ret = -1; |
| 512 | BIO *bio = NULL; | 512 | BIO *bio = NULL; |
| 513 | FILE *f; | 513 | FILE *f; |
| 514 | 514 | ||
| 515 | has_cert = has_crl = 0; | 515 | has_cert = has_crl = 0; |
| 516 | 516 | ||
| 517 | if ((ffd = openat(dfd, dep->d_name, O_RDONLY)) == -1) { | 517 | if ((f = fopen(dep->d_name, "r")) == NULL) { |
| 518 | fprintf(stderr, "failed to open %s\n", dep->d_name); | 518 | fprintf(stderr, "failed to fopen %s\n", dep->d_name); |
| 519 | goto err; | ||
| 520 | } | ||
| 521 | if ((f = fdopen(ffd, "r")) == NULL) { | ||
| 522 | fprintf(stderr, "failed to fdopen %s\n", dep->d_name); | ||
| 523 | goto err; | 519 | goto err; |
| 524 | } | 520 | } |
| 525 | if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) { | 521 | if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) { |
| 526 | fprintf(stderr, "failed to create bio\n"); | 522 | fprintf(stderr, "failed to create bio\n"); |
| 523 | fclose(f); | ||
| 527 | goto err; | 524 | goto err; |
| 528 | } | 525 | } |
| 529 | 526 | ||
| @@ -550,8 +547,6 @@ certhash_file(int dfd, struct dirent *dep, struct hashinfo **certs, | |||
| 550 | 547 | ||
| 551 | err: | 548 | err: |
| 552 | BIO_free(bio); | 549 | BIO_free(bio); |
| 553 | if (ffd != -1) | ||
| 554 | close(ffd); | ||
| 555 | 550 | ||
| 556 | return (ret); | 551 | return (ret); |
| 557 | } | 552 | } |
| @@ -560,15 +555,11 @@ static int | |||
| 560 | certhash_directory(const char *path) | 555 | certhash_directory(const char *path) |
| 561 | { | 556 | { |
| 562 | struct hashinfo *links = NULL, *certs = NULL, *crls = NULL, *link; | 557 | struct hashinfo *links = NULL, *certs = NULL, *crls = NULL, *link; |
| 563 | int dfd = -1, ret = 0; | 558 | int ret = 0; |
| 564 | struct dirent *dep; | 559 | struct dirent *dep; |
| 565 | DIR *dip = NULL; | 560 | DIR *dip = NULL; |
| 566 | 561 | ||
| 567 | if ((dfd = open(path, O_DIRECTORY)) == -1) { | 562 | if ((dip = opendir(".")) == NULL) { |
| 568 | fprintf(stderr, "failed to open directory %s\n", path); | ||
| 569 | goto err; | ||
| 570 | } | ||
| 571 | if ((dip = fdopendir(dfd)) == NULL) { | ||
| 572 | fprintf(stderr, "failed to open directory %s\n", path); | 563 | fprintf(stderr, "failed to open directory %s\n", path); |
| 573 | goto err; | 564 | goto err; |
| 574 | } | 565 | } |
| @@ -579,11 +570,11 @@ certhash_directory(const char *path) | |||
| 579 | /* Create lists of existing hash links, certs and CRLs. */ | 570 | /* Create lists of existing hash links, certs and CRLs. */ |
| 580 | while ((dep = readdir(dip)) != NULL) { | 571 | while ((dep = readdir(dip)) != NULL) { |
| 581 | if (filename_is_hash(dep->d_name)) { | 572 | if (filename_is_hash(dep->d_name)) { |
| 582 | if (certhash_link(dfd, dep, &links) == -1) | 573 | if (certhash_link(dep, &links) == -1) |
| 583 | goto err; | 574 | goto err; |
| 584 | } | 575 | } |
| 585 | if (filename_is_pem(dep->d_name)) { | 576 | if (filename_is_pem(dep->d_name)) { |
| 586 | if (certhash_file(dfd, dep, &certs, &crls) == -1) | 577 | if (certhash_file(dep, &certs, &crls) == -1) |
| 587 | goto err; | 578 | goto err; |
| 588 | } | 579 | } |
| 589 | } | 580 | } |
| @@ -604,7 +595,7 @@ certhash_directory(const char *path) | |||
| 604 | "removing"), link->filename, link->target); | 595 | "removing"), link->filename, link->target); |
| 605 | if (certhash_config.dryrun) | 596 | if (certhash_config.dryrun) |
| 606 | continue; | 597 | continue; |
| 607 | if (unlinkat(dfd, link->filename, 0) == -1) { | 598 | if (unlink(link->filename) == -1) { |
| 608 | fprintf(stderr, "failed to remove link %s\n", | 599 | fprintf(stderr, "failed to remove link %s\n", |
| 609 | link->filename); | 600 | link->filename); |
| 610 | goto err; | 601 | goto err; |
| @@ -622,8 +613,7 @@ certhash_directory(const char *path) | |||
| 622 | link->reference->filename); | 613 | link->reference->filename); |
| 623 | if (certhash_config.dryrun) | 614 | if (certhash_config.dryrun) |
| 624 | continue; | 615 | continue; |
| 625 | if (symlinkat(link->reference->filename, dfd, | 616 | if (symlink(link->reference->filename, link->filename) == -1) { |
| 626 | link->filename) == -1) { | ||
| 627 | fprintf(stderr, "failed to create link %s -> %s\n", | 617 | fprintf(stderr, "failed to create link %s -> %s\n", |
| 628 | link->filename, link->reference->filename); | 618 | link->filename, link->reference->filename); |
| 629 | goto err; | 619 | goto err; |
| @@ -642,9 +632,6 @@ done: | |||
| 642 | 632 | ||
| 643 | if (dip != NULL) | 633 | if (dip != NULL) |
| 644 | closedir(dip); | 634 | closedir(dip); |
| 645 | else if (dfd != -1) | ||
| 646 | close(dfd); | ||
| 647 | |||
| 648 | return (ret); | 635 | return (ret); |
| 649 | } | 636 | } |
| 650 | 637 | ||
| @@ -661,7 +648,7 @@ int | |||
| 661 | certhash_main(int argc, char **argv) | 648 | certhash_main(int argc, char **argv) |
| 662 | { | 649 | { |
| 663 | int argsused; | 650 | int argsused; |
| 664 | int i, ret = 0; | 651 | int i, cwdfd, ret = 0; |
| 665 | 652 | ||
| 666 | memset(&certhash_config, 0, sizeof(certhash_config)); | 653 | memset(&certhash_config, 0, sizeof(certhash_config)); |
| 667 | 654 | ||
| @@ -670,8 +657,27 @@ certhash_main(int argc, char **argv) | |||
| 670 | return (1); | 657 | return (1); |
| 671 | } | 658 | } |
| 672 | 659 | ||
| 673 | for (i = argsused; i < argc; i++) | 660 | if ((cwdfd = open(".", O_DIRECTORY)) == -1) { |
| 661 | perror("failed to open current directory"); | ||
| 662 | return (1); | ||
| 663 | } | ||
| 664 | |||
| 665 | for (i = argsused; i < argc; i++) { | ||
| 666 | if (chdir(argv[i]) == -1) { | ||
| 667 | fprintf(stderr, | ||
| 668 | "failed to change to directory %s: %s\n", | ||
| 669 | argv[i], strerror(errno)); | ||
| 670 | ret = 1; | ||
| 671 | continue; | ||
| 672 | } | ||
| 674 | ret |= certhash_directory(argv[i]); | 673 | ret |= certhash_directory(argv[i]); |
| 674 | if (fchdir(cwdfd) == -1) { | ||
| 675 | perror("failed to restore current directory"); | ||
| 676 | ret = 1; | ||
| 677 | break; /* can't continue safely */ | ||
| 678 | } | ||
| 679 | } | ||
| 680 | close(cwdfd); | ||
| 675 | 681 | ||
| 676 | return (ret); | 682 | return (ret); |
| 677 | } | 683 | } |
