From 1cf439a8a055980084a7c6c16f2a060c13fa8028 Mon Sep 17 00:00:00 2001 From: Miloslav Trmac Date: Thu, 23 Jul 2009 23:16:05 +0000 Subject: [PATCH] - Initial build. --- .cvsignore | 2 + cryptsetup-svn-r62.patch | 674 +++++++++++++++++++++++++++++++++++++++ sources | 2 + volume_key.spec | 139 ++++++++ 4 files changed, 817 insertions(+) create mode 100644 cryptsetup-svn-r62.patch create mode 100644 volume_key.spec diff --git a/.cvsignore b/.cvsignore index e69de29..f5ff883 100644 --- a/.cvsignore +++ b/.cvsignore @@ -0,0 +1,2 @@ +volume_key-0.2.tar.bz2 +cryptsetup-1.0.7-rc1.tar.bz2 diff --git a/cryptsetup-svn-r62.patch b/cryptsetup-svn-r62.patch new file mode 100644 index 0000000..21d0574 --- /dev/null +++ b/cryptsetup-svn-r62.patch @@ -0,0 +1,674 @@ +Index: lib/libcryptsetup.h +=================================================================== +--- lib/libcryptsetup.h (revision 62) ++++ lib/libcryptsetup.h (working copy) +@@ -65,6 +65,78 @@ + int crypt_luksFormat(struct crypt_options *options); + int crypt_luksDump(struct crypt_options *options); + ++struct crypt_luks_volume_info; ++ ++/* Get information about DEVICE, ++ Return 0 on sucess, setting INFO to the volume information. ++ return a negative errno value otherwise, the caller can try to use ++ crypt_get_error() to get an error message. ++ INFO can be NULL, in which case the function only verifies DEVICE is a valid ++ LUKS device. ++ If INFO is not not NULL, it should be freed using crypt_luks_vi_free(). ++*/ ++int crypt_luks_get_volume_info(struct crypt_luks_volume_info **info, ++ const char *device); ++ ++/* Get cipher name from INFO. ++ Return a string for free(), or NULL if out of memory. */ ++char *crypt_luks_vi_get_cipher_name(struct crypt_luks_volume_info *info); ++ ++/* Get cipher mode from INFO. ++ Return a string for free(), or NULL if out of memory. */ ++char *crypt_luks_vi_get_cipher_mode(struct crypt_luks_volume_info *info); ++ ++/* Get number of master key bytes from INFO. */ ++unsigned crypt_luks_vi_get_key_bytes(struct crypt_luks_volume_info *info); ++ ++/* Get UUID from INFO. ++ Return a string for free(), or NULL if out of memory. */ ++char *crypt_luks_vi_get_uuid(struct crypt_luks_volume_info *info); ++ ++/* Free INFO. */ ++void crypt_luks_vi_free(struct crypt_luks_volume_info *info); ++ ++/* Get the master key of DEVICE, using PASSPHRASE with PASSPHRASE_LENGTH. ++ Return the used slot on success, setting KEY and KEY_LENGTH to the master ++ key; ++ return a negative errno value otherwise, the caller can try to use ++ crypt_get_error() to get an error message. ++ The caller is responsible for calling free(KEY) if this function returns ++ 0. */ ++int crypt_luks_get_master_key(unsigned char **key, size_t *key_length, ++ const char *device, ++ const unsigned char *passphrase, ++ size_t passphrase_length, ++ void (*log)(int class, char *msg)); ++ ++/* Verify that KEY with KEY_LENGTH is valid for DEVICE. ++ Return 0 on success. ++ Return a negative errno value otherwise, the caller can try to use ++ crypt_get_error() to get an error message. */ ++int crypt_luks_verify_master_key(const char *device, const unsigned char *key, ++ size_t key_length); ++ ++/* Open DEVICE using KEY with KEY_LENGTH as NAME. ++ Return 0 on success. ++ Return a negative errno value otherwise, the caller can try to use ++ crypt_get_error() to get an error message. */ ++int crypt_luks_open_by_master_key(const char *name, const char *device, ++ const unsigned char *key, size_t key_length, ++ int flags, void (*log)(int class, char *msg)); ++ ++/* Add a PASSPHRASE with PASSPHRASE_LENGTH to SLOT of DEVICE, using KEY with ++ KEY_LENGTH. ++ Return the used slot on success; ++ Return a negative errno value otherwise, the caller can try to use ++ crypt_get_error() to get an error message. ++ SLOT may be -1 to use the first empty slot. */ ++int crypt_luks_add_passphrase_by_master_key(const char *device, ++ const unsigned char *key, ++ size_t key_length, int slot, ++ const unsigned char *passphrase, ++ size_t passphrase_length, ++ void (*log)(int class, char *msg)); ++ + void crypt_get_error(char *buf, size_t size); + void crypt_put_options(struct crypt_options *options); + const char *crypt_get_dir(void); +Index: lib/setup.c +=================================================================== +--- lib/setup.c (revision 62) ++++ lib/setup.c (working copy) +@@ -282,7 +282,7 @@ + } + } + +-static int __crypt_create_device(int reload, struct setup_backend *backend, ++static int __crypt_create_device(intptr_t reload, struct setup_backend *backend, + struct crypt_options *options) + { + struct crypt_options tmp = { +@@ -359,7 +359,7 @@ + return r; + } + +-static int __crypt_query_device(int details, struct setup_backend *backend, ++static int __crypt_query_device(intptr_t details, struct setup_backend *backend, + struct crypt_options *options) + { + int r = backend->status(details, options, NULL); +@@ -371,7 +371,7 @@ + return r; + } + +-static int __crypt_resize_device(int details, struct setup_backend *backend, ++static int __crypt_resize_device(intptr_t details, struct setup_backend *backend, + struct crypt_options *options) + { + struct crypt_options tmp = { +@@ -412,7 +412,7 @@ + return r; + } + +-static int __crypt_remove_device(int arg, struct setup_backend *backend, ++static int __crypt_remove_device(intptr_t arg, struct setup_backend *backend, + struct crypt_options *options) + { + int r; +@@ -428,7 +428,7 @@ + return backend->remove(0, options); + } + +-static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options) ++static int __crypt_luks_format(intptr_t arg, struct setup_backend *backend, struct crypt_options *options) + { + int r; + +@@ -504,8 +504,94 @@ + return r; + } + +-static int __crypt_luks_open(int arg, struct setup_backend *backend, struct crypt_options *options) ++static int open_from_hdr_and_mk(struct luks_phdr *hdr, ++ struct luks_masterkey *mk, ++ const struct device_infos *infos, ++ struct setup_backend *backend, ++ struct crypt_options *options) + { ++ char *dmCipherSpec; ++ int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ++ ? 0 : O_EXCL; ++ int r; ++ ++ if (infos->readonly) ++ options->flags |= CRYPT_FLAG_READONLY; ++ options->offset = hdr->payloadOffset; ++ if (asprintf(&dmCipherSpec, "%s-%s", hdr->cipherName, hdr->cipherMode) ++ < 0) { ++ r = -ENOMEM; ++ goto out; ++ } ++ 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 out; ++ } ++ if (options->size <= options->offset) { ++ set_error("Invalid offset"); ++ r = -EINVAL; ++ goto out; ++ } ++ options->size -= options->offset; ++ /* FIXME: code allows multiple crypt mapping, cannot use uuid then. ++ * anyway, it is dangerous and can corrupt data. Remove it in next version! */ ++ r = backend->create(0, options, mk->key, excl ? hdr->uuid : NULL); ++ out: ++ free(dmCipherSpec); ++ return r; ++} ++ ++static int __crypt_luks_open_by_master_key(intptr_t arg, ++ struct setup_backend *backend, ++ struct crypt_options *options) ++{ ++ struct luks_masterkey *mk; ++ struct luks_phdr hdr; ++ struct device_infos infos; ++ struct crypt_options tmp = { ++ .name = options->name, ++ }; ++ int r; ++ int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) != 0 ++ ? 0 : O_EXCL ; ++ ++ mk = (struct luks_masterkey *)arg; ++ ++ r = backend->status(0, &tmp, NULL); ++ if (r >= 0) { ++ set_error("Device %s already exists.", options->name); ++ return -EEXIST; ++ } ++ ++ if (!LUKS_device_ready(options->device, O_RDONLY | excl)) ++ return -ENOTBLK; ++ ++ if (get_device_infos(options->device, &infos) < 0) { ++ set_error("Can't get device information.\n"); ++ return -ENOTBLK; ++ } ++ ++ r = LUKS_read_phdr(options->device, &hdr); ++ if (r < 0) ++ return r; ++ ++ r = LUKS_verify_master_key(&hdr, mk); ++ if (r == -EPERM) ++ set_error("Master key does not match the volume.\n"); ++ if (r < 0) ++ return r; ++ ++ return open_from_hdr_and_mk(&hdr, mk, &infos, backend, options); ++} ++ ++static int __crypt_luks_open(intptr_t arg, struct setup_backend *backend, struct crypt_options *options) ++{ + struct luks_masterkey *mk=NULL; + struct luks_phdr hdr; + char *prompt = NULL; +@@ -515,7 +601,6 @@ + struct crypt_options tmp = { + .name = options->name, + }; +- char *dmCipherSpec = NULL; + int r, tries = options->tries; + int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ? 0 : O_EXCL ; + +@@ -533,9 +618,6 @@ + return -ENOTBLK; + } + +- if (infos.readonly) +- options->flags |= CRYPT_FLAG_READONLY; +- + if(asprintf(&prompt, "Enter LUKS passphrase for %s: ", options->device) < 0) + return -ENOMEM; + +@@ -559,33 +641,8 @@ + + logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r); + ++ r = open_from_hdr_and_mk(&hdr, mk, &infos, backend, options); + +- options->offset = hdr.payloadOffset; +- if (asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode) < 0) { +- 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; +- /* FIXME: code allows multiple crypt mapping, cannot use uuid then. +- * anyway, it is dangerous and can corrupt data. Remove it in next version! */ +- r = backend->create(0, options, mk->key, excl ? hdr.uuid : NULL); +- +- out2: +- free(dmCipherSpec); +- dmCipherSpec = NULL; + out1: + safe_free(password); + out: +@@ -598,8 +655,76 @@ + return r; + } + +-static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct crypt_options *options) ++/* arg is a struct luks_masterkey **. Caller must LUKS_dealloc_masterkey(*arg) ++ if this function returns 0. ++ options->key_size is abused as passphrase length. */ ++static int __crypt_luks_get_master_key(intptr_t arg, ++ struct setup_backend *backend, ++ struct crypt_options *options) + { ++ struct luks_masterkey *mk; ++ struct luks_phdr hdr; ++ int r; ++ ++ if (!LUKS_device_ready(options->device, O_RDONLY)) ++ return -ENOTBLK; ++ ++ r = LUKS_open_any_key(options->device, options->passphrase, ++ options->key_size, &hdr, &mk, backend); ++ if (r == -EPERM) ++ set_error("No key available with this passphrase."); ++ if (r < 0) { ++ LUKS_dealloc_masterkey(mk); ++ return r; ++ } ++ ++ *(struct luks_masterkey **)arg = mk; ++ return r; ++} ++ ++/* options->key_size is abused as passphrase length. */ ++static int __crypt_luks_add_passphrase_by_master_key ++ (intptr_t arg, struct setup_backend *backend, ++ struct crypt_options *options) ++{ ++ struct luks_phdr hdr; ++ unsigned int keyIndex; ++ struct luks_masterkey *mk; ++ const char *device = options->device; ++ int r; ++ ++ mk = (struct luks_masterkey *)arg; ++ ++ if (!LUKS_device_ready(options->device, O_RDWR)) ++ return -ENOTBLK; ++ ++ r = LUKS_read_phdr(device, &hdr); ++ if (r < 0) ++ return r; ++ ++ r = LUKS_verify_master_key(&hdr, mk); ++ if (r < 0) { ++ set_error("Master key does not match the volume"); ++ return -EINVAL; ++ } ++ ++ keyIndex = keyslot_from_option(options->key_slot, &hdr, options); ++ if (keyIndex == -EINVAL) ++ return -EINVAL; ++ ++ hdr.keyblock[keyIndex].passwordIterations ++ = at_least_one(LUKS_benchmarkt_iterations() ++ * ((float)options->iteration_time / 1000)); ++ ++ r = LUKS_set_key(device, keyIndex, options->passphrase, ++ options->key_size, &hdr, mk, backend); ++ if (r < 0) ++ return r; ++ return keyIndex; ++} ++ ++static int __crypt_luks_add_key(intptr_t arg, struct setup_backend *backend, struct crypt_options *options) ++{ + struct luks_masterkey *mk=NULL; + struct luks_phdr hdr; + char *password=NULL; unsigned int passwordLen; +@@ -664,7 +789,7 @@ + return r; + } + +-static int luks_remove_helper(int arg, struct setup_backend *backend, struct crypt_options *options, int supply_it) ++static int luks_remove_helper(intptr_t arg, struct setup_backend *backend, struct crypt_options *options, int supply_it) + { + struct luks_masterkey *mk; + struct luks_phdr hdr; +@@ -735,18 +860,18 @@ + return r; + } + +-static int __crypt_luks_kill_slot(int arg, struct setup_backend *backend, struct crypt_options *options) { ++static int __crypt_luks_kill_slot(intptr_t arg, struct setup_backend *backend, struct crypt_options *options) { + return luks_remove_helper(arg, backend, options, 0); + } + +-static int __crypt_luks_remove_key(int arg, struct setup_backend *backend, struct crypt_options *options) { ++static int __crypt_luks_remove_key(intptr_t arg, struct setup_backend *backend, struct crypt_options *options) { + return luks_remove_helper(arg, backend, options, 1); + } + + +-static int crypt_job(int (*job)(int arg, struct setup_backend *backend, ++static int crypt_job(int (*job)(intptr_t arg, struct setup_backend *backend, + struct crypt_options *options), +- int arg, struct crypt_options *options) ++ intptr_t arg, struct crypt_options *options) + { + struct setup_backend *backend; + int r; +@@ -807,6 +932,96 @@ + return crypt_job(__crypt_luks_format, 0, options); + } + ++int crypt_luks_get_master_key(unsigned char **key, size_t *key_length, ++ const char *device, ++ const unsigned char *passphrase, ++ size_t passphrase_length, ++ void (*log)(int class, char *msg)) ++{ ++ struct crypt_options options; ++ struct interface_callbacks icb; ++ struct luks_masterkey *mk; ++ int r; ++ ++ memset(&icb, 0, sizeof(icb)); ++ icb.log = log; ++ memset(&options, 0, sizeof(options)); ++ options.device = device; ++ options.icb = &icb; ++ options.passphrase = (const char *)passphrase; ++ options.key_size = passphrase_length; /* Abusing the field */ ++ if (options.key_size != passphrase_length) { ++ set_error("passphrase_length too large"); ++ return -EOVERFLOW; ++ } ++ r = crypt_job(__crypt_luks_get_master_key, (intptr_t)&mk, &options); ++ if (r < 0) ++ return r; ++ /* Note: this memory is not mlock()ed */ ++ *key = malloc(mk->keyLength); ++ if (*key == NULL) { ++ LUKS_dealloc_masterkey(mk); ++ return -ENOMEM; ++ } ++ memcpy(*key, mk->key, mk->keyLength); ++ *key_length = mk->keyLength; ++ LUKS_dealloc_masterkey(mk); ++ return r; ++} ++ ++int crypt_luks_verify_master_key(const char *device, const unsigned char *key, ++ size_t key_length) ++{ ++ struct luks_masterkey *mk; ++ struct luks_phdr hdr; ++ int r; ++ ++ r = LUKS_read_phdr(device, &hdr); ++ if (r < 0) ++ return r; ++ ++ mk = LUKS_alloc_masterkey(key_length); ++ if (mk == NULL) ++ return -ENOMEM; ++ memcpy(mk->key, key, key_length); ++ ++ r = LUKS_verify_master_key(&hdr, mk); ++ if (r == -EPERM) ++ set_error("Master key does not match the volume.\n"); ++ ++ LUKS_dealloc_masterkey(mk); ++ ++ return r; ++} ++ ++int crypt_luks_open_by_master_key(const char *name, const char *device, ++ const unsigned char *key, size_t key_length, ++ int flags, void (*log)(int class, char *msg)) ++{ ++ struct crypt_options options; ++ struct interface_callbacks icb; ++ struct luks_masterkey *mk; ++ int r; ++ ++ memset(&icb, 0, sizeof(icb)); ++ icb.log = log; ++ memset(&options, 0, sizeof(options)); ++ options.name = name; ++ options.device = device; ++ options.flags = flags; ++ options.offset = 0; ++ options.icb = &icb; ++ ++ mk = LUKS_alloc_masterkey(key_length); ++ if (mk == NULL) ++ return -ENOMEM; ++ memcpy(mk->key, key, key_length); ++ r = crypt_job(__crypt_luks_open_by_master_key, (intptr_t)mk, &options); ++ LUKS_dealloc_masterkey(mk); ++ ++ return r; ++} ++ + int crypt_luksOpen(struct crypt_options *options) + { + return crypt_job(__crypt_luks_open, 0, options); +@@ -822,6 +1037,39 @@ + return crypt_job(__crypt_luks_remove_key, 0, options); + } + ++int crypt_luks_add_passphrase_by_master_key(const char *device, ++ const unsigned char *key, ++ size_t key_length, int slot, ++ const unsigned char *passphrase, ++ size_t passphrase_length, ++ void (*log)(int class, char *msg)) ++{ ++ struct crypt_options options; ++ struct interface_callbacks icb; ++ struct luks_masterkey *mk; ++ int r; ++ ++ memset(&icb, 0, sizeof(icb)); ++ icb.log = log; ++ memset(&options, 0, sizeof(options)); ++ options.device = device; ++ options.passphrase = (const char *)passphrase; ++ options.key_size = passphrase_length; /* Abusing the field */ ++ options.key_slot = slot; ++ options.iteration_time = 1000; ++ options.icb = &icb; ++ ++ mk = LUKS_alloc_masterkey(key_length); ++ if (mk == NULL) ++ return -ENOMEM; ++ memcpy(mk->key, key, key_length); ++ r = crypt_job(__crypt_luks_add_passphrase_by_master_key, (intptr_t)mk, ++ &options); ++ LUKS_dealloc_masterkey(mk); ++ ++ return r; ++} ++ + int crypt_luksAddKey(struct crypt_options *options) + { + return crypt_job(__crypt_luks_add_key, 0, options); +@@ -840,6 +1088,84 @@ + return 0; + } + ++struct crypt_luks_volume_info ++{ ++ struct luks_phdr h; ++}; ++ ++int crypt_luks_get_volume_info(struct crypt_luks_volume_info **info, ++ const char *device) ++{ ++ struct crypt_luks_volume_info *vi; ++ int r; ++ ++ vi = malloc(sizeof(*vi)); ++ if (vi == NULL) ++ return -ENOMEM; ++ r = LUKS_read_phdr(device, &vi->h); ++ if (r != 0) { ++ free(vi); ++ return r; ++ } ++ if (info != NULL) ++ *info = vi; ++ else ++ free(vi); ++ return 0; ++} ++ ++char *crypt_luks_vi_get_cipher_name(struct crypt_luks_volume_info *info) ++{ ++ size_t field_size; ++ char *r; ++ ++ field_size = sizeof(info->h.cipherName); ++ r = malloc(field_size + 1); ++ if (r != NULL) { ++ memcpy(r, info->h.cipherName, field_size); ++ r[field_size] = '\0'; ++ } ++ return r; ++} ++ ++char *crypt_luks_vi_get_cipher_mode(struct crypt_luks_volume_info *info) ++{ ++ size_t field_size; ++ char *r; ++ ++ field_size = sizeof(info->h.cipherMode); ++ r = malloc(field_size + 1); ++ if (r != NULL) { ++ memcpy(r, info->h.cipherMode, field_size); ++ r[field_size] = '\0'; ++ } ++ return r; ++} ++ ++unsigned crypt_luks_vi_get_key_bytes(struct crypt_luks_volume_info *info) ++{ ++ return info->h.keyBytes; ++} ++ ++char *crypt_luks_vi_get_uuid(struct crypt_luks_volume_info *info) ++{ ++ size_t field_size; ++ char *r; ++ ++ field_size = sizeof(info->h.uuid); ++ r = malloc(field_size + 1); ++ if (r != NULL) { ++ memcpy(r, info->h.uuid, field_size); ++ r[field_size] = '\0'; ++ } ++ return r; ++} ++ ++void crypt_luks_vi_free(struct crypt_luks_volume_info *info) ++{ ++ free(info); ++} ++ + int crypt_isLuks(struct crypt_options *options) + { + struct luks_phdr hdr; +Index: luks/keymanage.c +=================================================================== +--- luks/keymanage.c (revision 62) ++++ luks/keymanage.c (working copy) +@@ -280,6 +280,20 @@ + return r; + } + ++/* Check whether a master key is invalid. */ ++int LUKS_verify_master_key(const struct luks_phdr *hdr, ++ const struct luks_masterkey *mk) ++{ ++ char checkHashBuf[LUKS_DIGESTSIZE]; ++ ++ PBKDF2_HMAC_SHA1(mk->key, mk->keyLength, hdr->mkDigestSalt, ++ LUKS_SALTSIZE, hdr->mkDigestIterations, checkHashBuf, ++ LUKS_DIGESTSIZE); ++ ++ return memcmp(checkHashBuf, hdr->mkDigest, LUKS_DIGESTSIZE) == 0 ++ ? 0 : -EPERM; ++} ++ + /* Try to open a particular key slot, + + */ +@@ -295,7 +309,6 @@ + char derivedKey[hdr->keyBytes]; + char *AfKey; + size_t AFEKSize; +- char checkHashBuf[LUKS_DIGESTSIZE]; + int r; + + if(hdr->keyblock[keyIndex].active != LUKS_KEY_ENABLED) { +@@ -329,13 +342,8 @@ + + r = AF_merge(AfKey,mk->key,mk->keyLength,hdr->keyblock[keyIndex].stripes); + if(r < 0) goto out; +- +- PBKDF2_HMAC_SHA1(mk->key,mk->keyLength, +- hdr->mkDigestSalt,LUKS_SALTSIZE, +- hdr->mkDigestIterations, +- checkHashBuf,LUKS_DIGESTSIZE); + +- r = (memcmp(checkHashBuf,hdr->mkDigest, LUKS_DIGESTSIZE) == 0)?0:-EPERM; ++ r = LUKS_verify_master_key(hdr, mk); + out: + free(AfKey); + return r; +Index: luks/luks.h +=================================================================== +--- luks/luks.h (revision 62) ++++ luks/luks.h (working copy) +@@ -124,6 +124,8 @@ + struct luks_masterkey **mk, + struct setup_backend *backend); + ++int LUKS_verify_master_key(const struct luks_phdr *hdr, ++ const struct luks_masterkey *mk); + + int LUKS_del_key(const char *device, unsigned int keyIndex); + int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex); diff --git a/sources b/sources index e69de29..e19b1d2 100644 --- a/sources +++ b/sources @@ -0,0 +1,2 @@ +882ec96bef41962a33a24d6ee5821a29 volume_key-0.2.tar.bz2 +0910632173fb960252412bf7342b42fc cryptsetup-1.0.7-rc1.tar.bz2 diff --git a/volume_key.spec b/volume_key.spec new file mode 100644 index 0000000..1395115 --- /dev/null +++ b/volume_key.spec @@ -0,0 +1,139 @@ +%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} + +Summary: An utility for manipulating storage encryption keys and passphrases +Name: volume_key +Version: 0.2 +Release: 1 +License: GPLv2 +Group: Applications/System +URL: https://fedorahosted.org/volume_key/ +Requires: volume_key-libs = %{version}-%{release} + +Source0: https://fedorahosted.org/releases/v/o/volume_key/volume_key-%{version}.tar.bz2 +Source1: http://cryptsetup.googlecode.com/files/cryptsetup-1.0.7-rc1.tar.bz2 +# http://code.google.com/p/cryptsetup/issues/detail?id=15 +Patch0: https://fedorahosted.org/releases/v/o/volume_key/cryptsetup-svn-r62.patch +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) +BuildRequires: gettext-devel, glib2-devel, gnupg, gpgme-devel, libblkid-devel +BuildRequires: nss-devel, python-devel + +# For cryptsetup +BuildRequires: device-mapper-devel, e2fsprogs-devel, libgcrypt-devel +BuildRequires: libgpg-error-devel, libselinux-devel, libsepol-devel, popt-devel + +%description +This package provides a command-line tool for manipulating storage volume +encryption keys and storing them separately from volumes. + +The main goal of the software is to allow restoring access to an encrypted +hard drive if the primary user forgets the passphrase. The encryption key +back up can also be useful for extracting data after a hardware or software +failure that corrupts the header of the encrypted volume, or to access the +company data after an employee leaves abruptly. + +%package devel +Summary: A library for manipulating storage encryption keys and passphrases +Group: Development/Libraries +Requires: volume_key-libs = %{version}-%{release} + +%description devel +This package provides libvolume_key, a library for manipulating storage volume +encryption keys and storing them separately from volumes. + +The main goal of the software is to allow restoring access to an encrypted +hard drive if the primary user forgets the passphrase. The encryption key +back up can also be useful for extracting data after a hardware or software +failure that corrupts the header of the encrypted volume, or to access the +company data after an employee leaves abruptly. + +%package libs +Summary: A library for manipulating storage encryption keys and passphrases +Group: System Environment/Libraries + +%description libs +This package provides libvolume_key, a library for manipulating storage volume +encryption keys and storing them separately from volumes. + +The main goal of the software is to allow restoring access to an encrypted +hard drive if the primary user forgets the passphrase. The encryption key +back up can also be useful for extracting data after a hardware or software +failure that corrupts the header of the encrypted volume, or to access the +company data after an employee leaves abruptly. + +%package -n python-volume_key +Summary: Python bindings for libvolume_key +Group: System Environment/Libraries +Requires: volume_key-libs = %{version}-%{release} + +%description -n python-volume_key +This package provides Python bindings for libvolume_key, a library for +manipulating storage volume encryption keys and storing them separately from +volumes. + +The main goal of the software is to allow restoring access to an encrypted +hard drive if the primary user forgets the passphrase. The encryption key +back up can also be useful for extracting data after a hardware or software +failure that corrupts the header of the encrypted volume, or to access the +company data after an employee leaves abruptly. + +volume_key currently supports only the LUKS volume encryption format. Support +for other formats is possible, some formats are planned for future releases. + +%prep +%setup -q -a 1 +pushd cryptsetup-1.0.7-rc1 +%patch0 -p0 -b .cs-vk +popd + +%build +cryptsetup_root=$(pwd)/cryptsetup-root + +pushd cryptsetup-1.0.7-rc1 +%configure --enable-static --disable-shared --with-pic +make %{?_smp_mflags} +make install "DESTDIR=$cryptsetup_root" INSTALL='install -p' +popd + +%configure "CPPFLAGS=-I$cryptsetup_root"%{_includedir} \ + "LDFLAGS=-L$cryptsetup_root"%{_libdir} --disable-static +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT + +make install DESTDIR=$RPM_BUILD_ROOT + +%find_lang volume_key + +%clean +rm -rf $RPM_BUILD_ROOT + +%post libs -p /sbin/ldconfig +%postun libs -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%doc README +%{_bindir}/volume_key +%{_mandir}/man8/volume_key.8* + +%files devel +%defattr(-,root,root,-) +%{_includedir}/volume_key +%exclude %{_libdir}/libvolume_key.la +%{_libdir}/libvolume_key.so + +%files libs -f volume_key.lang +%defattr(-,root,root,-) +%doc AUTHORS COPYING ChangeLog NEWS +%{_libdir}/libvolume_key.so.* + +%files -n python-volume_key +%defattr(-,root,root,-) +%exclude %{python_sitearch}/_volume_key.la +%{python_sitearch}/_volume_key.so +%{python_sitearch}/volume_key.py* + +%changelog +* Tue Jun 30 2009 Miloslav Trmač - 0.2-1 +- Initial build.