diff options
author | Michael Biebl <biebl@debian.org> | 2018-12-21 22:06:22 +0100 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2018-12-21 22:06:22 +0100 |
commit | 6e866b331d7cd4a5e0759dd160dea6edabd3678e (patch) | |
tree | 4d24c1ffe4ae946f04d8910956090e8d13aecd9a /src/cryptsetup/cryptsetup.c | |
parent | b012e92123bdc9fa10c2f079ec5bd9313b23e21a (diff) | |
download | systemd-6e866b331d7cd4a5e0759dd160dea6edabd3678e.tar.gz |
New upstream version 240
Diffstat (limited to 'src/cryptsetup/cryptsetup.c')
-rw-r--r-- | src/cryptsetup/cryptsetup.c | 172 |
1 files changed, 96 insertions, 76 deletions
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 832168184a..daf26aad70 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -14,19 +14,27 @@ #include "escape.h" #include "fileio.h" #include "log.h" +#include "main-func.h" #include "mount-util.h" #include "parse-util.h" #include "path-util.h" #include "string-util.h" #include "strv.h" +#include "pretty-print.h" #include "util.h" /* internal helper */ #define ANY_LUKS "LUKS" +/* as in src/cryptsetup.h */ +#define CRYPT_SECTOR_SIZE 512 +#define CRYPT_MAX_SECTOR_SIZE 4096 static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */ static char *arg_cipher = NULL; static unsigned arg_key_size = 0; +#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE +static unsigned arg_sector_size = CRYPT_SECTOR_SIZE; +#endif static int arg_key_slot = CRYPT_ANY_SLOT; static unsigned arg_keyfile_size = 0; static uint64_t arg_keyfile_offset = 0; @@ -46,6 +54,11 @@ static uint64_t arg_offset = 0; static uint64_t arg_skip = 0; static usec_t arg_timeout = USEC_INFINITY; +STATIC_DESTRUCTOR_REGISTER(arg_cipher, freep); +STATIC_DESTRUCTOR_REGISTER(arg_hash, freep); +STATIC_DESTRUCTOR_REGISTER(arg_header, freep); +STATIC_DESTRUCTOR_REGISTER(arg_tcrypt_keyfiles, strv_freep); + /* Options Debian's crypttab knows we don't: precheck= @@ -86,6 +99,29 @@ static int parse_one_option(const char *option) { arg_key_size /= 8; + } else if ((val = startswith(option, "sector-size="))) { + +#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE + r = safe_atou(val, &arg_sector_size); + if (r < 0) { + log_error_errno(r, "Failed to parse %s, ignoring: %m", option); + return 0; + } + + if (arg_sector_size % 2) { + log_error("sector-size= not a multiple of 2, ignoring."); + return 0; + } + + if (arg_sector_size < CRYPT_SECTOR_SIZE || arg_sector_size > CRYPT_MAX_SECTOR_SIZE) { + log_error("sector-size= is outside of %u and %u, ignoring.", CRYPT_SECTOR_SIZE, CRYPT_MAX_SECTOR_SIZE); + return 0; + } +#else + log_error("sector-size= is not supported, compiled with old libcryptsetup."); + return 0; +#endif + } else if ((val = startswith(option, "key-slot="))) { arg_type = ANY_LUKS; @@ -137,15 +173,13 @@ static int parse_one_option(const char *option) { } else if ((val = startswith(option, "header="))) { arg_type = ANY_LUKS; - if (!path_is_absolute(val)) { - log_error("Header path \"%s\" is not absolute, refusing.", val); - return -EINVAL; - } + if (!path_is_absolute(val)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Header path \"%s\" is not absolute, refusing.", val); - if (arg_header) { - log_error("Duplicate header= option, refusing."); - return -EINVAL; - } + if (arg_header) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Duplicate header= option, refusing."); arg_header = strdup(val); if (!arg_header) @@ -180,8 +214,8 @@ static int parse_one_option(const char *option) { arg_type = CRYPT_TCRYPT; arg_tcrypt_veracrypt = true; #else - log_error("This version of cryptsetup does not support tcrypt-veracrypt; refusing."); - return -EINVAL; + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "This version of cryptsetup does not support tcrypt-veracrypt; refusing."); #endif } else if (STR_IN_SET(option, "plain", "swap", "tmp")) arg_type = CRYPT_PLAIN; @@ -241,7 +275,6 @@ static int parse_options(const char *options) { } static char* disk_description(const char *path) { - static const char name_fields[] = "ID_PART_ENTRY_NAME\0" "DM_NAME\0" @@ -249,9 +282,8 @@ static char* disk_description(const char *path) { "ID_MODEL\0"; _cleanup_(sd_device_unrefp) sd_device *device = NULL; + const char *i, *name; struct stat st; - const char *i; - int r; assert(path); @@ -261,17 +293,13 @@ static char* disk_description(const char *path) { if (!S_ISBLK(st.st_mode)) return NULL; - r = sd_device_new_from_devnum(&device, 'b', st.st_rdev); - if (r < 0) + if (sd_device_new_from_devnum(&device, 'b', st.st_rdev) < 0) return NULL; - NULSTR_FOREACH(i, name_fields) { - const char *name; - - r = sd_device_get_property_value(device, i, &name); - if (r >= 0 && !isempty(name)) + NULSTR_FOREACH(i, name_fields) + if (sd_device_get_property_value(device, i, &name) >= 0 && + !isempty(name)) return strdup(name); - } return NULL; } @@ -333,7 +361,7 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc name = name_buffer ? name_buffer : vol; - if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) + if (asprintf(&text, "Please enter passphrase for disk %s:", name) < 0) return log_oom(); id = strjoina("cryptsetup:", disk_path); @@ -349,7 +377,7 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc assert(strv_length(passwords) == 1); - if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) + if (asprintf(&text, "Please enter passphrase for disk %s (verification):", name) < 0) return log_oom(); id = strjoina("cryptsetup-verification:", disk_path); @@ -433,10 +461,10 @@ static int attach_tcrypt( r = crypt_load(cd, CRYPT_TCRYPT, ¶ms); if (r < 0) { - if (key_file && r == -EPERM) { - log_error("Failed to activate using password file '%s'.", key_file); - return -EAGAIN; - } + if (key_file && r == -EPERM) + return log_error_errno(SYNTHETIC_ERRNO(EAGAIN), + "Failed to activate using password file '%s'.", + key_file); return r; } @@ -471,6 +499,9 @@ static int attach_luks_or_plain(struct crypt_device *cd, struct crypt_params_plain params = { .offset = arg_offset, .skip = arg_skip, +#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE + .sector_size = arg_sector_size, +#endif }; const char *cipher, *cipher_mode; _cleanup_free_ char *truncated_cipher = NULL; @@ -549,33 +580,38 @@ static int attach_luks_or_plain(struct crypt_device *cd, } static int help(void) { + _cleanup_free_ char *link = NULL; + int r; + + r = terminal_urlify_man("systemd-cryptsetup@.service", "8", &link); + if (r < 0) + return log_oom(); printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n" "%s detach VOLUME\n\n" - "Attaches or detaches an encrypted block device.\n", - program_invocation_short_name, - program_invocation_short_name); + "Attaches or detaches an encrypted block device.\n" + "\nSee the %s for details.\n" + , program_invocation_short_name + , program_invocation_short_name + , link + ); return 0; } -int main(int argc, char *argv[]) { +static int run(int argc, char *argv[]) { _cleanup_(crypt_freep) struct crypt_device *cd = NULL; - int r = -EINVAL; + int r; - if (argc <= 1) { - r = help(); - goto finish; - } + if (argc <= 1) + return help(); if (argc < 3) { log_error("This program requires at least two arguments."); - goto finish; + return -EINVAL; } - log_set_target(LOG_TARGET_AUTO); - log_parse_environment(); - log_open(); + log_setup_service(); umask(0022); @@ -590,7 +626,7 @@ int main(int argc, char *argv[]) { if (argc < 4) { log_error("attach requires at least two arguments."); - goto finish; + return -EINVAL; } if (argc >= 5 && @@ -605,8 +641,9 @@ int main(int argc, char *argv[]) { } if (argc >= 6 && argv[5][0] && !streq(argv[5], "-")) { - if (parse_options(argv[5]) < 0) - goto finish; + r = parse_options(argv[5]); + if (r < 0) + return r; } /* A delicious drop of snake oil */ @@ -617,18 +654,15 @@ int main(int argc, char *argv[]) { r = crypt_init(&cd, arg_header); } else r = crypt_init(&cd, argv[3]); - if (r < 0) { - log_error_errno(r, "crypt_init() failed: %m"); - goto finish; - } + if (r < 0) + return log_error_errno(r, "crypt_init() failed: %m"); crypt_set_log_callback(cd, cryptsetup_log_glue, NULL); status = crypt_status(cd, argv[2]); if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) { log_info("Volume %s already active.", argv[2]); - r = 0; - goto finish; + return 0; } if (arg_readonly) @@ -661,7 +695,7 @@ int main(int argc, char *argv[]) { if (r == -EAGAIN) continue; if (r < 0) - goto finish; + return r; } if (streq_ptr(arg_type, CRYPT_TCRYPT)) @@ -679,18 +713,15 @@ int main(int argc, char *argv[]) { key_file = NULL; continue; } - if (r != -EPERM) { - log_error_errno(r, "Failed to activate: %m"); - goto finish; - } + if (r != -EPERM) + return log_error_errno(r, "Failed to activate: %m"); log_warning("Invalid passphrase."); } if (arg_tries != 0 && tries >= arg_tries) { log_error("Too many attempts; giving up."); - r = -EPERM; - goto finish; + return -EPERM; } } else if (streq(argv[1], "detach")) { @@ -698,34 +729,23 @@ int main(int argc, char *argv[]) { r = crypt_init_by_name(&cd, argv[2]); if (r == -ENODEV) { log_info("Volume %s already inactive.", argv[2]); - r = 0; - goto finish; - } - if (r < 0) { - log_error_errno(r, "crypt_init_by_name() failed: %m"); - goto finish; + return 0; } + if (r < 0) + return log_error_errno(r, "crypt_init_by_name() failed: %m"); crypt_set_log_callback(cd, cryptsetup_log_glue, NULL); r = crypt_deactivate(cd, argv[2]); - if (r < 0) { - log_error_errno(r, "Failed to deactivate: %m"); - goto finish; - } + if (r < 0) + return log_error_errno(r, "Failed to deactivate: %m"); } else { log_error("Unknown verb %s.", argv[1]); - goto finish; + return -EINVAL; } - r = 0; - -finish: - free(arg_cipher); - free(arg_hash); - free(arg_header); - strv_free(arg_tcrypt_keyfiles); - - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + return 0; } + +DEFINE_MAIN_FUNCTION(run); |