diff options
Diffstat (limited to 'sbin/md5/md5.c')
-rw-r--r-- | sbin/md5/md5.c | 133 |
1 files changed, 71 insertions, 62 deletions
diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c index 15fd7ebec5d4..10ffae53c775 100644 --- a/sbin/md5/md5.c +++ b/sbin/md5/md5.c @@ -17,7 +17,6 @@ * documentation and/or software. */ -#include <sys/cdefs.h> #include <sys/param.h> #include <sys/resource.h> #include <sys/stat.h> @@ -47,6 +46,8 @@ #ifdef HAVE_CAPSICUM #include <sys/capsicum.h> #include <capsicum_helpers.h> +#include <libcasper.h> +#include <casper/cap_fileargs.h> #endif /* @@ -262,7 +263,8 @@ static const char *gnu_shortopts = "bctwz"; static const struct option perl_longopts[] = { { "algorithm", required_argument, 0, opt_algorithm }, - { "check", required_argument, 0, opt_check }, + { "binary", no_argument, 0, opt_binary }, + { "check", no_argument, 0, opt_check }, { "help", no_argument, 0, opt_help }, { "ignore-missing", no_argument, 0, opt_ignore_missing }, { "quiet", no_argument, 0, opt_quiet }, @@ -285,9 +287,10 @@ MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len) } struct chksumrec { - char *filename; - char *chksum; - struct chksumrec *next; + char *filename; + enum input_mode input_mode; + char *chksum; + struct chksumrec *next; }; static struct chksumrec *head = NULL; @@ -300,17 +303,18 @@ static unsigned int numrecs; static void gnu_check(const char *checksumsfile) { - FILE *inp; - char *linebuf = NULL; - size_t linecap; - ssize_t linelen; - int lineno; - char *filename; - char *hashstr; - struct chksumrec *rec; - const char *digestname; - size_t digestnamelen; - size_t hashstrlen; + FILE *inp; + char *linebuf = NULL; + size_t linecap; + ssize_t linelen; + int lineno; + char *filename; + char *hashstr; + struct chksumrec *rec; + const char *digestname; + size_t digestnamelen; + size_t hashstrlen; + struct stat st; if (strcmp(checksumsfile, "-") == 0) inp = stdin; @@ -358,8 +362,19 @@ gnu_check(const char *checksumsfile) rec = malloc(sizeof(*rec)); if (rec == NULL) errx(1, "malloc failed"); + + if ((*filename == '*' || *filename == ' ' || + *filename == 'U' || *filename == '^') && + lstat(filename, &st) != 0 && + lstat(filename + 1, &st) == 0) { + rec->filename = strdup(filename + 1); + rec->input_mode = (enum input_mode)*filename; + } else { + rec->filename = strdup(filename); + rec->input_mode = input_mode; + } + rec->chksum = strdup(hashstr); - rec->filename = strdup(filename); if (rec->chksum == NULL || rec->filename == NULL) errx(1, "malloc failed"); rec->next = NULL; @@ -384,16 +399,17 @@ int main(int argc, char *argv[]) { #ifdef HAVE_CAPSICUM - cap_rights_t rights; + cap_rights_t rights; + fileargs_t *fa = NULL; #endif const struct option *longopts; const char *shortopts; - FILE *f; - int i, opt; - char *p, *string = NULL; - char buf[HEX_DIGEST_LENGTH]; - size_t len; - struct chksumrec *rec; + FILE *f; + int i, opt; + char *p, *string = NULL; + char buf[HEX_DIGEST_LENGTH]; + size_t len; + struct chksumrec *rec; if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; @@ -562,7 +578,7 @@ main(int argc, char *argv[]) argv += optind; #ifdef HAVE_CAPSICUM - if (caph_limit_stdout() < 0 || caph_limit_stderr() < 0) + if (caph_limit_stdio() < 0) err(1, "unable to limit rights for stdio"); #endif @@ -576,7 +592,7 @@ main(int argc, char *argv[]) while (argc--) gnu_check(*argv++); argc = 0; - argv = calloc(sizeof(char *), numrecs + 1); + argv = calloc(numrecs + 1, sizeof(char *)); for (rec = head; rec != NULL; rec = rec->next) { argv[argc] = rec->filename; argc++; @@ -585,59 +601,49 @@ main(int argc, char *argv[]) rec = head; } - if (*argv) { +#ifdef HAVE_CAPSICUM + fa = fileargs_init(argc, argv, O_RDONLY, 0, + cap_rights_init(&rights, CAP_READ, CAP_FSTAT, CAP_FCNTL), FA_OPEN | FA_LSTAT); + if (fa == NULL) + err(1, "Unable to initialize casper"); + if (caph_enter_casper() < 0) + err(1, "Unable to enter capability mode"); +#endif + + if (*argv && !pflag && string == NULL) { do { - struct stat st; const char *filename = *argv; const char *filemode = "rb"; - if (*filename == '*' || - *filename == ' ' || - *filename == 'U' || - *filename == '^') { - if (lstat(filename, &st) != 0) { - input_mode = (int)*filename; - filename++; - } + if (cflag && mode != mode_bsd) { + input_mode = rec->input_mode; + checkAgainst = rec->chksum; + rec = rec->next; } if (input_mode == input_text) filemode = "r"; - if ((f = fopen(filename, filemode)) == NULL) { + if (strcmp(filename, "-") == 0) { + f = stdin; + } else { +#ifdef HAVE_CAPSICUM + f = fileargs_fopen(fa, filename, filemode); +#else + f = fopen(filename, filemode); +#endif + } + if (f == NULL) { if (errno != ENOENT || !(cflag && ignoreMissing)) { warn("%s", filename); failed = true; } - if (cflag && mode != mode_bsd) - rec = rec->next; continue; } - /* - * XXX Enter capability mode on the last argv file. - * When a casper file service or other approach is - * available, switch to that and enter capability mode - * earlier. - */ - if (*(argv + 1) == NULL) { -#ifdef HAVE_CAPSICUM - cap_rights_init(&rights, CAP_READ, CAP_FSTAT); - if (caph_rights_limit(fileno(f), &rights) < 0 || - caph_enter() < 0) - err(1, "capsicum"); -#endif - } - if (cflag && mode != mode_bsd) { - checkAgainst = rec->chksum; - rec = rec->next; - } p = MDInput(&Algorithm[digest], f, buf, false); - (void)fclose(f); + if (f != stdin) + (void)fclose(f); MDOutput(&Algorithm[digest], p, filename); } while (*++argv); } else if (!cflag && string == NULL && !skip) { -#ifdef HAVE_CAPSICUM - if (caph_limit_stdin() < 0 || caph_enter() < 0) - err(1, "capsicum"); -#endif if (mode == mode_bsd) output_mode = output_bare; p = MDInput(&Algorithm[digest], stdin, buf, pflag); @@ -659,6 +665,9 @@ main(int argc, char *argv[]) if (checksFailed != 0 || (strict && malformed > 0)) return (1); } +#ifdef HAVE_CAPSICUM + fileargs_free(fa); +#endif if (failed) return (1); if (checksFailed > 0) |