aboutsummaryrefslogtreecommitdiff
path: root/sbin/md5/md5.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/md5/md5.c')
-rw-r--r--sbin/md5/md5.c133
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)