summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorguenther <>2015-02-22 22:29:40 +0000
committerguenther <>2015-02-22 22:29:40 +0000
commit2820d04ee847cb7bede0b25e49194c3ade7ebdbf (patch)
tree3c525a8cd1f84e7ea69c4187584960c6859caf30
parentb88519f93bce16ae710fb69c935df87dc60ea8f4 (diff)
downloadopenbsd-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@
-rw-r--r--src/usr.bin/openssl/certhash.c64
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
472static int 472static int
473certhash_link(int dfd, struct dirent *dep, struct hashinfo **links) 473certhash_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
505static int 505static int
506certhash_file(int dfd, struct dirent *dep, struct hashinfo **certs, 506certhash_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
551err: 548err:
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
560certhash_directory(const char *path) 555certhash_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
661certhash_main(int argc, char **argv) 648certhash_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}