Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 2 | /* |
| 3 | * fs-verity userspace tool |
| 4 | * |
Eric Biggers | 8387ad3 | 2018-08-21 12:37:56 -0700 | [diff] [blame] | 5 | * Copyright (C) 2018 Google LLC |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 6 | * |
Eric Biggers | 8387ad3 | 2018-08-21 12:37:56 -0700 | [diff] [blame] | 7 | * Written by Eric Biggers. |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 8 | */ |
| 9 | |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 10 | #include <stdlib.h> |
| 11 | #include <string.h> |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 12 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 13 | #include "commands.h" |
| 14 | #include "hash_algs.h" |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 15 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 16 | static const struct fsverity_command { |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 17 | const char *name; |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 18 | int (*func)(const struct fsverity_command *cmd, int argc, char *argv[]); |
| 19 | const char *short_desc; |
| 20 | const char *usage_str; |
| 21 | } fsverity_commands[] = { |
| 22 | { |
| 23 | .name = "enable", |
| 24 | .func = fsverity_cmd_enable, |
| 25 | .short_desc = |
| 26 | "Enable fs-verity on a file with verity metadata", |
| 27 | .usage_str = |
| 28 | " fsverity enable FILE\n" |
| 29 | }, { |
Eric Biggers | 25b5945 | 2018-07-27 10:47:02 -0700 | [diff] [blame] | 30 | .name = "measure", |
| 31 | .func = fsverity_cmd_measure, |
| 32 | .short_desc = |
| 33 | "Display the measurement of the given fs-verity file(s)", |
| 34 | .usage_str = |
| 35 | " fsverity measure FILE...\n" |
| 36 | }, { |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 37 | .name = "setup", |
| 38 | .func = fsverity_cmd_setup, |
| 39 | .short_desc = "Create the verity metadata for a file", |
| 40 | .usage_str = |
| 41 | " fsverity setup INFILE [OUTFILE]\n" |
| 42 | " [--hash=HASH_ALG] [--salt=SALT] [--signing-key=KEYFILE]\n" |
| 43 | " [--signing-cert=CERTFILE] [--signature=SIGFILE]\n" |
| 44 | " [--patch=OFFSET,PATCHFILE] [--elide=OFFSET,LENGTH]\n" |
Eric Biggers | 25b5945 | 2018-07-27 10:47:02 -0700 | [diff] [blame] | 45 | } |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 46 | }; |
| 47 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 48 | static void usage_all(FILE *fp) |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 49 | { |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 50 | int i; |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 51 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 52 | fputs("Usage:\n", fp); |
| 53 | for (i = 0; i < ARRAY_SIZE(fsverity_commands); i++) |
| 54 | fprintf(fp, " %s:\n%s\n", fsverity_commands[i].short_desc, |
| 55 | fsverity_commands[i].usage_str); |
| 56 | fputs( |
| 57 | " Standard options:\n" |
| 58 | " fsverity --help\n" |
| 59 | " fsverity --version\n" |
| 60 | "\n" |
| 61 | "Available hash algorithms: ", fp); |
| 62 | show_all_hash_algs(fp); |
| 63 | fputs("\nSee `man fsverity` for more details.\n", fp); |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 64 | } |
| 65 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 66 | static void usage_cmd(const struct fsverity_command *cmd, FILE *fp) |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 67 | { |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 68 | fprintf(fp, "Usage:\n%s", cmd->usage_str); |
| 69 | } |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 70 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 71 | void usage(const struct fsverity_command *cmd, FILE *fp) |
| 72 | { |
| 73 | if (cmd) |
| 74 | usage_cmd(cmd, fp); |
| 75 | else |
| 76 | usage_all(fp); |
| 77 | } |
| 78 | |
| 79 | #define PACKAGE_VERSION "v0.0-alpha" |
| 80 | #define PACKAGE_BUGREPORT "linux-fscrypt@vger.kernel.org" |
| 81 | |
| 82 | static void show_version(void) |
| 83 | { |
| 84 | static const char * const str = |
| 85 | "fsverity " PACKAGE_VERSION "\n" |
Eric Biggers | 8387ad3 | 2018-08-21 12:37:56 -0700 | [diff] [blame] | 86 | "Copyright (C) 2018 Google LLC\n" |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 87 | "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.\n" |
| 88 | "This is free software: you are free to change and redistribute it.\n" |
| 89 | "There is NO WARRANTY, to the extent permitted by law.\n" |
| 90 | "\n" |
| 91 | "Report bugs to " PACKAGE_BUGREPORT ".\n"; |
| 92 | fputs(str, stdout); |
| 93 | } |
| 94 | |
| 95 | static void handle_common_options(int argc, char *argv[], |
| 96 | const struct fsverity_command *cmd) |
| 97 | { |
| 98 | int i; |
| 99 | |
| 100 | for (i = 1; i < argc; i++) { |
| 101 | const char *arg = argv[i]; |
| 102 | |
| 103 | if (*arg++ != '-') |
| 104 | continue; |
| 105 | if (*arg++ != '-') |
| 106 | continue; |
| 107 | if (!strcmp(arg, "help")) { |
| 108 | usage(cmd, stdout); |
| 109 | exit(0); |
| 110 | } else if (!strcmp(arg, "version")) { |
| 111 | show_version(); |
| 112 | exit(0); |
| 113 | } else if (!*arg) /* reached "--", no more options */ |
| 114 | return; |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 115 | } |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 116 | } |
| 117 | |
| 118 | static const struct fsverity_command *find_command(const char *name) |
| 119 | { |
| 120 | int i; |
| 121 | |
| 122 | for (i = 0; i < ARRAY_SIZE(fsverity_commands); i++) |
| 123 | if (!strcmp(name, fsverity_commands[i].name)) |
| 124 | return &fsverity_commands[i]; |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 125 | return NULL; |
| 126 | } |
| 127 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 128 | int main(int argc, char *argv[]) |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 129 | { |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 130 | const struct fsverity_command *cmd; |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 131 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 132 | if (argc < 2) { |
| 133 | error_msg("no command specified"); |
| 134 | usage_all(stderr); |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 135 | return 2; |
| 136 | } |
| 137 | |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 138 | cmd = find_command(argv[1]); |
| 139 | |
| 140 | handle_common_options(argc, argv, cmd); |
| 141 | |
| 142 | if (!cmd) { |
| 143 | error_msg("unrecognized command: '%s'", argv[1]); |
| 144 | usage_all(stderr); |
| 145 | return 2; |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 146 | } |
Eric Biggers | 431c67b | 2018-06-27 15:01:06 -0700 | [diff] [blame] | 147 | return cmd->func(cmd, argc - 1, argv + 1); |
Eric Biggers | 1e64b3d | 2018-03-21 17:53:20 -0700 | [diff] [blame] | 148 | } |