summaryrefslogtreecommitdiff
path: root/src/cryptsetup/cryptsetup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptsetup/cryptsetup.c')
-rw-r--r--src/cryptsetup/cryptsetup.c172
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, &params);
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);