#include "alloc-util.h"
#include "analyze.h"
+#include "analyze-architectures.h"
#include "analyze-blame.h"
#include "analyze-calendar.h"
#include "analyze-capability.h"
#include "analyze-exit-status.h"
#include "analyze-fdstore.h"
#include "analyze-filesystems.h"
+#include "analyze-image-policy.h"
#include "analyze-inspect-elf.h"
#include "analyze-log-control.h"
#include "analyze-malloc.h"
+#include "analyze-pcrs.h"
#include "analyze-plot.h"
#include "analyze-security.h"
#include "analyze-service-watchdogs.h"
+#include "analyze-srk.h"
#include "analyze-syscall-filter.h"
#include "analyze-time.h"
#include "analyze-time-data.h"
#include "unit-name.h"
#include "verb-log-control.h"
#include "verbs.h"
-#include "version.h"
DotMode arg_dot = DEP_ALL;
char **arg_dot_from_patterns = NULL, **arg_dot_to_patterns = NULL;
usec_t arg_fuzz = 0;
PagerFlags arg_pager_flags = 0;
+CatFlags arg_cat_flags = 0;
BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
const char *arg_host = NULL;
RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
" dot [UNIT...] Output dependency graph in %s format\n"
" dump [PATTERN...] Output state serialization of service\n"
" manager\n"
- " cat-config Show configuration file and drop-ins\n"
+ " cat-config NAME|PATH... Show configuration file and drop-ins\n"
" unit-files List files and symlinks for units\n"
" unit-paths List load directories for units\n"
" exit-status [STATUS...] List exit status definitions\n"
" capability [CAP...] List capability definitions\n"
" syscall-filter [NAME...] List syscalls in seccomp filters\n"
" filesystems [NAME...] List known filesystems\n"
+ " architectures [NAME...] List known architectures\n"
" condition CONDITION... Evaluate conditions and asserts\n"
" compare-versions VERSION1 [OP] VERSION2\n"
" Compare two version strings\n"
" inspect-elf FILE... Parse and print ELF package metadata\n"
" malloc [D-BUS SERVICE...] Dump malloc stats of a D-Bus service\n"
" fdstore SERVICE... Show file descriptor store contents of service\n"
+ " image-policy POLICY... Analyze image policy string\n"
+ " pcrs [PCR...] Show TPM2 PCRs and their names\n"
+ " srk [>FILE] Write TPM2 SRK (to FILE)\n"
"\nOptions:\n"
" --recursive-errors=MODE Control which units are verified\n"
" --offline=BOOL Perform a security review on unit file(s)\n"
" specified time\n"
" --profile=name|PATH Include the specified profile in the\n"
" security review of the unit(s)\n"
+ " --unit=UNIT Evaluate conditions and asserts of unit\n"
" --table Output plot's raw time data as a table\n"
" -h --help Show this help\n"
" --version Show package version\n"
" -q --quiet Do not emit hints\n"
+ " --tldr Skip comments and empty lines\n"
" --root=PATH Operate on an alternate filesystem root\n"
" --image=PATH Operate on disk image as filesystem root\n"
" --image-policy=POLICY Specify disk image dissection policy\n"
ARG_REQUIRE,
ARG_ROOT,
ARG_IMAGE,
+ ARG_IMAGE_POLICY,
ARG_SYSTEM,
ARG_USER,
ARG_GLOBAL,
ARG_PROFILE,
ARG_TABLE,
ARG_NO_LEGEND,
- ARG_IMAGE_POLICY,
+ ARG_TLDR,
};
static const struct option options[] = {
{ "require", no_argument, NULL, ARG_REQUIRE },
{ "root", required_argument, NULL, ARG_ROOT },
{ "image", required_argument, NULL, ARG_IMAGE },
+ { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
{ "recursive-errors", required_argument, NULL, ARG_RECURSIVE_ERRORS },
{ "offline", required_argument, NULL, ARG_OFFLINE },
{ "threshold", required_argument, NULL, ARG_THRESHOLD },
{ "profile", required_argument, NULL, ARG_PROFILE },
{ "table", optional_argument, NULL, ARG_TABLE },
{ "no-legend", optional_argument, NULL, ARG_NO_LEGEND },
- { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
+ { "tldr", no_argument, NULL, ARG_TLDR },
{}
};
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "hH:M:U:", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "hH:M:U:q", options, NULL)) >= 0)
switch (c) {
case 'h':
return r;
break;
+ case ARG_IMAGE_POLICY:
+ r = parse_image_policy_argument(optarg, &arg_image_policy);
+ if (r < 0)
+ return r;
+ break;
+
case ARG_SYSTEM:
arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
break;
arg_legend = false;
break;
- case ARG_IMAGE_POLICY: {
- _cleanup_(image_policy_freep) ImagePolicy *p = NULL;
-
- r = image_policy_from_string(optarg, &p);
- if (r < 0)
- return log_error_errno(r, "Failed to parse image policy: %s", optarg);
-
- image_policy_free(arg_image_policy);
- arg_image_policy = TAKE_PTR(p);
+ case ARG_TLDR:
+ arg_cat_flags = CAT_TLDR;
break;
- }
case '?':
return -EINVAL;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --offline= is only supported for security right now.");
- if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot", "fdstore"))
+ if (arg_offline && optind >= argc - 1)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Option --offline= requires one or more units to perform a security review.");
+
+ if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot", "fdstore", "pcrs", "architectures", "capability", "exit-status"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Option --json= is only supported for security, inspect-elf, plot, and fdstore right now.");
+ "Option --json= is only supported for security, inspect-elf, plot, fdstore, pcrs, architectures, capability, exit-status right now.");
if (arg_threshold != 100 && !streq_ptr(argv[optind], "security"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
if (streq_ptr(argv[optind], "condition") && arg_unit && optind < argc - 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No conditions can be passed if --unit= is used.");
- if ((!arg_legend && !streq_ptr(argv[optind], "plot")) ||
+ if ((!arg_legend && !STRPTR_IN_SET(argv[optind], "plot", "architectures")) ||
(streq_ptr(argv[optind], "plot") && !arg_legend && !arg_table && FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF)))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --no-legend is only supported for plot with either --table or --json=.");
static int run(int argc, char *argv[]) {
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
+ _cleanup_(umount_and_freep) char *mounted_dir = NULL;
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
{ "inspect-elf", 2, VERB_ANY, 0, verb_elf_inspection },
{ "malloc", VERB_ANY, VERB_ANY, 0, verb_malloc },
{ "fdstore", 2, VERB_ANY, 0, verb_fdstore },
+ { "image-policy", 2, 2, 0, verb_image_policy },
+ { "pcrs", VERB_ANY, VERB_ANY, 0, verb_pcrs },
+ { "srk", VERB_ANY, 1, 0, verb_srk },
+ { "architectures", VERB_ANY, VERB_ANY, 0, verb_architectures },
{}
};
arg_image_policy,
DISSECT_IMAGE_GENERIC_ROOT |
DISSECT_IMAGE_RELAX_VAR_CHECK |
- DISSECT_IMAGE_READ_ONLY,
- &unlink_dir,
+ DISSECT_IMAGE_READ_ONLY |
+ DISSECT_IMAGE_ALLOW_USERSPACE_VERITY,
+ &mounted_dir,
/* ret_dir_fd= */ NULL,
&loop_device);
if (r < 0)
return r;
- arg_root = strdup(unlink_dir);
+ arg_root = strdup(mounted_dir);
if (!arg_root)
return log_oom();
}