From a47856ac496753ab3150ac2507bac692b400914a Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 8 Sep 2009 06:41:44 +0000 Subject: [PATCH] Use dm-uuid for all crypt devices, contains device type and name now. DM_UUID now contains prefix (CRYPT-), device type (LUKS1, PLAIN, TEMP), UUID (if provided - LUKS) and device name. Because e.g. snapshot of full LUKS device during activation must have different name, DM-UUID is different too and we do not need --disable-uuid option. DM-UUID is persistent during activation time. * Revert (and solve different way): Replace not safe option --non-exclusive with --disable-uuid. Signed-off-by: Milan Broz git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@105 36d66b0a-2a48-0410-832c-cd162a569da5 --- ChangeLog | 4 ++- lib/internal.h | 6 ++-- lib/libcryptsetup.h | 2 +- lib/libdevmapper.c | 80 +++++++++++++++++++++++++++++++++--------- lib/setup.c | 98 ++++++++++++++++++++++++++++++++++------------------ luks/keyencryption.c | 2 +- man/cryptsetup.8 | 3 -- src/cryptsetup.c | 8 ++--- 8 files changed, 141 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6e4ccd2..abc5a5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2009-09-08 Milan Broz + * Use dm-uuid for all crypt devices, contains device type and name now. + 2009-09-02 Milan Broz * Add luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase). @@ -20,7 +23,6 @@ * Implement old API calls using new functions. * Remove old API code helper functions. * Add --master-key-file option for luksFormat and luksAddKey. - * Replace not safe option --non-exclusive with --disable-uuid. 2009-08-17 Milan Broz * Fix PBKDF2 speed calculation for large passhrases. diff --git a/lib/internal.h b/lib/internal.h index 62c44f5..bf0e5fb 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -81,8 +81,10 @@ int dm_query_device(const char *name, int *key_size, char **key, int *read_only, - int *suspended); -int dm_create_device(const char *name, const char *device, const char *cipher, const char *uuid, + int *suspended, + char **uuid); +int dm_create_device(const char *name, const char *device, const char *cipher, + const char *type, const char *uuid, uint64_t size, uint64_t skip, uint64_t offset, size_t key_size, const char *key, int read_only, int reload); diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index 3c296a9..cdd30ec 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -471,7 +471,7 @@ void crypt_set_debug_level(int level); * Provided only for backward compatibility. */ -struct interface_callbacks { +struct interface_callbacks { int (*yesDialog)(char *msg); void (*log)(int class, char *msg); }; diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index 61d0369..d359737 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -2,8 +2,10 @@ #include #include #include +#include #include #include +#include #include "internal.h" #include "luks.h" @@ -11,7 +13,6 @@ #define DEVICE_DIR "/dev" #define DM_UUID_PREFIX "CRYPT-" #define DM_UUID_PREFIX_LEN 6 -#define DM_UUID_LEN UUID_STRING_L #define DM_CRYPT_TARGET "crypt" #define RETRY_COUNT 5 @@ -264,9 +265,42 @@ int dm_remove_device(const char *name, int force, uint64_t size) return r; } +#define UUID_LEN 37 /* 36 + \0, libuuid ... */ +/* + * UUID has format: CRYPT--[-] + * CRYPT-PLAIN-name + * CRYPT-LUKS1-00000000000000000000000000000000-name + * CRYPT-TEMP-name + */ +static void dm_prepare_uuid(const char *name, const char *type, const char *uuid, char *buf, size_t buflen) +{ + char *ptr, uuid2[UUID_LEN] = {0}; + uuid_t uu; + int i = 0; + + /* Remove '-' chars */ + if (uuid && !uuid_parse(uuid, uu)) { + for (ptr = uuid2, i = 0; i < UUID_LEN; i++) + if (uuid[i] != '-') { + *ptr = uuid[i]; + ptr++; + } + } + + i = snprintf(buf, buflen, DM_UUID_PREFIX "%s%s%s%s%s", + type ?: "", type ? "-" : "", + uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "", + name); + + log_dbg("DM-UUID is %s", buf); + if (i >= buflen) + log_err(NULL, _("DM-UUID for device %s was truncated.\n"), name); +} + int dm_create_device(const char *name, const char *device, const char *cipher, + const char *type, const char *uuid, uint64_t size, uint64_t skip, @@ -281,25 +315,35 @@ int dm_create_device(const char *name, struct dm_info dmi; char *params = NULL; char *error = NULL; - char dev_uuid[DM_UUID_PREFIX_LEN + DM_UUID_LEN + 1] = {0}; + char dev_uuid[DM_UUID_LEN] = {0}; int r = -EINVAL; uint32_t read_ahead = 0; params = get_params(device, skip, offset, cipher, key_size, key); if (!params) goto out_no_removal; - - if (uuid) { - strncpy(dev_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN); - strncpy(dev_uuid + DM_UUID_PREFIX_LEN, uuid, DM_UUID_LEN); - dev_uuid[DM_UUID_PREFIX_LEN + DM_UUID_LEN] = '\0'; + + /* All devices must have DM_UUID, only resize on old device is exception */ + if (reload) { + if (!(dmt = dm_task_create(DM_DEVICE_RELOAD))) + goto out_no_removal; + + if (!dm_task_set_name(dmt, name)) + goto out_no_removal; + } else { + dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid)); + + if (!(dmt = dm_task_create(DM_DEVICE_CREATE))) + goto out_no_removal; + + if (!dm_task_set_name(dmt, name)) + goto out_no_removal; + + if (!dm_task_set_uuid(dmt, dev_uuid)) + goto out_no_removal; } - if (!(dmt = dm_task_create(reload ? DM_DEVICE_RELOAD - : DM_DEVICE_CREATE))) - goto out_no_removal; - if (!dm_task_set_name(dmt, name)) - goto out_no_removal; + if (read_only && !dm_task_set_ro(dmt)) goto out_no_removal; if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params)) @@ -311,9 +355,6 @@ int dm_create_device(const char *name, goto out_no_removal; #endif - if (uuid && !dm_task_set_uuid(dmt, dev_uuid)) - goto out_no_removal; - if (!dm_task_run(dmt)) goto out_no_removal; @@ -412,12 +453,13 @@ int dm_query_device(const char *name, int *key_size, char **key, int *read_only, - int *suspended) + int *suspended, + char **uuid) { struct dm_task *dmt; struct dm_info dmi; uint64_t start, length, val64; - char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3]; + char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3], *tmp_uuid; void *next = NULL; int i, r = -EINVAL; @@ -508,6 +550,10 @@ int dm_query_device(const char *name, if (suspended) *suspended = dmi.suspended; + if (uuid && (tmp_uuid = (char*)dm_task_get_uuid(dmt)) && + !strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN)) + *uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN); + r = (dmi.open_count > 0); out: if (dmt) diff --git a/lib/setup.c b/lib/setup.c index 4854cc0..3fb8486 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -372,7 +372,7 @@ static int create_device_helper(struct crypt_device *cd, if (!processed_key) return -ENOENT; - r = dm_create_device(name, cd->device, dm_cipher ?: cipher, uuid, size, skip, offset, + r = dm_create_device(name, cd->device, dm_cipher ?: cipher, cd->type, uuid, size, skip, offset, key_size, processed_key, read_only, reload); free(dm_cipher); @@ -402,9 +402,10 @@ static int open_from_hdr_and_mk(struct crypt_device *cd, crypt_get_cipher_mode(cd)) < 0) r = -ENOMEM; else - r = dm_create_device(name, cd->device, cipher, no_uuid ? NULL : crypt_get_uuid(cd), - size, 0, offset, mk->keyLength, mk->key, - read_only, 0); + r = dm_create_device(name, cd->device, cipher, cd->type, + no_uuid ? NULL : crypt_get_uuid(cd), + size, 0, offset, mk->keyLength, mk->key, + read_only, 0); free(cipher); return r; } @@ -490,16 +491,24 @@ static void key_from_file(struct crypt_device *cd, char *msg, } static int _crypt_init(struct crypt_device **cd, + const char *type, struct crypt_options *options, int load, int need_dm) { - int r; + int init_by_name, r; + + /* if it is plain device and mapping table is being reloaded + initialize it by name*/ + init_by_name = (type && !strcmp(type, CRYPT_PLAIN) && load); /* Some of old API calls do not require DM in kernel, fake initialisation by initialise it with kernel_check disabled */ if (!need_dm) (void)dm_init(NULL, 0); - r = crypt_init(cd, options->device); + if (init_by_name) + r = crypt_init_by_name(cd, options->name); + else + r = crypt_init(cd, options->device); if (!need_dm) dm_exit(); @@ -511,11 +520,20 @@ static int _crypt_init(struct crypt_device **cd, crypt_set_timeout(*cd, options->timeout); crypt_set_password_retry(*cd, options->tries); - crypt_set_iterarion_time(*cd, options->iteration_time); + crypt_set_iterarion_time(*cd, options->iteration_time ?: 1000); crypt_set_password_verify(*cd, options->flags & CRYPT_FLAG_VERIFY); - if (load) - r = crypt_load(*cd, CRYPT_LUKS1, NULL); + if (load && !init_by_name) + r = crypt_load(*cd, type, NULL); + + if (type && !(*cd)->type) { + (*cd)->type = strdup(type); + if (!(*cd)->type) + r = -ENOMEM; + } + + if (r) + crypt_free(*cd); return r; } @@ -554,7 +572,7 @@ int crypt_create_device(struct crypt_options *options) unsigned int keyLen; int r; - r = _crypt_init(&cd, options, 0, 1); + r = _crypt_init(&cd, CRYPT_PLAIN, options, 0, 1); if (r) return r; @@ -582,7 +600,7 @@ int crypt_update_device(struct crypt_options *options) unsigned int keyLen; int r; - r = _crypt_init(&cd, options, 0, 1); + r = _crypt_init(&cd, CRYPT_PLAIN, options, 1, 1); if (r) return r; @@ -606,30 +624,43 @@ int crypt_update_device(struct crypt_options *options) int crypt_resize_device(struct crypt_options *options) { struct crypt_device *cd = NULL; - char *device, *cipher, *key = NULL; + char *device = NULL, *cipher = NULL, *uuid = NULL, *key = NULL; + char *type = NULL; uint64_t size, skip, offset; int key_size, read_only, r; r = dm_query_device(options->name, &device, &size, &skip, &offset, - &cipher, &key_size, &key, &read_only, NULL); + &cipher, &key_size, &key, &read_only, NULL, &uuid); if (r < 0) - return r; + goto out; - r = _crypt_init(&cd, options, 0, 1); + /* Try to determine type of device from UUID */ + if (uuid) { + if (!strncmp(uuid, CRYPT_PLAIN, strlen(CRYPT_PLAIN))) { + type = CRYPT_PLAIN; + free (uuid); + uuid = NULL; + } else if (!strncmp(uuid, CRYPT_LUKS1, strlen(CRYPT_LUKS1))) + type = CRYPT_LUKS1; + } + + r = _crypt_init(&cd, type, options, 1, 1); if (r) - return r; + goto out; size = options->size; r = device_check_and_adjust(cd, device, &size, &offset, &read_only); if (r) - return r; + goto out; - r = dm_create_device(options->name, device, cipher, NULL, size, skip, offset, + r = dm_create_device(options->name, device, cipher, type, + crypt_get_uuid(cd), size, skip, offset, key_size, key, read_only, 1); - +out: safe_free(key); free(cipher); free(device); + free(uuid); crypt_free(cd); return r; } @@ -645,7 +676,7 @@ int crypt_query_device(struct crypt_options *options) r = dm_query_device(options->name, (char **)&options->device, &options->size, &options->skip, &options->offset, (char **)&options->cipher, - &options->key_size, NULL, &read_only, NULL); + &options->key_size, NULL, &read_only, NULL, NULL); if (r < 0) return r; @@ -686,7 +717,7 @@ int crypt_luksFormat(struct crypt_options *options) return r; } - if ((r = _crypt_init(&cd, options, 0, 1))) + if ((r = _crypt_init(&cd, CRYPT_LUKS1, options, 0, 1))) return r; if (options->key_slot >= LUKS_NUMKEYS && options->key_slot != CRYPT_ANY_SLOT) { @@ -728,7 +759,7 @@ int crypt_luksOpen(struct crypt_options *options) if (!options->name) return -EINVAL; - r = _crypt_init(&cd, options, 1, 1); + r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1); if (r) return r; @@ -758,7 +789,7 @@ int crypt_luksKillSlot(struct crypt_options *options) struct crypt_device *cd = NULL; int r; - r = _crypt_init(&cd, options, 1, 1); + r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1); if (r) return r; @@ -775,7 +806,7 @@ int crypt_luksRemoveKey(struct crypt_options *options) struct crypt_device *cd = NULL; int r; - r = _crypt_init(&cd, options, 1, 1); + r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1); if (r) return r; @@ -794,7 +825,7 @@ int crypt_luksAddKey(struct crypt_options *options) struct crypt_device *cd = NULL; int r = -EINVAL; - r = _crypt_init(&cd, options, 1, 1); + r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1); if (r) return r; @@ -817,7 +848,7 @@ int crypt_luksUUID(struct crypt_options *options) char *uuid; int r; - r = _crypt_init(&cd, options, 1, 0); + r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0); if (r) return r; @@ -834,8 +865,9 @@ int crypt_isLuks(struct crypt_options *options) struct crypt_device *cd = NULL; int r; - r = _crypt_init(&cd, options, 1, 0); - crypt_free(cd); + r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0); + if (!r) + crypt_free(cd); return r; } @@ -845,7 +877,7 @@ int crypt_luksDump(struct crypt_options *options) struct crypt_device *cd = NULL; int r; - r = _crypt_init(&cd, options, 1, 0); + r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0); if(r < 0) return r; @@ -943,7 +975,7 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name) } r = dm_query_device(name, &device, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL, NULL); if (!r) r = crypt_init(cd, device); @@ -1123,7 +1155,7 @@ int crypt_suspend(struct crypt_device *cd, } r = dm_query_device(name, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, &suspended); + NULL, NULL, NULL, NULL, &suspended, NULL); if (r < 0) return r; @@ -1157,7 +1189,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd, } r = dm_query_device(name, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, &suspended); + NULL, NULL, NULL, NULL, &suspended, NULL); if (r < 0) return r; @@ -1204,7 +1236,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd, } r = dm_query_device(name, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, &suspended); + NULL, NULL, NULL, NULL, &suspended, NULL); if (r < 0) return r; diff --git a/luks/keyencryption.c b/luks/keyencryption.c index f32729b..28b1a0d 100644 --- a/luks/keyencryption.c +++ b/luks/keyencryption.c @@ -71,7 +71,7 @@ static int setup_mapping(const char *cipher, const char *name, size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE; cleaner_size = size; - return dm_create_device(name, device, cipher, NULL, size, 0, sector, + return dm_create_device(name, device, cipher, "TEMP", NULL, size, 0, sector, keyLength, key, (mode == O_RDONLY), 0); } diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index 8c9ac46..423df19 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -146,9 +146,6 @@ This option is only relevant for \fIcreate\fR action. .B "\-\-readonly" set up a read-only mapping. .TP -.B "\-\-disable-uuid" -Activate device without UUID. Useful for \fIluksOpen\fR to activate cloned LUKS device or its snapshot. -.TP .B "\-\-iter-time, \-i" The number of milliseconds to spend with PBKDF2 password processing. This option is only relevant to the LUKS operations as \fIluksFormat\fR or \fIluksAddKey\fR. .TP diff --git a/src/cryptsetup.c b/src/cryptsetup.c index db51c14..dc337fc 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -34,7 +34,7 @@ static int opt_version_mode = 0; static int opt_timeout = 0; static int opt_tries = 3; static int opt_align_payload = 0; -static int opt_disable_uuid = 0; +static int opt_non_exclusive = 0; static const char **action_argv; static int action_argc; @@ -375,8 +375,8 @@ static int action_luksOpen(int arg) if (opt_readonly) options.flags |= CRYPT_FLAG_READONLY; - if (opt_disable_uuid) /* Abuse old flag */ - options.flags |= CRYPT_FLAG_NON_EXCLUSIVE_ACCESS; + if (opt_non_exclusive) + log_err(_("Obsolete option --non-exclusive is ignored.\n")); return crypt_luksOpen(&options); } @@ -637,7 +637,7 @@ int main(int argc, char **argv) { "timeout", 't', POPT_ARG_INT, &opt_timeout, 0, N_("Timeout for interactive passphrase prompt (in seconds)"), N_("secs") }, { "tries", 'T', POPT_ARG_INT, &opt_tries, 0, N_("How often the input of the passphrase canbe retried"), NULL }, { "align-payload", '\0', POPT_ARG_INT, &opt_align_payload, 0, N_("Align payload at sector boundaries - for luksFormat"), N_("SECTORS") }, - { "disable-uuid", '\0', POPT_ARG_NONE, &opt_disable_uuid, 0, N_("Do not set UUID for device luksOpen."), NULL }, + { "non-exclusive", '\0', POPT_ARG_NONE, &opt_non_exclusive, 0, N_("Allows non-exclusive access for luksOpen, WARNING see manpage."), NULL }, POPT_TABLEEND }; poptContext popt_context; -- 2.7.4