Commit a38cb237 authored by Milan Broz's avatar Milan Broz

* Add crypt_set_uuid() to API.

* Allow UUID setting in luksFormat and luksUUID (--uuid parameter).

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@355 36d66b0a-2a48-0410-832c-cd162a569da5
parent dfe77be7
......@@ -4,6 +4,8 @@
* Implement --use-random and --use-urandom for luksFormat to allow
setting of RNG for volume key generator.
* Add crypt_set_rng_type() and crypt_get_rng_type() to API.
* Add crypt_set_uuid() to API.
* Allow UUID setting in luksFormat and luksUUID (--uuid parameter).
2010-10-17 Milan Broz <mbroz@redhat.com>
* Add crypt_get_device_name() to API (get underlying device name).
......
......@@ -182,6 +182,17 @@ int crypt_format(struct crypt_device *cd,
size_t volume_key_size,
void *params);
/**
* Set new UUID for already existing device (if format supports it)
*
* Returns 0 on success or negative errno value otherwise.
*
* @cd - crypt device handle
* @uuid - requested UUID or NULL if it should be generated
*/
int crypt_set_uuid(struct crypt_device *cd,
const char *uuid);
/**
* Load crypt device parameters from on-disk header
*
......
......@@ -9,6 +9,7 @@ CRYPTSETUP_1.0 {
crypt_set_password_retry;
crypt_set_iterarion_time;
crypt_set_password_verify;
crypt_set_uuid;
crypt_memory_lock;
crypt_format;
......
......@@ -1186,6 +1186,30 @@ int crypt_load(struct crypt_device *cd,
return r;
}
int crypt_set_uuid(struct crypt_device *cd, const char *uuid)
{
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is not supported for this device type.\n"));
return -EINVAL;
}
if (uuid && !strncmp(uuid, cd->hdr.uuid, sizeof(cd->hdr.uuid))) {
log_dbg("UUID is the same as requested (%s) for device %s.",
uuid, cd->device);
return 0;
}
if (uuid)
log_dbg("Requested new UUID change to %s for %s.", uuid, cd->device);
else
log_dbg("Requested new UUID refresh for %s.", cd->device);
if (!crypt_confirm(cd, _("Do you really want to change UUID of device?")))
return -EPERM;
return LUKS_hdr_uuid_set(cd->device, &cd->hdr, uuid, cd);
}
int crypt_header_backup(struct crypt_device *cd,
const char *requested_type,
const char *backup_file)
......@@ -2015,8 +2039,6 @@ int crypt_dump(struct crypt_device *cd)
log_std(cd, "Key Slot %d: DISABLED\n", i);
}
log_std(cd, "DNAME: %s\n", crypt_get_device_name(cd) ?: "");
return 0;
}
......
......@@ -411,6 +411,13 @@ int LUKS_generate_phdr(struct luks_phdr *header,
return -EINVAL;
}
if (uuid && uuid_parse(uuid, partitionUuid) == -1) {
log_err(ctx, _("Wrong LUKS UUID format provided.\n"));
return -EINVAL;
}
if (!uuid)
uuid_generate(partitionUuid);
memset(header,0,sizeof(struct luks_phdr));
/* Set Magic */
......@@ -465,12 +472,6 @@ int LUKS_generate_phdr(struct luks_phdr *header,
/* alignOffset - offset from natural device alignment provided by topology info */
header->payloadOffset = currentSector + alignOffset;
if (uuid && !uuid_parse(uuid, partitionUuid)) {
log_err(ctx, _("Wrong UUID format provided, generating new one.\n"));
uuid = NULL;
}
if (!uuid)
uuid_generate(partitionUuid);
uuid_unparse(partitionUuid, header->uuid);
log_dbg("Data offset %d, UUID %s, digest iterations %" PRIu32,
......@@ -479,6 +480,26 @@ int LUKS_generate_phdr(struct luks_phdr *header,
return 0;
}
int LUKS_hdr_uuid_set(
const char *device,
struct luks_phdr *hdr,
const char *uuid,
struct crypt_device *ctx)
{
uuid_t partitionUuid;
if (uuid && uuid_parse(uuid, partitionUuid) == -1) {
log_err(ctx, _("Wrong LUKS UUID format provided.\n"));
return -EINVAL;
}
if (!uuid)
uuid_generate(partitionUuid);
uuid_unparse(partitionUuid, hdr->uuid);
return LUKS_write_phdr(device, hdr, ctx);
}
int LUKS_set_key(const char *device, unsigned int keyIndex,
const char *password, size_t passwordLen,
struct luks_phdr *hdr, struct volume_key *vk,
......
......@@ -103,6 +103,12 @@ int LUKS_read_phdr_backup(
int require_luks_device,
struct crypt_device *ctx);
int LUKS_hdr_uuid_set(
const char *device,
struct luks_phdr *hdr,
const char *uuid,
struct crypt_device *ctx);
int LUKS_hdr_backup(
const char *backup_file,
const char *device,
......
......@@ -43,7 +43,7 @@ These are valid LUKS actions:
initializes a LUKS partition and sets the initial key, either via prompting or via <key file>.
\fB<options>\fR can be [\-\-cipher, \-\-verify-passphrase, \-\-key-size, \-\-key-slot,
\-\-key-file (takes precedence over optional second argument), \-\-use-random | \-\-use-urandom].
\-\-key-file (takes precedence over optional second argument), \-\-use-random | \-\-use-urandom, \-\-uuid].
.PP
\fIluksOpen\fR <device> <name>
......@@ -96,6 +96,8 @@ identical to luksKillSlot, but deprecated action name.
\fIluksUUID\fR <device>
.IP
print UUID, if <device> has a LUKS header.
set new UUID if \fI\-\-uuid\fR option is specified.
.PP
\fIisLuks\fR <device>
.IP
......@@ -232,6 +234,11 @@ Align payload at a boundary of \fIvalue\fR 512-byte sectors. This option is rele
If not specified, cryptsetup tries to use topology info provided by kernel for underlying device to get optimal alignment.
If not available (or calculated value is multiple of default) data is by default aligned to 1 MiB boundary (2048 512-byte sectors).
.TP
.B "\-\-uuid=\fIUUID\fR"
Use provided \fIUUID\fR in \fIluksFormat\fR command instead of generating new one or change existing UUID in \fIluksUUID\fR command.
The UUID must be provided in standard UUID format (e.g. 12345678-1234-1234-1234-123456789abc).
.TP
.B "\-\-version"
Show the version.
......
......@@ -24,6 +24,7 @@ static int opt_verify_passphrase = 0;
static char *opt_key_file = NULL;
static char *opt_master_key_file = NULL;
static char *opt_header_backup_file = NULL;
static char *opt_uuid = NULL;
static unsigned int opt_key_size = 0;
static int opt_key_slot = CRYPT_ANY_SLOT;
static uint64_t opt_size = 0;
......@@ -390,7 +391,7 @@ static int action_luksFormat(int arg)
goto out;
r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode,
NULL, key, keysize, &params);
opt_uuid, key, keysize, &params);
if (r < 0)
goto out;
......@@ -400,7 +401,7 @@ static int action_luksFormat(int arg)
crypt_get_key(_("Enter LUKS passphrase: "),
&password, &passwordLen, 0,
key_file, opt_timeout,
opt_verify_passphrase && !opt_batch_mode,
opt_batch_mode ? 0 : 1, /* always verify */
cd);
if(!password) {
......@@ -409,7 +410,7 @@ static int action_luksFormat(int arg)
}
r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode,
NULL, NULL, keysize, &params);
opt_uuid, NULL, keysize, &params);
if (r < 0)
goto out;
......@@ -554,12 +555,30 @@ static int action_isLuks(int arg)
static int action_luksUUID(int arg)
{
struct crypt_options options = {
.device = action_argv[0],
.icb = &cmd_icb,
};
struct crypt_device *cd = NULL;
const char *existing_uuid = NULL;
int r;
if ((r = crypt_init(&cd, action_argv[0])))
goto out;
crypt_set_log_callback(cd, _log, NULL);
crypt_set_confirm_callback(cd, _yesDialog, NULL);
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
goto out;
if (opt_uuid)
r = crypt_set_uuid(cd, opt_uuid);
else {
existing_uuid = crypt_get_uuid(cd);
log_std("%s\n", existing_uuid ?: "");
r = existing_uuid ? 0 : 1;
}
out:
crypt_free(cd);
return r;
return crypt_luksUUID(&options);
}
static int action_luksDump(int arg)
......@@ -759,6 +778,7 @@ int main(int argc, char **argv)
{ "header-backup-file",'\0', POPT_ARG_STRING, &opt_header_backup_file, 0, N_("File with LUKS header and keyslots backup."), NULL },
{ "use-random", '\0', POPT_ARG_NONE, &opt_random, 0, N_("Use /dev/random for generating volume key."), NULL },
{ "use-urandom", '\0', POPT_ARG_NONE, &opt_urandom, 0, N_("Use /dev/urandom for generating volume key."), NULL },
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
POPT_TABLEEND
};
poptContext popt_context;
......@@ -839,6 +859,10 @@ int main(int argc, char **argv)
usage(popt_context, 1, _("Option --use-[u]random is allowed only for luksFormat."),
poptGetInvocationName(popt_context));
if (opt_uuid && strcmp(aname, "luksFormat") && strcmp(aname, "luksUUID"))
usage(popt_context, 1, _("Option --uuid is allowed only for luksFormat and luksUUID."),
poptGetInvocationName(popt_context));
action_argc = 0;
action_argv = poptGetArgs(popt_context);
/* Make return values of poptGetArgs more consistent in case of remaining argc = 0 */
......
......@@ -52,6 +52,8 @@
#define KEYFILE2 "key2.file"
#define KEY2 "0123456789abcdef"
#define DEVICE_TEST_UUID "12345678-1234-1234-1234-123456789abc"
static int _debug = 0;
static int _verbose = 1;
......@@ -740,6 +742,10 @@ static void AddDeviceLuks(void)
crypt_set_log_callback(cd, NULL, NULL);
reset_log();
FAIL_(crypt_set_uuid(cd, "blah"), "wrong UUID format");
OK_(crypt_set_uuid(cd, DEVICE_TEST_UUID));
OK_(strcmp(DEVICE_TEST_UUID, crypt_get_uuid(cd)));
FAIL_(crypt_deactivate(cd, CDEVICE_2), "not active");
crypt_free(cd);
}
......
......@@ -18,6 +18,8 @@ KEY_SLOT1="S256-259 S260-263 R264-295 A296-299 A300-303"
KEY_MATERIAL1="R69632-133632"
KEY_MATERIAL1_EXT="S69632-133632"
TEST_UUID="12345678-1234-1234-1234-123456789abc"
function remove_mapping()
{
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
......@@ -173,5 +175,15 @@ echo -n $'foo\nbar' | $CRYPTSETUP -q luksFormat $LOOPDEV || fail
echo 'foo' | $CRYPTSETUP -q luksOpen $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP -q luksClose $DEV_NAME || fail
prepare "[15] UUID - use and report provided UUID" wipe
echo "key0" | $CRYPTSETUP -q luksFormat --uuid blah $LOOPDEV 2>/dev/null && fail
echo "key0" | $CRYPTSETUP -q luksFormat --uuid $TEST_UUID $LOOPDEV || fail
tst=$($CRYPTSETUP -q luksUUID $LOOPDEV)
[ "$tst"x = "$TEST_UUID"x ] || fail
echo "key0" | $CRYPTSETUP -q luksFormat $LOOPDEV || fail
$CRYPTSETUP -q luksUUID --uuid $TEST_UUID $LOOPDEV || fail
tst=$($CRYPTSETUP -q luksUUID $LOOPDEV)
[ "$tst"x = "$TEST_UUID"x ] || fail
remove_mapping
exit 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment