second update
since the reload function did not work as it should (at least for me it
always generated wrong keys) i did some further work - it's far away
from being beautiful - just a quickndirty hack
and since im a little bit paranoid now its only allowed to remove the
device if key slot 0 is used and i added the readonly check for the
reload mechanism.
i would really appreciate it if someone could point me the right
direction for extending the key slots with a little bit right management
i thought of adding 5 parameters in the structure definition of keyblock
in luks_phdr in luks/luks.h (something like allow_readonly,
allow_reload, allow_remove, allow_status, allow_resize) to be prepared
for building such a small privilege system according to each keyslot.
Martin Strigl schrieb:
hi there, first of all congrats to your work.
i got an idea or to be more precise a feature request. and although i'm
not quite sure if it would be useful to others i want to propose it. and
just for the case noone finds it useful, i would appreciate it if you
could point me in the right direction where to start.
* i got a scenario where it would be very useful if i could open a luks
encrypted device just readonly for certain key slots.
let's say if someone gives the credentials for key slot 1 or 3 it's
opened AUTOMATICALLY as readonly, but if you use key slot 0 or 2 it's
opened just the way you want (normally rw, but in respect to the options
given).
* i thought of 2 ways accomplishing this:
- the first one is the quickndirty hack which just says "okay if its
key slot 0 do what the user wants todo, for all others ALWAYS set
options.flags |= CRYPT_FLAG_READONLY"
- the second one would be more fine. lets define add key creation
time the right (rw or just ro) this key has and according to that do
what you ought todo
* as to the first way, it seems quite clear to me that i just need to
modify the function __crypt_luks_open in lib/setup.c (around the call
LUKS_open_any_key) and according to the return value modify options
* for the second i'm not quite sure where to start
so please share your ideas with me (and excuse my english)
mfg,
martin strigl
diff -urN cryptsetup-luks-1.0.3-orig/lib/setup.c cryptsetup-luks-1.0.3/lib/setup.c
--- cryptsetup-luks-1.0.3-orig/lib/setup.c 2006-04-02 10:58:18.000000000 +0200
+++ cryptsetup-luks-1.0.3/lib/setup.c 2007-04-04 14:46:13.000000000 +0200
@@ -327,14 +327,20 @@
static int __crypt_create_device(int reload, struct setup_backend *backend,
struct crypt_options *options)
{
+ struct luks_masterkey mk;
+ struct luks_phdr hdr;
+ char *password; int passwordLen;
+ char *dmCipherSpec;
+ int r, tries = options->tries;
+ int whichkey;
+
struct crypt_options tmp = {
.name = options->name,
};
struct device_infos infos;
- char *key = NULL;
- int keyLen;
- char *processed_key = NULL;
- int r;
+ //char *key = NULL;
+ //int keyLen;
+ //char *processed_key = NULL;
r = backend->status(0, &tmp, NULL);
if (reload) {
@@ -373,7 +379,7 @@
if (infos.readonly)
options->flags |= CRYPT_FLAG_READONLY;
- get_key(options, "Enter passphrase: ", &key, &keyLen);
+/* get_key(options, "Enter passphrase: ", &key, &keyLen);
if (!key) {
set_error("Key reading error");
return -ENOENT;
@@ -393,10 +399,62 @@
set_error("Key processing error");
return -ENOENT;
}
-
- r = backend->create(reload, options, processed_key);
-
- safe_free(processed_key);
+*/
+start:
+ options->key_size = 0; // FIXME, define a clean interface some day.
+
+ if(get_key(options,"Enter LUKS passphrase: ",&password,&passwordLen))
+ tries--;
+ else
+ tries = 0;
+
+ if(!password) {
+ r = -EINVAL; goto out;
+ }
+ whichkey=LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend);
+ if(whichkey < 0) {
+ set_error("No key available with this passphrase.\n");
+ r = -EPERM; goto out1;
+ }
+ if (whichkey>0) {
+ infos.readonly = 1;
+ options->flags |= CRYPT_FLAG_READONLY;
+ }
+
+
+ options->offset = hdr.payloadOffset;
+ asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode);
+ if(!dmCipherSpec) {
+ r = -ENOMEM;
+ goto out2;
+ }
+ options->cipher = dmCipherSpec;
+ options->key_size = mk.keyLength;
+ options->skip = 0;
+
+ options->size = infos.size;
+ if (!options->size) {
+ set_error("Not a block device.\n");
+ r = -ENOTBLK; goto out2;
+ }
+ if (options->size <= options->offset) {
+ set_error("Invalid offset");
+ r = -EINVAL; goto out2;
+ }
+ options->size -= options->offset;
+ r = backend->create(reload, options, mk.key);
+ //r = backend->create(reload, options, processed_key);
+ //safe_free(processed_key);
+out2:
+ free(dmCipherSpec);
+out1:
+ safe_free(password);
+out:
+ memset(&mk,0,sizeof(mk));
+
+ if (r != 0 && tries > 0)
+ goto start;
+
return r;
}
@@ -457,9 +515,18 @@
static int __crypt_remove_device(int arg, struct setup_backend *backend,
struct crypt_options *options)
{
- int r;
+ struct luks_masterkey mk;
+ struct luks_phdr hdr;
+ char *password; int passwordLen;
+ struct device_infos infos;
+ struct crypt_options tmp = {
+ .name = options->name,
+ };
+ char *dmCipherSpec;
+ int r, tries = options->tries;
+ int whichkey;
- r = backend->status(0, options, NULL);
+ r = backend->status(1, options, NULL);
if (r < 0)
return r;
if (r > 0) {
@@ -467,6 +534,67 @@
return -EBUSY;
}
+ if (get_device_infos(options->device, &infos) < 0) {
+ set_error("Can't get device information.\n");
+ r = -ENOTBLK; goto out;
+ }
+
+start:
+ options->key_size = 0; // FIXME, define a clean interface some day.
+
+ if(get_key(options,"Enter LUKS passphrase: ",&password,&passwordLen))
+ tries--;
+ else
+ tries = 0;
+
+ if(!password) {
+ r = -EINVAL; goto out;
+ }
+ whichkey=LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend);
+ if(whichkey < 0) {
+ set_error("No key available with this passphrase.\n");
+ r = -EPERM; goto out1;
+ }
+ if (whichkey>0) {
+ set_error("Not allowed to remove device");
+ r = -EPERM;
+ }
+
+ options->offset = hdr.payloadOffset;
+ asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode);
+ if(!dmCipherSpec) {
+ r = -ENOMEM;
+ goto out2;
+ }
+ options->cipher = dmCipherSpec;
+ options->key_size = mk.keyLength;
+ options->skip = 0;
+
+ options->size = infos.size;
+ if (!options->size) {
+ set_error("Not a block device.\n");
+ r = -ENOTBLK; goto out2;
+ }
+ if (options->size <= options->offset) {
+ set_error("Invalid offset");
+ r = -EINVAL; goto out2;
+ }
+ options->size -= options->offset;
+
+out2:
+ free(dmCipherSpec);
+out1:
+ safe_free(password);
+out:
+ memset(&mk,0,sizeof(mk));
+
+ if (r != 0 && tries > 0)
+ goto start;
+
+ if (r != 0) {
+ return r;
+ }
+
return backend->remove(options);
}
@@ -546,6 +674,7 @@
};
char *dmCipherSpec;
int r, tries = options->tries;
+ int whichkey;
r = backend->status(0, &tmp, NULL);
if (r >= 0) {
@@ -571,10 +700,16 @@
if(!password) {
r = -EINVAL; goto out;
}
- if(LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend) < 0) {
+ whichkey=LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend);
+ if(whichkey < 0) {
set_error("No key available with this passphrase.\n");
r = -EPERM; goto out1;
}
+ if (whichkey>0) {
+ infos.readonly = 1;
+ options->flags |= CRYPT_FLAG_READONLY;
+ }
+
options->offset = hdr.payloadOffset;
asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode);
diff -urN cryptsetup-luks-1.0.3-orig/luks/keymanage.c cryptsetup-luks-1.0.3/luks/keymanage.c
--- cryptsetup-luks-1.0.3-orig/luks/keymanage.c 2006-04-02 10:36:11.000000000 +0200
+++ cryptsetup-luks-1.0.3/luks/keymanage.c 2007-04-04 10:53:53.000000000 +0200
@@ -338,7 +338,7 @@
break;
}
if(i!=LUKS_NUMKEYS) printf("key slot %d unlocked.\n",i);
- return i==LUKS_NUMKEYS?-EPERM:0;
+ return i==LUKS_NUMKEYS?-EPERM:i;
}
/*
---------------------------------------------------------------------
dm-crypt mailing list - http://www.saout.de/misc/dm-crypt/
To unsubscribe, e-mail: dm-crypt-unsubscribe@xxxxxxxx
For additional commands, e-mail: dm-crypt-help@xxxxxxxx