static bool opt_readonly = false;
static bool opt_verify = false;
static bool opt_discards = false;
-static usec_t opt_timeout = DEFAULT_TIMEOUT_USEC;
+static usec_t opt_timeout = 0;
/* Options Debian's crypttab knows we don't:
assert(option);
/* Handled outside of this tool */
- if (streq(option, "noauto"))
+ if (streq(option, "noauto") || streq(option, "nofail"))
return 0;
if (startswith(option, "cipher=")) {
char *t;
- if (!(t = strdup(option+7)))
+ t = strdup(option+7);
+ if (!t)
return -ENOMEM;
free(opt_cipher);
} else if (startswith(option, "hash=")) {
char *t;
- if (!(t = strdup(option+5)))
+ t = strdup(option+5);
+ if (!t)
return -ENOMEM;
free(opt_hash);
return 0;
}
- } else if (streq(option, "readonly"))
+ } else if (streq(option, "readonly") || streq(option, "read-only"))
opt_readonly = true;
else if (streq(option, "verify"))
opt_verify = true;
opt_type = CRYPT_PLAIN;
else if (startswith(option, "timeout=")) {
- if (parse_usec(option+8, &opt_timeout) < 0) {
+ if (parse_sec(option+8, &opt_timeout) < 0) {
log_error("timeout= parse failure, ignoring.");
return 0;
}
}
static int parse_options(const char *options) {
- char *state;
- char *w;
+ char *state, *w;
size_t l;
+ int r;
assert(options);
FOREACH_WORD_SEPARATOR(w, l, options, ",", state) {
- char *o;
- int r;
+ _cleanup_free_ char *o;
- if (!(o = strndup(w, l)))
+ o = strndup(w, l);
+ if (!o)
return -ENOMEM;
-
r = parse_one_option(o);
- free(o);
-
if (r < 0)
return r;
}
}
static char *disk_description(const char *path) {
+
+ static const char name_fields[] = {
+ "ID_PART_ENTRY_NAME\0"
+ "DM_NAME\0"
+ "ID_MODEL_FROM_DATABASE\0"
+ "ID_MODEL\0"
+ };
+
struct udev *udev = NULL;
struct udev_device *device = NULL;
struct stat st;
char *description = NULL;
- const char *model;
+ const char *i;
assert(path);
if (!S_ISBLK(st.st_mode))
return NULL;
- if (!(udev = udev_new()))
+ udev = udev_new();
+ if (!udev)
return NULL;
- if (!(device = udev_device_new_from_devnum(udev, 'b', st.st_rdev)))
+ device = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+ if (!device)
goto finish;
- if ((model = udev_device_get_property_value(device, "ID_MODEL_FROM_DATABASE")) ||
- (model = udev_device_get_property_value(device, "ID_MODEL")) ||
- (model = udev_device_get_property_value(device, "DM_NAME")))
- description = strdup(model);
+ NULSTR_FOREACH(i, name_fields) {
+ const char *name;
+
+ name = udev_device_get_property_value(device, i);
+ if (!isempty(name)) {
+ description = strdup(name);
+ break;
+ }
+ }
finish:
if (device)
key_file = argv[4];
}
- if (argc >= 6 && argv[5][0] && !streq(argv[5], "-"))
- parse_options(argv[5]);
+ if (argc >= 6 && argv[5][0] && !streq(argv[5], "-")) {
+ if (parse_options(argv[5]) < 0)
+ goto finish;
+ }
/* A delicious drop of snake oil */
mlockall(MCL_FUTURE);
name = name_buffer ? name_buffer : argv[2];
- if ((k = crypt_init(&cd, argv[3]))) {
+ k = crypt_init(&cd, argv[3]);
+ if (k) {
log_error("crypt_init() failed: %s", strerror(-k));
goto finish;
}
size_t l;
l = strcspn(opt_cipher, "-");
+ truncated_cipher = strndup(opt_cipher, l);
- if (!(truncated_cipher = strndup(opt_cipher, l))) {
+ if (!truncated_cipher) {
log_oom();
goto finish;
}
passwords = NULL;
if (!key_file) {
- char *text;
- char **p;
+ char *text, **p;
if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) {
log_oom();
k = crypt_load(cd, CRYPT_LUKS1, NULL);
if ((!opt_type && k < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) {
- struct crypt_params_plain params;
-
- zero(params);
- params.hash = hash;
+ struct crypt_params_plain params = { .hash = hash };
/* for CRYPT_PLAIN limit reads
* from keyfile to key length, and
crypt_get_volume_key_size(cd)*8,
argv[3]);
- if (key_file)
- k = crypt_activate_by_keyfile_offset(cd, argv[2], CRYPT_ANY_SLOT, key_file, opt_keyfile_size,
- opt_keyfile_offset, flags);
- else {
+ if (key_file) {
+ struct stat st;
+
+ /* Ideally we'd do this on the open
+ * fd, but since this is just a
+ * warning it's OK to do this in two
+ * steps */
+ if (stat(key_file, &st) >= 0 && (st.st_mode & 0005))
+ log_warning("Key file %s is world-readable. That's certainly not a good idea.", key_file);
+
+ k = crypt_activate_by_keyfile_offset(
+ cd, argv[2], CRYPT_ANY_SLOT, key_file, opt_keyfile_size,
+ opt_keyfile_offset, flags);
+ if (k < 0) {
+ log_error("Failed to activate with key file '%s': %s", key_file, strerror(-k));
+ key_file = NULL;
+ continue;
+ }
+ } else {
char **p;
STRV_FOREACH(p, passwords) {
} else if (streq(argv[1], "detach")) {
int k;
- if ((k = crypt_init_by_name(&cd, argv[2]))) {
+ k = crypt_init_by_name(&cd, argv[2]);
+ if (k) {
log_error("crypt_init() failed: %s", strerror(-k));
goto finish;
}
crypt_set_log_callback(cd, log_glue, NULL);
- if ((k = crypt_deactivate(cd, argv[2])) < 0) {
+ k = crypt_deactivate(cd, argv[2]);
+ if (k < 0) {
log_error("Failed to deactivate: %s", strerror(-k));
goto finish;
}