]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/veritysetup/veritysetup.c
d33c9732236b2a598c4ef54d9d0a216615967821
[thirdparty/systemd.git] / src / veritysetup / veritysetup.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright 2016 Lennart Poettering
4 ***/
5
6 #include <errno.h>
7 #include <stdio.h>
8 #include <sys/stat.h>
9
10 #include "alloc-util.h"
11 #include "crypt-util.h"
12 #include "hexdecoct.h"
13 #include "log.h"
14 #include "string-util.h"
15
16 static char *arg_root_hash = NULL;
17 static char *arg_data_what = NULL;
18 static char *arg_hash_what = NULL;
19
20 static int help(void) {
21 printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH\n"
22 "%s detach VOLUME\n\n"
23 "Attaches or detaches an integrity protected block device.\n",
24 program_invocation_short_name,
25 program_invocation_short_name);
26
27 return 0;
28 }
29
30 int main(int argc, char *argv[]) {
31 _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
32 int r;
33
34 if (argc <= 1) {
35 r = help();
36 goto finish;
37 }
38
39 if (argc < 3) {
40 log_error("This program requires at least two arguments.");
41 r = -EINVAL;
42 goto finish;
43 }
44
45 log_set_target(LOG_TARGET_AUTO);
46 log_parse_environment();
47 log_open();
48
49 umask(0022);
50
51 if (streq(argv[1], "attach")) {
52 _cleanup_free_ void *m = NULL;
53 crypt_status_info status;
54 size_t l;
55
56 if (argc < 6) {
57 log_error("attach requires at least two arguments.");
58 r = -EINVAL;
59 goto finish;
60 }
61
62 r = unhexmem(argv[5], strlen(argv[5]), &m, &l);
63 if (r < 0) {
64 log_error("Failed to parse root hash.");
65 goto finish;
66 }
67
68 r = crypt_init(&cd, argv[4]);
69 if (r < 0) {
70 log_error_errno(r, "Failed to open verity device %s: %m", argv[4]);
71 goto finish;
72 }
73
74 crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
75
76 status = crypt_status(cd, argv[2]);
77 if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
78 log_info("Volume %s already active.", argv[2]);
79 r = 0;
80 goto finish;
81 }
82
83 r = crypt_load(cd, CRYPT_VERITY, NULL);
84 if (r < 0) {
85 log_error_errno(r, "Failed to load verity superblock: %m");
86 goto finish;
87 }
88
89 r = crypt_set_data_device(cd, argv[3]);
90 if (r < 0) {
91 log_error_errno(r, "Failed to configure data device: %m");
92 goto finish;
93 }
94
95 r = crypt_activate_by_volume_key(cd, argv[2], m, l, CRYPT_ACTIVATE_READONLY);
96 if (r < 0) {
97 log_error_errno(r, "Failed to set up verity device: %m");
98 goto finish;
99 }
100
101 } else if (streq(argv[1], "detach")) {
102
103 r = crypt_init_by_name(&cd, argv[2]);
104 if (r == -ENODEV) {
105 log_info("Volume %s already inactive.", argv[2]);
106 goto finish;
107 } else if (r < 0) {
108 log_error_errno(r, "crypt_init_by_name() failed: %m");
109 goto finish;
110 }
111
112 crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
113
114 r = crypt_deactivate(cd, argv[2]);
115 if (r < 0) {
116 log_error_errno(r, "Failed to deactivate: %m");
117 goto finish;
118 }
119
120 } else {
121 log_error("Unknown verb %s.", argv[1]);
122 r = -EINVAL;
123 goto finish;
124 }
125
126 r = 0;
127
128 finish:
129 free(arg_root_hash);
130 free(arg_data_what);
131 free(arg_hash_what);
132
133 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
134 }