Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <errno.h>
4 : : #include <stdio.h>
5 : : #include <sys/stat.h>
6 : :
7 : : #include "alloc-util.h"
8 : : #include "crypt-util.h"
9 : : #include "hexdecoct.h"
10 : : #include "log.h"
11 : : #include "main-func.h"
12 : : #include "pretty-print.h"
13 : : #include "string-util.h"
14 : : #include "terminal-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 : 0 : STATIC_DESTRUCTOR_REGISTER(arg_root_hash, freep);
21 : 0 : STATIC_DESTRUCTOR_REGISTER(arg_data_what, freep);
22 : 0 : STATIC_DESTRUCTOR_REGISTER(arg_hash_what, freep);
23 : :
24 : 0 : static int help(void) {
25 : 0 : _cleanup_free_ char *link = NULL;
26 : : int r;
27 : :
28 : 0 : r = terminal_urlify_man("systemd-veritysetup@.service", "8", &link);
29 [ # # ]: 0 : if (r < 0)
30 : 0 : return log_oom();
31 : :
32 : 0 : printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH\n"
33 : : "%s detach VOLUME\n\n"
34 : : "Attaches or detaches an integrity protected block device.\n"
35 : : "\nSee the %s for details.\n"
36 : : , program_invocation_short_name
37 : : , program_invocation_short_name
38 : : , link
39 : : );
40 : :
41 : 0 : return 0;
42 : : }
43 : :
44 : 0 : static int run(int argc, char *argv[]) {
45 : 0 : _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
46 : : int r;
47 : :
48 [ # # ]: 0 : if (argc <= 1)
49 : 0 : return help();
50 : :
51 [ # # ]: 0 : if (argc < 3)
52 [ # # ]: 0 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires at least two arguments.");
53 : :
54 : 0 : log_setup_service();
55 : :
56 : 0 : umask(0022);
57 : :
58 [ # # ]: 0 : if (streq(argv[1], "attach")) {
59 [ # # ]: 0 : _cleanup_free_ void *m = NULL;
60 : : crypt_status_info status;
61 : : size_t l;
62 : :
63 [ # # ]: 0 : if (argc < 6)
64 [ # # ]: 0 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least two arguments.");
65 : :
66 : 0 : r = unhexmem(argv[5], strlen(argv[5]), &m, &l);
67 [ # # ]: 0 : if (r < 0)
68 [ # # ]: 0 : return log_error_errno(r, "Failed to parse root hash: %m");
69 : :
70 : 0 : r = crypt_init(&cd, argv[4]);
71 [ # # ]: 0 : if (r < 0)
72 [ # # ]: 0 : return log_error_errno(r, "Failed to open verity device %s: %m", argv[4]);
73 : :
74 : 0 : crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
75 : :
76 : 0 : status = crypt_status(cd, argv[2]);
77 [ # # # # ]: 0 : if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
78 [ # # ]: 0 : log_info("Volume %s already active.", argv[2]);
79 : 0 : return 0;
80 : : }
81 : :
82 : 0 : r = crypt_load(cd, CRYPT_VERITY, NULL);
83 [ # # ]: 0 : if (r < 0)
84 [ # # ]: 0 : return log_error_errno(r, "Failed to load verity superblock: %m");
85 : :
86 : 0 : r = crypt_set_data_device(cd, argv[3]);
87 [ # # ]: 0 : if (r < 0)
88 [ # # ]: 0 : return log_error_errno(r, "Failed to configure data device: %m");
89 : :
90 : 0 : r = crypt_activate_by_volume_key(cd, argv[2], m, l, CRYPT_ACTIVATE_READONLY);
91 [ # # ]: 0 : if (r < 0)
92 [ # # ]: 0 : return log_error_errno(r, "Failed to set up verity device: %m");
93 : :
94 [ # # ]: 0 : } else if (streq(argv[1], "detach")) {
95 : :
96 : 0 : r = crypt_init_by_name(&cd, argv[2]);
97 [ # # ]: 0 : if (r == -ENODEV) {
98 [ # # ]: 0 : log_info("Volume %s already inactive.", argv[2]);
99 : 0 : return 0;
100 : : }
101 [ # # ]: 0 : if (r < 0)
102 [ # # ]: 0 : return log_error_errno(r, "crypt_init_by_name() failed: %m");
103 : :
104 : 0 : crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
105 : :
106 : 0 : r = crypt_deactivate(cd, argv[2]);
107 [ # # ]: 0 : if (r < 0)
108 [ # # ]: 0 : return log_error_errno(r, "Failed to deactivate: %m");
109 : :
110 : : } else
111 [ # # ]: 0 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", argv[1]);
112 : :
113 : 0 : return 0;
114 : : }
115 : :
116 : 0 : DEFINE_MAIN_FUNCTION(run);
|