Re: addition to luks or feature request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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

[Index of Archives]     [Device Mapper Devel]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]     [Fedora Docs]

  Powered by Linux