]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/veritysetup/veritysetup.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / veritysetup / veritysetup.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
2f3dfc6f
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2016 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
21#include <libcryptsetup.h>
22#include <stdio.h>
23#include <sys/stat.h>
24
25#include "log.h"
26#include "hexdecoct.h"
27#include "string-util.h"
28#include "alloc-util.h"
29
30static char *arg_root_hash = NULL;
31static char *arg_data_what = NULL;
32static char *arg_hash_what = NULL;
33
34static int help(void) {
35 printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH\n"
36 "%s detach VOLUME\n\n"
37 "Attaches or detaches an integrity protected block device.\n",
38 program_invocation_short_name,
39 program_invocation_short_name);
40
41 return 0;
42}
43
44static void log_glue(int level, const char *msg, void *usrptr) {
45 log_debug("%s", msg);
46}
47
48int main(int argc, char *argv[]) {
49 struct crypt_device *cd = NULL;
50 int r;
51
52 if (argc <= 1) {
53 r = help();
54 goto finish;
55 }
56
57 if (argc < 3) {
58 log_error("This program requires at least two arguments.");
59 r = -EINVAL;
60 goto finish;
61 }
62
63 log_set_target(LOG_TARGET_AUTO);
64 log_parse_environment();
65 log_open();
66
67 umask(0022);
68
69 if (streq(argv[1], "attach")) {
70 _cleanup_free_ void *m = NULL;
71 crypt_status_info status;
72 size_t l;
73
74 if (argc < 6) {
75 log_error("attach requires at least two arguments.");
76 r = -EINVAL;
77 goto finish;
78 }
79
80 r = unhexmem(argv[5], strlen(argv[5]), &m, &l);
81 if (r < 0) {
82 log_error("Failed to parse root hash.");
83 goto finish;
84 }
85
86 r = crypt_init(&cd, argv[4]);
87 if (r < 0) {
88 log_error_errno(r, "Failed to open verity device %s: %m", argv[4]);
89 goto finish;
90 }
91
92 crypt_set_log_callback(cd, log_glue, NULL);
93
94 status = crypt_status(cd, argv[2]);
3742095b 95 if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
2f3dfc6f
LP
96 log_info("Volume %s already active.", argv[2]);
97 r = 0;
98 goto finish;
99 }
100
101 r = crypt_load(cd, CRYPT_VERITY, NULL);
102 if (r < 0) {
103 log_error_errno(r, "Failed to load verity superblock: %m");
104 goto finish;
105 }
106
107 r = crypt_set_data_device(cd, argv[3]);
108 if (r < 0) {
109 log_error_errno(r, "Failed to configure data device: %m");
110 goto finish;
111 }
112
113 r = crypt_activate_by_volume_key(cd, argv[2], m, l, CRYPT_ACTIVATE_READONLY);
114 if (r < 0) {
115 log_error_errno(r, "Failed to set up verity device: %m");
116 goto finish;
117 }
118
119 } else if (streq(argv[1], "detach")) {
120
121 r = crypt_init_by_name(&cd, argv[2]);
122 if (r == -ENODEV) {
123 log_info("Volume %s already inactive.", argv[2]);
124 goto finish;
125 } else if (r < 0) {
126 log_error_errno(r, "crypt_init_by_name() failed: %m");
127 goto finish;
128 }
129
130 crypt_set_log_callback(cd, log_glue, NULL);
131
132 r = crypt_deactivate(cd, argv[2]);
133 if (r < 0) {
134 log_error_errno(r, "Failed to deactivate: %m");
135 goto finish;
136 }
137
138 } else {
139 log_error("Unknown verb %s.", argv[1]);
140 r = -EINVAL;
141 goto finish;
142 }
143
144 r = 0;
145
146finish:
147 if (cd)
148 crypt_free(cd);
149
150 free(arg_root_hash);
151 free(arg_data_what);
152 free(arg_hash_what);
153
154 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
155}