mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
Merge pull request #22919 from poettering/cryptsetup-tweaks
various minor tweaks to cryptsetup/veritysetup/integritysetup
This commit is contained in:
commit
d6d450074f
@ -14,10 +14,11 @@
|
||||
#include "mkdir.h"
|
||||
#include "parse-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "terminal-util.h"
|
||||
#include "process-util.h"
|
||||
#include "reboot-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int help(void) {
|
||||
@ -368,7 +369,7 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
log_setup();
|
||||
|
||||
if (strv_contains(strv_skip(argv, 1), "--help"))
|
||||
if (argv_looks_like_help(argc, argv))
|
||||
return help();
|
||||
|
||||
if (argc != 3)
|
||||
|
@ -1615,6 +1615,30 @@ _noreturn_ void freeze(void) {
|
||||
pause();
|
||||
}
|
||||
|
||||
bool argv_looks_like_help(int argc, char **argv) {
|
||||
char **l;
|
||||
|
||||
/* Scans the command line for indications the user asks for help. This is supposed to be called by
|
||||
* tools that do not implement getopt() style command line parsing because they are not primarily
|
||||
* user-facing. Detects four ways of asking for help:
|
||||
*
|
||||
* 1. Passing zero arguments
|
||||
* 2. Passing "help" as first argument
|
||||
* 3. Passing --help as any argument
|
||||
* 4. Passing -h as any argument
|
||||
*/
|
||||
|
||||
if (argc <= 1)
|
||||
return true;
|
||||
|
||||
if (streq_ptr(argv[1], "help"))
|
||||
return true;
|
||||
|
||||
l = strv_skip(argv, 1);
|
||||
|
||||
return strv_contains(l, "--help") ||
|
||||
strv_contains(l, "-h");
|
||||
}
|
||||
|
||||
static const char *const sigchld_code_table[] = {
|
||||
[CLD_EXITED] = "exited",
|
||||
|
@ -191,3 +191,5 @@ int setpriority_closest(int priority);
|
||||
bool invoked_as(char *argv[], const char *token);
|
||||
|
||||
_noreturn_ void freeze(void);
|
||||
|
||||
bool argv_looks_like_help(int argc, char **argv);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "path-util.h"
|
||||
#include "pkcs11-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "random-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@ -850,7 +851,7 @@ static int acquire_pins_from_env_variable(char ***ret_pins) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static int attach_luks2_by_fido2(
|
||||
static int attach_luks2_by_fido2_via_plugin(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
usec_t until,
|
||||
@ -980,7 +981,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
|
||||
|
||||
for (;;) {
|
||||
if (use_libcryptsetup_plugin && !arg_fido2_cid) {
|
||||
r = attach_luks2_by_fido2(cd, name, until, arg_headless, arg_fido2_device, flags);
|
||||
r = attach_luks2_by_fido2_via_plugin(cd, name, until, arg_headless, arg_fido2_device, flags);
|
||||
if (IN_SET(r, -ENOTUNIQ, -ENXIO, -ENOENT))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
|
||||
"Automatic FIDO2 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
|
||||
@ -1053,7 +1054,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int attach_luks2_by_pkcs11(
|
||||
static int attach_luks2_by_pkcs11_via_plugin(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *friendly_name,
|
||||
@ -1133,7 +1134,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
|
||||
|
||||
for (;;) {
|
||||
if (use_libcryptsetup_plugin && arg_pkcs11_uri_auto)
|
||||
r = attach_luks2_by_pkcs11(cd, name, friendly, until, arg_headless, flags);
|
||||
r = attach_luks2_by_pkcs11_via_plugin(cd, name, friendly, until, arg_headless, flags);
|
||||
else {
|
||||
r = decrypt_pkcs11_key(
|
||||
name,
|
||||
@ -1246,7 +1247,7 @@ static int make_tpm2_device_monitor(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int attach_luks2_by_tpm2(
|
||||
static int attach_luks2_by_tpm2_via_plugin(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
uint32_t flags) {
|
||||
@ -1328,11 +1329,11 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
|
||||
return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
|
||||
}
|
||||
} else {
|
||||
r = attach_luks2_by_tpm2(cd, name, flags);
|
||||
r = attach_luks2_by_tpm2_via_plugin(cd, name, flags);
|
||||
/* EAGAIN means: no tpm2 chip found
|
||||
* EOPNOTSUPP means: no libcryptsetup plugins support */
|
||||
if (r == -ENXIO)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
|
||||
return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
|
||||
"No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking.");
|
||||
if (r == -ENOENT)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
|
||||
@ -1343,7 +1344,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
|
||||
}
|
||||
}
|
||||
|
||||
if (r == -EOPNOTSUPP) {
|
||||
if (r == -EOPNOTSUPP) { /* Plugin not available, let's process TPM2 stuff right here instead */
|
||||
_cleanup_free_ void *blob = NULL, *policy_hash = NULL;
|
||||
size_t blob_size, policy_hash_size;
|
||||
bool found_some = false;
|
||||
@ -1372,7 +1373,8 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
|
||||
&tpm2_flags);
|
||||
if (r == -ENXIO)
|
||||
/* No further TPM2 tokens found in the LUKS2 header. */
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
|
||||
return log_full_errno(found_some ? LOG_NOTICE : LOG_DEBUG,
|
||||
SYNTHETIC_ERRNO(EAGAIN),
|
||||
found_some
|
||||
? "No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking."
|
||||
: "No TPM2 metadata enrolled in LUKS2 header, falling back to traditional unlocking.");
|
||||
@ -1398,7 +1400,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
|
||||
arg_ask_password_flags,
|
||||
&decrypted_key, &decrypted_key_size);
|
||||
if (IN_SET(r, -EACCES, -ENOLCK))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed, falling back to traditional unlocking.");
|
||||
return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed, falling back to traditional unlocking.");
|
||||
if (r != -EPERM)
|
||||
break;
|
||||
|
||||
@ -1726,7 +1728,7 @@ static int run(int argc, char *argv[]) {
|
||||
const char *verb;
|
||||
int r;
|
||||
|
||||
if (argc <= 1)
|
||||
if (argv_looks_like_help(argc, argv))
|
||||
return help();
|
||||
|
||||
if (argc < 3)
|
||||
@ -1758,8 +1760,8 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
volume = argv[2];
|
||||
source = argv[3];
|
||||
key_file = argc >= 5 && !STR_IN_SET(argv[4], "", "-", "none") ? argv[4] : NULL;
|
||||
options = argc >= 6 && !STR_IN_SET(argv[5], "", "-", "none") ? argv[5] : NULL;
|
||||
key_file = mangle_none(argc >= 5 ? argv[4] : NULL);
|
||||
options = mangle_none(argc >= 6 ? argv[5] : NULL);
|
||||
|
||||
if (!filename_is_valid(volume))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
|
||||
|
@ -12,9 +12,10 @@
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "memory-util.h"
|
||||
#include "path-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
@ -87,19 +88,16 @@ static const char *integrity_algorithm_select(const void *key_file_buf) {
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
||||
char *verb, *volume;
|
||||
int r;
|
||||
char *action, *volume;
|
||||
|
||||
if (argc <= 1 ||
|
||||
strv_contains(strv_skip(argv, 1), "--help") ||
|
||||
strv_contains(strv_skip(argv, 1), "-h") ||
|
||||
streq(argv[1], "help"))
|
||||
if (argv_looks_like_help(argc, argv))
|
||||
return help();
|
||||
|
||||
if (argc < 3)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires at least two arguments.");
|
||||
|
||||
action = argv[1];
|
||||
verb = argv[1];
|
||||
volume = argv[2];
|
||||
|
||||
log_setup();
|
||||
@ -108,7 +106,7 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
umask(0022);
|
||||
|
||||
if (streq(action, "attach")) {
|
||||
if (streq(verb, "attach")) {
|
||||
/* attach name device optional_key_file optional_options */
|
||||
|
||||
crypt_status_info status;
|
||||
@ -123,8 +121,11 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach has a maximum of five arguments.");
|
||||
|
||||
device = argv[3];
|
||||
key_file = (argc > 4) ? empty_or_dash_to_null(argv[4]) : NULL;
|
||||
options = (argc > 5) ? empty_or_dash_to_null(argv[5]) : NULL;
|
||||
key_file = mangle_none(argc > 4 ? argv[4] : NULL);
|
||||
options = mangle_none(argc > 5 ? argv[5] : NULL);
|
||||
|
||||
if (!filename_is_valid(volume))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
|
||||
|
||||
if (key_file) {
|
||||
r = load_key_file(key_file, &key_buf, &key_buf_size);
|
||||
@ -171,14 +172,19 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up integrity device: %m");
|
||||
|
||||
} else if (streq(action, "detach")) {
|
||||
} else if (streq(verb, "detach")) {
|
||||
|
||||
if (argc > 3)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "detach has a maximum of two arguments.");
|
||||
|
||||
if (!filename_is_valid(volume))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
|
||||
|
||||
r = crypt_init_by_name(&cd, volume);
|
||||
if (r == -ENODEV)
|
||||
if (r == -ENODEV) {
|
||||
log_info("Volume %s already inactive.", volume);
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "crypt_init_by_name() failed: %m");
|
||||
|
||||
@ -189,7 +195,7 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to deactivate: %m");
|
||||
|
||||
} else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", action);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", verb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -86,3 +86,8 @@ static inline void sym_crypt_free(struct crypt_device* cd) {}
|
||||
static inline void sym_crypt_freep(struct crypt_device** cd) {}
|
||||
|
||||
#endif
|
||||
|
||||
static inline const char *mangle_none(const char *s) {
|
||||
/* A helper that turns cryptsetup/integritysetup/veritysetup "options" strings into NULL if they are effectively empty */
|
||||
return isempty(s) || STR_IN_SET(s, "-", "none") ? NULL : s;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "main-func.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
@ -111,12 +112,10 @@ static int parse_options(const char *options) {
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
||||
const char *verb;
|
||||
int r;
|
||||
|
||||
if (argc <= 1 ||
|
||||
strv_contains(strv_skip(argv, 1), "--help") ||
|
||||
strv_contains(strv_skip(argv, 1), "-h") ||
|
||||
streq(argv[1], "help"))
|
||||
if (argv_looks_like_help(argc, argv))
|
||||
return help();
|
||||
|
||||
if (argc < 3)
|
||||
@ -128,7 +127,10 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
umask(0022);
|
||||
|
||||
if (streq(argv[1], "attach")) {
|
||||
verb = argv[1];
|
||||
|
||||
if (streq(verb, "attach")) {
|
||||
const char *volume, *data_device, *verity_device, *root_hash, *options;
|
||||
_cleanup_free_ void *m = NULL;
|
||||
crypt_status_info status;
|
||||
size_t l;
|
||||
@ -136,24 +138,33 @@ static int run(int argc, char *argv[]) {
|
||||
if (argc < 6)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least four arguments.");
|
||||
|
||||
r = unhexmem(argv[5], strlen(argv[5]), &m, &l);
|
||||
volume = argv[2];
|
||||
data_device = argv[3];
|
||||
verity_device = argv[4];
|
||||
root_hash = argv[5];
|
||||
options = mangle_none(argc > 6 ? argv[6] : NULL);
|
||||
|
||||
if (!filename_is_valid(volume))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
|
||||
|
||||
r = unhexmem(root_hash, SIZE_MAX, &m, &l);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse root hash: %m");
|
||||
|
||||
r = crypt_init(&cd, argv[4]);
|
||||
r = crypt_init(&cd, verity_device);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open verity device %s: %m", argv[4]);
|
||||
return log_error_errno(r, "Failed to open verity device %s: %m", verity_device);
|
||||
|
||||
cryptsetup_enable_logging(cd);
|
||||
|
||||
status = crypt_status(cd, argv[2]);
|
||||
status = crypt_status(cd, volume);
|
||||
if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
|
||||
log_info("Volume %s already active.", argv[2]);
|
||||
log_info("Volume %s already active.", volume);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc > 6) {
|
||||
r = parse_options(argv[6]);
|
||||
if (options) {
|
||||
r = parse_options(options);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse options: %m");
|
||||
}
|
||||
@ -162,7 +173,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to load verity superblock: %m");
|
||||
|
||||
r = crypt_set_data_device(cd, argv[3]);
|
||||
r = crypt_set_data_device(cd, data_device);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to configure data device: %m");
|
||||
|
||||
@ -186,20 +197,26 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to read root hash signature: %m");
|
||||
}
|
||||
|
||||
r = crypt_activate_by_signed_key(cd, argv[2], m, l, hash_sig, hash_sig_size, arg_activate_flags);
|
||||
r = crypt_activate_by_signed_key(cd, volume, m, l, hash_sig, hash_sig_size, arg_activate_flags);
|
||||
#else
|
||||
assert_not_reached();
|
||||
#endif
|
||||
} else
|
||||
r = crypt_activate_by_volume_key(cd, argv[2], m, l, arg_activate_flags);
|
||||
r = crypt_activate_by_volume_key(cd, volume, m, l, arg_activate_flags);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up verity device: %m");
|
||||
|
||||
} else if (streq(argv[1], "detach")) {
|
||||
} else if (streq(verb, "detach")) {
|
||||
const char *volume;
|
||||
|
||||
r = crypt_init_by_name(&cd, argv[2]);
|
||||
volume = argv[2];
|
||||
|
||||
if (!filename_is_valid(volume))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
|
||||
|
||||
r = crypt_init_by_name(&cd, volume);
|
||||
if (r == -ENODEV) {
|
||||
log_info("Volume %s already inactive.", argv[2]);
|
||||
log_info("Volume %s already inactive.", volume);
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
@ -207,12 +224,12 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
cryptsetup_enable_logging(cd);
|
||||
|
||||
r = crypt_deactivate(cd, argv[2]);
|
||||
r = crypt_deactivate(cd, volume);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to deactivate: %m");
|
||||
|
||||
} else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", argv[1]);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", verb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user