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 <mbroz@redhat.com>

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@105 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
Milan Broz
2009-09-08 06:41:44 +00:00
parent 3cea5dcc7b
commit a47856ac49
8 changed files with 141 additions and 62 deletions

View File

@@ -1,3 +1,6 @@
2009-09-08 Milan Broz <mbroz@redhat.com>
* Use dm-uuid for all crypt devices, contains device type and name now.
2009-09-02 Milan Broz <mbroz@redhat.com> 2009-09-02 Milan Broz <mbroz@redhat.com>
* Add luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase). * Add luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase).
@@ -20,7 +23,6 @@
* Implement old API calls using new functions. * Implement old API calls using new functions.
* Remove old API code helper functions. * Remove old API code helper functions.
* Add --master-key-file option for luksFormat and luksAddKey. * Add --master-key-file option for luksFormat and luksAddKey.
* Replace not safe option --non-exclusive with --disable-uuid.
2009-08-17 Milan Broz <mbroz@redhat.com> 2009-08-17 Milan Broz <mbroz@redhat.com>
* Fix PBKDF2 speed calculation for large passhrases. * Fix PBKDF2 speed calculation for large passhrases.

View File

@@ -81,8 +81,10 @@ int dm_query_device(const char *name,
int *key_size, int *key_size,
char **key, char **key,
int *read_only, int *read_only,
int *suspended); int *suspended,
int dm_create_device(const char *name, const char *device, const char *cipher, const char *uuid, 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, uint64_t size, uint64_t skip, uint64_t offset,
size_t key_size, const char *key, size_t key_size, const char *key,
int read_only, int reload); int read_only, int reload);

View File

@@ -2,8 +2,10 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <libdevmapper.h> #include <libdevmapper.h>
#include <linux/dm-ioctl.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <uuid/uuid.h>
#include "internal.h" #include "internal.h"
#include "luks.h" #include "luks.h"
@@ -11,7 +13,6 @@
#define DEVICE_DIR "/dev" #define DEVICE_DIR "/dev"
#define DM_UUID_PREFIX "CRYPT-" #define DM_UUID_PREFIX "CRYPT-"
#define DM_UUID_PREFIX_LEN 6 #define DM_UUID_PREFIX_LEN 6
#define DM_UUID_LEN UUID_STRING_L
#define DM_CRYPT_TARGET "crypt" #define DM_CRYPT_TARGET "crypt"
#define RETRY_COUNT 5 #define RETRY_COUNT 5
@@ -264,9 +265,42 @@ int dm_remove_device(const char *name, int force, uint64_t size)
return r; return r;
} }
#define UUID_LEN 37 /* 36 + \0, libuuid ... */
/*
* UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
* 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, int dm_create_device(const char *name,
const char *device, const char *device,
const char *cipher, const char *cipher,
const char *type,
const char *uuid, const char *uuid,
uint64_t size, uint64_t size,
uint64_t skip, uint64_t skip,
@@ -281,7 +315,7 @@ int dm_create_device(const char *name,
struct dm_info dmi; struct dm_info dmi;
char *params = NULL; char *params = NULL;
char *error = 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; int r = -EINVAL;
uint32_t read_ahead = 0; uint32_t read_ahead = 0;
@@ -289,17 +323,27 @@ int dm_create_device(const char *name,
if (!params) if (!params)
goto out_no_removal; goto out_no_removal;
if (uuid) { /* All devices must have DM_UUID, only resize on old device is exception */
strncpy(dev_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN); if (reload) {
strncpy(dev_uuid + DM_UUID_PREFIX_LEN, uuid, DM_UUID_LEN); if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
dev_uuid[DM_UUID_PREFIX_LEN + DM_UUID_LEN] = '\0';
}
if (!(dmt = dm_task_create(reload ? DM_DEVICE_RELOAD
: DM_DEVICE_CREATE)))
goto out_no_removal; goto out_no_removal;
if (!dm_task_set_name(dmt, name)) if (!dm_task_set_name(dmt, name))
goto out_no_removal; 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 (read_only && !dm_task_set_ro(dmt)) if (read_only && !dm_task_set_ro(dmt))
goto out_no_removal; goto out_no_removal;
if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params)) 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; goto out_no_removal;
#endif #endif
if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
goto out_no_removal;
if (!dm_task_run(dmt)) if (!dm_task_run(dmt))
goto out_no_removal; goto out_no_removal;
@@ -412,12 +453,13 @@ int dm_query_device(const char *name,
int *key_size, int *key_size,
char **key, char **key,
int *read_only, int *read_only,
int *suspended) int *suspended,
char **uuid)
{ {
struct dm_task *dmt; struct dm_task *dmt;
struct dm_info dmi; struct dm_info dmi;
uint64_t start, length, val64; 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; void *next = NULL;
int i, r = -EINVAL; int i, r = -EINVAL;
@@ -508,6 +550,10 @@ int dm_query_device(const char *name,
if (suspended) if (suspended)
*suspended = dmi.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); r = (dmi.open_count > 0);
out: out:
if (dmt) if (dmt)

View File

@@ -372,7 +372,7 @@ static int create_device_helper(struct crypt_device *cd,
if (!processed_key) if (!processed_key)
return -ENOENT; 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); key_size, processed_key, read_only, reload);
free(dm_cipher); free(dm_cipher);
@@ -402,7 +402,8 @@ static int open_from_hdr_and_mk(struct crypt_device *cd,
crypt_get_cipher_mode(cd)) < 0) crypt_get_cipher_mode(cd)) < 0)
r = -ENOMEM; r = -ENOMEM;
else else
r = dm_create_device(name, cd->device, cipher, no_uuid ? NULL : crypt_get_uuid(cd), r = dm_create_device(name, cd->device, cipher, cd->type,
no_uuid ? NULL : crypt_get_uuid(cd),
size, 0, offset, mk->keyLength, mk->key, size, 0, offset, mk->keyLength, mk->key,
read_only, 0); read_only, 0);
free(cipher); free(cipher);
@@ -490,15 +491,23 @@ static void key_from_file(struct crypt_device *cd, char *msg,
} }
static int _crypt_init(struct crypt_device **cd, static int _crypt_init(struct crypt_device **cd,
const char *type,
struct crypt_options *options, struct crypt_options *options,
int load, int need_dm) 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, /* Some of old API calls do not require DM in kernel,
fake initialisation by initialise it with kernel_check disabled */ fake initialisation by initialise it with kernel_check disabled */
if (!need_dm) if (!need_dm)
(void)dm_init(NULL, 0); (void)dm_init(NULL, 0);
if (init_by_name)
r = crypt_init_by_name(cd, options->name);
else
r = crypt_init(cd, options->device); r = crypt_init(cd, options->device);
if (!need_dm) if (!need_dm)
dm_exit(); dm_exit();
@@ -511,11 +520,20 @@ static int _crypt_init(struct crypt_device **cd,
crypt_set_timeout(*cd, options->timeout); crypt_set_timeout(*cd, options->timeout);
crypt_set_password_retry(*cd, options->tries); 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); crypt_set_password_verify(*cd, options->flags & CRYPT_FLAG_VERIFY);
if (load) if (load && !init_by_name)
r = crypt_load(*cd, CRYPT_LUKS1, NULL); 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; return r;
} }
@@ -554,7 +572,7 @@ int crypt_create_device(struct crypt_options *options)
unsigned int keyLen; unsigned int keyLen;
int r; int r;
r = _crypt_init(&cd, options, 0, 1); r = _crypt_init(&cd, CRYPT_PLAIN, options, 0, 1);
if (r) if (r)
return r; return r;
@@ -582,7 +600,7 @@ int crypt_update_device(struct crypt_options *options)
unsigned int keyLen; unsigned int keyLen;
int r; int r;
r = _crypt_init(&cd, options, 0, 1); r = _crypt_init(&cd, CRYPT_PLAIN, options, 1, 1);
if (r) if (r)
return r; return r;
@@ -606,30 +624,43 @@ int crypt_update_device(struct crypt_options *options)
int crypt_resize_device(struct crypt_options *options) int crypt_resize_device(struct crypt_options *options)
{ {
struct crypt_device *cd = NULL; 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; uint64_t size, skip, offset;
int key_size, read_only, r; int key_size, read_only, r;
r = dm_query_device(options->name, &device, &size, &skip, &offset, 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) 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) if (r)
return r; goto out;
size = options->size; size = options->size;
r = device_check_and_adjust(cd, device, &size, &offset, &read_only); r = device_check_and_adjust(cd, device, &size, &offset, &read_only);
if (r) 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); key_size, key, read_only, 1);
out:
safe_free(key); safe_free(key);
free(cipher); free(cipher);
free(device); free(device);
free(uuid);
crypt_free(cd); crypt_free(cd);
return r; 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, r = dm_query_device(options->name, (char **)&options->device, &options->size,
&options->skip, &options->offset, (char **)&options->cipher, &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) if (r < 0)
return r; return r;
@@ -686,7 +717,7 @@ int crypt_luksFormat(struct crypt_options *options)
return r; return r;
} }
if ((r = _crypt_init(&cd, options, 0, 1))) if ((r = _crypt_init(&cd, CRYPT_LUKS1, options, 0, 1)))
return r; return r;
if (options->key_slot >= LUKS_NUMKEYS && options->key_slot != CRYPT_ANY_SLOT) { 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) if (!options->name)
return -EINVAL; return -EINVAL;
r = _crypt_init(&cd, options, 1, 1); r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
if (r) if (r)
return r; return r;
@@ -758,7 +789,7 @@ int crypt_luksKillSlot(struct crypt_options *options)
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
r = _crypt_init(&cd, options, 1, 1); r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
if (r) if (r)
return r; return r;
@@ -775,7 +806,7 @@ int crypt_luksRemoveKey(struct crypt_options *options)
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
r = _crypt_init(&cd, options, 1, 1); r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
if (r) if (r)
return r; return r;
@@ -794,7 +825,7 @@ int crypt_luksAddKey(struct crypt_options *options)
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r = -EINVAL; int r = -EINVAL;
r = _crypt_init(&cd, options, 1, 1); r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
if (r) if (r)
return r; return r;
@@ -817,7 +848,7 @@ int crypt_luksUUID(struct crypt_options *options)
char *uuid; char *uuid;
int r; int r;
r = _crypt_init(&cd, options, 1, 0); r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
if (r) if (r)
return r; return r;
@@ -834,7 +865,8 @@ int crypt_isLuks(struct crypt_options *options)
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
r = _crypt_init(&cd, options, 1, 0); r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
if (!r)
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
@@ -845,7 +877,7 @@ int crypt_luksDump(struct crypt_options *options)
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
r = _crypt_init(&cd, options, 1, 0); r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
if(r < 0) if(r < 0)
return r; 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, r = dm_query_device(name, &device, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL, NULL, NULL);
if (!r) if (!r)
r = crypt_init(cd, device); 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, r = dm_query_device(name, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, &suspended); NULL, NULL, NULL, NULL, &suspended, NULL);
if (r < 0) if (r < 0)
return r; return r;
@@ -1157,7 +1189,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
} }
r = dm_query_device(name, NULL, NULL, NULL, NULL, r = dm_query_device(name, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, &suspended); NULL, NULL, NULL, NULL, &suspended, NULL);
if (r < 0) if (r < 0)
return r; return r;
@@ -1204,7 +1236,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
} }
r = dm_query_device(name, NULL, NULL, NULL, NULL, r = dm_query_device(name, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, &suspended); NULL, NULL, NULL, NULL, &suspended, NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@@ -71,7 +71,7 @@ static int setup_mapping(const char *cipher, const char *name,
size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE; size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
cleaner_size = 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); keyLength, key, (mode == O_RDONLY), 0);
} }

View File

@@ -146,9 +146,6 @@ This option is only relevant for \fIcreate\fR action.
.B "\-\-readonly" .B "\-\-readonly"
set up a read-only mapping. set up a read-only mapping.
.TP .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" .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. 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 .TP

View File

@@ -34,7 +34,7 @@ static int opt_version_mode = 0;
static int opt_timeout = 0; static int opt_timeout = 0;
static int opt_tries = 3; static int opt_tries = 3;
static int opt_align_payload = 0; static int opt_align_payload = 0;
static int opt_disable_uuid = 0; static int opt_non_exclusive = 0;
static const char **action_argv; static const char **action_argv;
static int action_argc; static int action_argc;
@@ -375,8 +375,8 @@ static int action_luksOpen(int arg)
if (opt_readonly) if (opt_readonly)
options.flags |= CRYPT_FLAG_READONLY; options.flags |= CRYPT_FLAG_READONLY;
if (opt_disable_uuid) /* Abuse old flag */ if (opt_non_exclusive)
options.flags |= CRYPT_FLAG_NON_EXCLUSIVE_ACCESS; log_err(_("Obsolete option --non-exclusive is ignored.\n"));
return crypt_luksOpen(&options); 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") }, { "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 }, { "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 <n> sector boundaries - for luksFormat"), N_("SECTORS") }, { "align-payload", '\0', POPT_ARG_INT, &opt_align_payload, 0, N_("Align payload at <n> 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 POPT_TABLEEND
}; };
poptContext popt_context; poptContext popt_context;