From: Milan Broz Date: Sun, 30 Aug 2009 17:56:33 +0000 (+0000) Subject: Require device device-mapper to build and do not use backend wrapper for dm calls. X-Git-Tag: upstream/1.6~737 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ab953b3ff6b9add2db5ac25a05c55c3ecbb748fc;p=platform%2Fupstream%2Fcryptsetup.git Require device device-mapper to build and do not use backend wrapper for dm calls. Signed-off-by: Milan Broz git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@90 36d66b0a-2a48-0410-832c-cd162a569da5 --- diff --git a/ChangeLog b/ChangeLog index 2b1be40..b49ceb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,7 @@ +2009-08-30 Milan Broz + * Require device device-mapper to build and do not use backend wrapper for dm calls. + 2009-08-17 Milan Broz * Fix PBKDF2 speed calculation for large passhrases. * Allow using passphrase provided in options struct for LuksOpen. diff --git a/configure.in b/configure.in index 4a2815e..3a5be93 100644 --- a/configure.in +++ b/configure.in @@ -26,10 +26,12 @@ AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \ ctype.h unistd.h locale.h) -AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR('You need the uuid library (from e2fsprogs)')]) +AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR('You need the uuid library')]) +AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR('You need the device-mapper library')]) saved_LIBS="$LIBS" -AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR('You need the uuid library (from e2fsprogs)')]) +AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR('You need the uuid library')]) +AC_CHECK_LIB(devmapper, dm_task_set_name,,[AC_MSG_ERROR('You need the device-mapper library')]) UUID_LIBS="$LIBS" LIBS="$saved_LIBS" AC_SUBST(UUID_LIBS) @@ -91,30 +93,24 @@ AM_CONDITIONAL(SHARED_LIBGCRYPT, test x$build_shared = xyes) AC_ARG_ENABLE(selinux, [ --disable-selinux disable selinux support [[default=auto]]],[], []) -MODULE_HELPER(libdevmapper, -[ --enable-libdevmapper enable dm-crypt backend through libdevmapper - [[default=auto]]],auto,[ - have_module=yes - saved_LIBS="$LIBS" - if test "x$enable_selinux" != xno; then - AC_CHECK_LIB(sepol, sepol_bool_set) - AC_CHECK_LIB(selinux, is_selinux_enabled) - # Check if we need -pthread with --enable-static and selinux - if test x$build_static = xyes; then - saved_LIBS2="$LIBS" - LIBS="$LIBS -static" - AC_SEARCH_LIBS([pthread_mutex_lock], [pthread], - [test "$ac_cv_search_pthread_mutex_lock" = "none required" || LIB_PTHREAD=-lpthread]) - LIBS="$saved_LIBS2" - fi +saved_LIBS="$LIBS" +if test "x$enable_selinux" != xno; then + AC_CHECK_LIB(sepol, sepol_bool_set) + AC_CHECK_LIB(selinux, is_selinux_enabled) + # Check if we need -pthread with --enable-static and selinux + if test x$build_static = xyes; then + saved_LIBS2="$LIBS" + LIBS="$LIBS -static" + AC_SEARCH_LIBS([pthread_mutex_lock], [pthread], + [test "$ac_cv_search_pthread_mutex_lock" = "none required" || LIB_PTHREAD=-lpthread]) + LIBS="$saved_LIBS2" fi - AC_CHECK_LIB(devmapper, dm_task_set_name,,unset have_module) - AC_CHECK_HEADER(libdevmapper.h,,unset have_module) - LIBDEVMAPPER_LIBS="$LIBS $LIB_PTHREAD" - LIBS="$saved_LIBS" - AC_SUBST(LIBDEVMAPPER_LIBS) - AC_SUBST(LIBDEVMAPPER_CFLAGS) -]) +fi +LIBDEVMAPPER_LIBS="$LIBS $LIB_PTHREAD" +LIBS="$saved_LIBS" +AC_SUBST(LIBDEVMAPPER_LIBS) +AC_SUBST(LIBDEVMAPPER_CFLAGS) + AM_CONDITIONAL(BUILD_LIBDEVMAPPER, test x$build_static = xyes) AM_CONDITIONAL(SHARED_LIBDEVMAPPER, test x$build_shared = xyes) diff --git a/lib/backends.c b/lib/backends.c index 3b4829a..e05dfc9 100644 --- a/lib/backends.c +++ b/lib/backends.c @@ -7,7 +7,6 @@ #include "internal.h" extern struct hash_backend hash_gcrypt_backend; -extern struct setup_backend setup_libdevmapper_backend; #ifdef USE_PLUGINS static void init_plugins(void) @@ -24,13 +23,6 @@ static struct hash_backend *hash_backends[] = { NULL }; -static struct setup_backend *setup_backends[] = { -#ifdef BUILTIN_LIBDEVMAPPER - &setup_libdevmapper_backend, -#endif - NULL -}; - struct hash_backend *get_hash_backend(const char *name) { struct hash_backend **backend; @@ -114,22 +106,3 @@ out: return r; } - -struct setup_backend *get_setup_backend(const char *name) -{ - struct setup_backend **backend; - - init_plugins(); - - for(backend = setup_backends; *backend; backend++) - if (!name || strcmp(name, (*backend)->name) == 0) - break; - - return *backend; -} - -void put_setup_backend(struct setup_backend *backend) -{ -#ifdef USE_PLUGINS -#endif -} diff --git a/lib/internal.h b/lib/internal.h index 38a03a8..8e62c20 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -33,18 +33,7 @@ struct hash_backend { void (*free_hashes)(struct hash_type *hashes); }; -struct setup_backend { - const char *name; - int (*init)(void); - void (*exit)(void); - int (*create)(int reload, struct crypt_options *options, - const char *key, const char *uuid); - int (*status)(int details, struct crypt_options *options, - char **key); - int (*remove)(int force, struct crypt_options *options); - - const char * (*dir)(void); -}; +struct crypt_device; void set_error_va(const char *fmt, va_list va); void set_error(const char *fmt, ...); @@ -60,11 +49,28 @@ int hash(const char *backend_name, const char *hash_name, char *result, size_t size, const char *passphrase, size_t sizep); -struct setup_backend *get_setup_backend(const char *name); -void put_setup_backend(struct setup_backend *backend); - void hexprint(char *d, int n); +/* Device mapper backend */ +const char *dm_get_dir(void); +int dm_init(struct crypt_device *context, int check_kernel); +void dm_exit(void); +int dm_remove_device(const char *name, int force, uint64_t size); +int dm_status_device(const char *name); +int dm_query_device(const char *name, + char **device, + uint64_t *size, + uint64_t *skip, + uint64_t *offset, + char **cipher, + int *key_size, + char **key, + int *read_only); +int dm_create_device(const char *name, const char *device, const char *cipher, const char *uuid, + uint64_t size, uint64_t skip, uint64_t offset, + size_t key_size, const char *key, + int read_only, int reload); + int sector_size_for_device(const char *device); ssize_t write_blockwise(int fd, const void *buf, size_t count); ssize_t read_blockwise(int fd, void *_buf, size_t count); diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index d272e4a..9db687e 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -1,20 +1,10 @@ -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include #include #include #include -#include "libcryptsetup.h" #include "internal.h" #include "luks.h" @@ -25,8 +15,11 @@ #define DM_CRYPT_TARGET "crypt" #define RETRY_COUNT 5 +static int _dm_use_count = 0; +static struct crypt_device *_context = NULL; + static void set_dm_error(int level, const char *file, int line, - const char *f, ...) + const char *f, ...) { va_list va; @@ -40,21 +33,29 @@ static void set_dm_error(int level, const char *file, int line, static int _dm_simple(int task, const char *name); -static int dm_init(void) +int dm_init(struct crypt_device *context, int check_kernel) { - dm_log_init(set_dm_error); - if (!_dm_simple(DM_DEVICE_LIST_VERSIONS, "test")) { - set_error("Cannot communicate with device-mapper. Is the dm_mod module loaded?"); - return -1; + if (!_dm_use_count++) { + if (check_kernel && !_dm_simple(DM_DEVICE_LIST_VERSIONS, NULL)) + return -1; + dm_log_init(set_dm_error); + dm_log_init_verbose(10); } + if (context) + _context = context; + return 1; /* unsafe memory */ } -static void dm_exit(void) +void dm_exit(void) { - dm_log_init(NULL); - dm_lib_release(); + if (_dm_use_count && (!--_dm_use_count)) { + dm_log_init_verbose(0); + dm_log_init(NULL); + dm_lib_release(); + _context = NULL; + } } static char *__lookup_dev(char *path, dev_t dev) @@ -134,35 +135,29 @@ static int _dev_read_ahead(const char *dev, uint32_t *read_ahead) return r; } -static char *get_params(struct crypt_options *options, const char *key) +static char *get_params(const char *device, uint64_t skip, uint64_t offset, + const char *cipher, size_t key_size, const char *key) { char *params; char *hexkey; int i; - hexkey = safe_alloc(options->key_size * 2 + 1); - if (!hexkey) { - set_error("Memory allocation problem"); + hexkey = safe_alloc(key_size * 2 + 1); + if (!hexkey) return NULL; - } - for(i = 0; i < options->key_size; i++) + for(i = 0; i < key_size; i++) sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]); - params = safe_alloc(strlen(hexkey) + strlen(options->cipher) + - strlen(options->device) + 64); - if (!params) { - set_error("Memory allocation problem"); + params = safe_alloc(strlen(hexkey) + strlen(cipher) + strlen(device) + 64); + if (!params) goto out; - } sprintf(params, "%s %s %" PRIu64 " %s %" PRIu64, - options->cipher, hexkey, options->skip, - options->device, options->offset); + cipher, hexkey, skip, device, offset); out: safe_free(hexkey); - return params; } @@ -175,7 +170,7 @@ static int _dm_simple(int task, const char *name) if (!(dmt = dm_task_create(task))) return 0; - if (!dm_task_set_name(dmt, name)) + if (name && !dm_task_set_name(dmt, name)) goto out; r = dm_task_run(dmt); @@ -185,7 +180,7 @@ static int _dm_simple(int task, const char *name) return r; } -static int _error_device(struct crypt_options *options) +static int _error_device(const char *name, size_t size) { struct dm_task *dmt; int r = 0; @@ -193,10 +188,10 @@ static int _error_device(struct crypt_options *options) if (!(dmt = dm_task_create(DM_DEVICE_RELOAD))) return 0; - if (!dm_task_set_name(dmt, options->name)) + if (!dm_task_set_name(dmt, name)) goto error; - if (!dm_task_add_target(dmt, UINT64_C(0), options->size, "error", "")) + if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", "")) goto error; if (!dm_task_set_ro(dmt)) @@ -208,8 +203,8 @@ static int _error_device(struct crypt_options *options) if (!dm_task_run(dmt)) goto error; - if (!_dm_simple(DM_DEVICE_RESUME, options->name)) { - _dm_simple(DM_DEVICE_CLEAR, options->name); + if (!_dm_simple(DM_DEVICE_RESUME, name)) { + _dm_simple(DM_DEVICE_CLEAR, name); goto error; } @@ -220,11 +215,14 @@ error: return r; } -static int _dm_remove(struct crypt_options *options, int force) +int dm_remove_device(const char *name, int force, uint64_t size) { int r = -EINVAL; int retries = force ? RETRY_COUNT : 1; + if (!name || (force && !size)) + return -EINVAL; + /* If force flag is set, replace device with error, read-only target. * it should stop processes from reading it and also removed underlying * device from mapping, so it is usable again. @@ -234,14 +232,15 @@ static int _dm_remove(struct crypt_options *options, int force) * it is bug - no other process should try touch it (e.g. udev). */ if (force) { - _error_device(options); + _error_device(name, size); retries = RETRY_COUNT; } do { - r = _dm_simple(DM_DEVICE_REMOVE, options->name) ? 0 : -EINVAL; - if (--retries && r) + r = _dm_simple(DM_DEVICE_REMOVE, name) ? 0 : -EINVAL; + if (--retries && r) { sleep(1); + } } while (r == -EINVAL && retries); dm_task_update_nodes(); @@ -249,8 +248,17 @@ static int _dm_remove(struct crypt_options *options, int force) return r; } -static int dm_create_device(int reload, struct crypt_options *options, - const char *key, const char *uuid) +int dm_create_device(const char *name, + const char *device, + const char *cipher, + const char *uuid, + uint64_t size, + uint64_t skip, + uint64_t offset, + size_t key_size, + const char *key, + int read_only, + int reload) { struct dm_task *dmt = NULL; struct dm_task *dmt_query = NULL; @@ -261,7 +269,7 @@ static int dm_create_device(int reload, struct crypt_options *options, int r = -EINVAL; uint32_t read_ahead = 0; - params = get_params(options, key); + params = get_params(device, skip, offset, cipher, key_size, key); if (!params) goto out_no_removal; @@ -273,31 +281,31 @@ static int dm_create_device(int reload, struct crypt_options *options, if (!(dmt = dm_task_create(reload ? DM_DEVICE_RELOAD : DM_DEVICE_CREATE))) - goto out; - if (!dm_task_set_name(dmt, options->name)) - goto out; - if (options->flags & CRYPT_FLAG_READONLY && !dm_task_set_ro(dmt)) - goto out; - if (!dm_task_add_target(dmt, 0, options->size, DM_CRYPT_TARGET, params)) - goto out; + goto out_no_removal; + if (!dm_task_set_name(dmt, name)) + goto out_no_removal; + if (read_only && !dm_task_set_ro(dmt)) + goto out_no_removal; + if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params)) + goto out_no_removal; #ifdef DM_READ_AHEAD_MINIMUM_FLAG - if (_dev_read_ahead(options->device, &read_ahead) && + if (_dev_read_ahead(device, &read_ahead) && !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG)) - goto out; + goto out_no_removal; #endif if (uuid && !dm_task_set_uuid(dmt, dev_uuid)) - goto out; + goto out_no_removal; if (!dm_task_run(dmt)) - goto out; + goto out_no_removal; if (reload) { dm_task_destroy(dmt); if (!(dmt = dm_task_create(DM_DEVICE_RESUME))) goto out; - if (!dm_task_set_name(dmt, options->name)) + if (!dm_task_set_name(dmt, name)) goto out; if (uuid && !dm_task_set_uuid(dmt, dev_uuid)) goto out; @@ -307,8 +315,6 @@ static int dm_create_device(int reload, struct crypt_options *options, if (!dm_task_get_info(dmt, &dmi)) goto out; - if (dmi.read_only) - options->flags |= CRYPT_FLAG_READONLY; r = 0; out: @@ -316,7 +322,7 @@ out: if (get_error()) error = strdup(get_error()); - _dm_remove(options, 0); + dm_remove_device(name, 0, 0); if (error) { set_error(error); @@ -335,8 +341,7 @@ out_no_removal: return r; } -static int dm_query_device(int details, struct crypt_options *options, - char **key) +int dm_status_device(const char *name) { struct dm_task *dmt; struct dm_info dmi; @@ -345,10 +350,63 @@ static int dm_query_device(int details, struct crypt_options *options, void *next = NULL; int r = -EINVAL; - if (!(dmt = dm_task_create(details ? DM_DEVICE_TABLE - : DM_DEVICE_STATUS))) + if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) + return -EINVAL; + + if (!dm_task_set_name(dmt, name)) { + r = -EINVAL; + goto out; + } + + if (!dm_task_run(dmt)) { + r = -ENODEV; + goto out; + } + + if (!dm_task_get_info(dmt, &dmi)) { + r = -EINVAL; + goto out; + } + + if (!dmi.exists) { + r = -ENODEV; + goto out; + } + + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, ¶ms); + if (!target_type || strcmp(target_type, DM_CRYPT_TARGET) != 0 || + start != 0 || next) + r = -EINVAL; + else + r = (dmi.open_count > 0); +out: + if (dmt) + dm_task_destroy(dmt); + + return r; +} + +int dm_query_device(const char *name, + char **device, + uint64_t *size, + uint64_t *skip, + uint64_t *offset, + char **cipher, + int *key_size, + char **key, + int *read_only) +{ + struct dm_task *dmt; + struct dm_info dmi; + uint64_t start, length, val64; + char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3]; + void *next = NULL; + int i, r = -EINVAL; + + if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) goto out; - if (!dm_task_set_name(dmt, options->name)) + if (!dm_task_set_name(dmt, name)) goto out; r = -ENODEV; if (!dm_task_run(dmt)) @@ -369,116 +427,77 @@ static int dm_query_device(int details, struct crypt_options *options, start != 0 || next) goto out; - options->hash = NULL; - options->cipher = NULL; - options->offset = 0; - options->skip = 0; - options->size = length; - if (details) { - char *cipher, *key_, *device; - uint64_t val64; + if (size) + *size = length; - set_error("Invalid dm table"); + rcipher = strsep(¶ms, " "); + /* cipher */ + if (cipher) + *cipher = strdup(rcipher); - cipher = strsep(¶ms, " "); - key_ = strsep(¶ms, " "); - if (!params) - goto out; + /* skip */ + key_ = strsep(¶ms, " "); + if (!params) + goto out; + val64 = strtoull(params, ¶ms, 10); + if (*params != ' ') + goto out; + params++; + if (skip) + *skip = val64; - val64 = strtoull(params, ¶ms, 10); - if (*params != ' ') - goto out; - params++; - options->skip = val64; + /* device */ + rdevice = strsep(¶ms, " "); + if (device) + *device = lookup_dev(rdevice); - device = strsep(¶ms, " "); - if (!params) + /*offset */ + if (!params) + goto out; + val64 = strtoull(params, ¶ms, 10); + if (*params) + goto out; + if (offset) + *offset = val64; + + /* key_size */ + if (key_size) + *key_size = strlen(key_) / 2; + + /* key */ + if (key_size && key) { + *key = safe_alloc(*key_size); + if (!*key) { + r = -ENOMEM; goto out; + } - val64 = strtoull(params, ¶ms, 10); - if (*params) - goto out; - options->offset = val64; - - options->cipher = strdup(cipher); - options->key_size = strlen(key_) / 2; - if (key) { - char buffer[3]; - char *endp; - int i; - - *key = safe_alloc(options->key_size); - if (!*key) { - set_error("Out of memory"); - r = -ENOMEM; + buffer[2] = '\0'; + for(i = 0; i < *key_size; i++) { + memcpy(buffer, &key_[i * 2], 2); + (*key)[i] = strtoul(buffer, &endp, 16); + if (endp != &buffer[2]) { + safe_free(key); + *key = NULL; goto out; } - - buffer[2] = '\0'; - for(i = 0; i < options->key_size; i++) { - memcpy(buffer, &key_[i * 2], 2); - (*key)[i] = strtoul(buffer, &endp, 16); - if (endp != &buffer[2]) { - safe_free(key); - *key = NULL; - goto out; - } - } } - memset(key_, 0, strlen(key_)); - options->device = lookup_dev(device); - - set_error(NULL); } + memset(key_, 0, strlen(key_)); - r = (dmi.open_count > 0); + /* read_only */ + if (read_only) + *read_only = dmi.read_only; + r = (dmi.open_count > 0); out: if (dmt) dm_task_destroy(dmt); - if (r >= 0) { - if (options->device) - options->flags |= CRYPT_FLAG_FREE_DEVICE; - if (options->cipher) - options->flags |= CRYPT_FLAG_FREE_CIPHER; - options->flags &= ~CRYPT_FLAG_READONLY; - if (dmi.read_only) - options->flags |= CRYPT_FLAG_READONLY; - } else { - if (options->device) { - free((char *)options->device); - options->device = NULL; - options->flags &= ~CRYPT_FLAG_FREE_DEVICE; - } - if (options->cipher) { - free((char *)options->cipher); - options->cipher = NULL; - options->flags &= ~CRYPT_FLAG_FREE_CIPHER; - } - } - return r; -} - -static int dm_remove_device(int force, struct crypt_options *options) -{ - if (!options || !options->name) - return -EINVAL; - return _dm_remove(options, force);; + return r; } - -static const char *dm_get_dir(void) +const char *dm_get_dir(void) { return dm_dir(); } - -struct setup_backend setup_libdevmapper_backend = { - .name = "dm-crypt", - .init = dm_init, - .exit = dm_exit, - .create = dm_create_device, - .status = dm_query_device, - .remove = dm_remove_device, - .dir = dm_get_dir -}; diff --git a/lib/setup.c b/lib/setup.c index 03d58ed..2cc0775 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -22,7 +22,6 @@ struct device_infos { }; static int memory_unsafe = 0; -static char *default_backend = NULL; #define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; }) @@ -46,7 +45,7 @@ static void hexprintICB(struct crypt_options *options, int class, char *d, int n logger(options, class, "%02hhx ", (char)d[i]); } -static int setup_enter(struct setup_backend *backend, void (*log)(int, char *)) +static int setup_enter(void (*log)(int, char *)) { int r; @@ -63,22 +62,11 @@ static int setup_enter(struct setup_backend *backend, void (*log)(int, char *)) set_error(NULL); - if (backend) { - r = backend->init(); - if (r < 0) - return r; - if (r > 0) - memory_unsafe = 1; - } - return 0; } -static int setup_leave(struct setup_backend *backend) +static int setup_leave(void) { - if (backend) - backend->exit(); - /* dangerous, we can't wipe all the memory */ if (!memory_unsafe) munlockall(); @@ -291,19 +279,15 @@ static int keyslot_from_option(int keySlotOption, struct luks_phdr *hdr, struct } } -static int __crypt_create_device(int reload, struct setup_backend *backend, - struct crypt_options *options) +static int __crypt_create_device(int reload, struct crypt_options *options) { - struct crypt_options tmp = { - .name = options->name, - }; struct device_infos infos; char *key = NULL; unsigned int keyLen; char *processed_key = NULL; int r; - r = backend->status(0, &tmp, NULL); + r = dm_status_device(options->name); if (reload) { if (r < 0) return r; @@ -361,40 +345,53 @@ static int __crypt_create_device(int reload, struct setup_backend *backend, return -ENOENT; } - r = backend->create(reload, options, processed_key, NULL); + r = dm_create_device(options->name, options->device, options->cipher, + NULL, options->size, options->skip, options->offset, + options->key_size, processed_key, + options->flags & CRYPT_FLAG_READONLY, reload); safe_free(processed_key); return r; } -static int __crypt_query_device(int details, struct setup_backend *backend, - struct crypt_options *options) +static int __crypt_query_device(int details, struct crypt_options *options) { - int r = backend->status(details, options, NULL); + int read_only, r; + + r = dm_status_device(options->name); if (r == -ENODEV) return 0; - else if (r >= 0) - return 1; - else + + r = dm_query_device(options->name, (char **)&options->device, &options->size, + &options->skip, &options->offset, (char **)&options->cipher, + &options->key_size, NULL, &read_only); + + if (r < 0) return r; + + if (read_only) + options->flags |= CRYPT_FLAG_READONLY; + + options->flags |= CRYPT_FLAG_FREE_DEVICE; + options->flags |= CRYPT_FLAG_FREE_CIPHER; + + return 1; } -static int __crypt_resize_device(int details, struct setup_backend *backend, - struct crypt_options *options) +static int __crypt_resize_device(int details, struct crypt_options *options) { - struct crypt_options tmp = { - .name = options->name, - }; + char *device, *cipher, *key = NULL; + uint64_t size, skip, offset; + int key_size, read_only, r; struct device_infos infos; - char *key = NULL; - int r; - r = backend->status(1, &tmp, &key); + r = dm_query_device(options->name, &device, &size, &skip, &offset, + &cipher, &key_size, &key, &read_only); if (r < 0) return r; - if (get_device_infos(tmp.device, &infos) < 0) + if (get_device_infos(device, &infos) < 0) return -EINVAL; if (!options->size) { @@ -403,30 +400,32 @@ static int __crypt_resize_device(int details, struct setup_backend *backend, set_error("Not a block device"); return -ENOTBLK; } - if (options->size <= tmp.offset) { + if (options->size <= offset) { set_error("Invalid offset"); return -EINVAL; } - options->size -= tmp.offset; + options->size -= offset; } - tmp.size = options->size; + size = options->size; if (infos.readonly) options->flags |= CRYPT_FLAG_READONLY; - r = backend->create(1, &tmp, key, NULL); + r = dm_create_device(options->name, device, cipher, NULL, size, skip, offset, + key_size, key, read_only, 1); safe_free(key); + free(cipher); + free(device); return r; } -static int __crypt_remove_device(int arg, struct setup_backend *backend, - struct crypt_options *options) +static int __crypt_remove_device(int arg, struct crypt_options *options) { int r; - r = backend->status(0, options, NULL); + r = dm_status_device(options->name); if (r < 0) return r; if (r > 0) { @@ -434,10 +433,10 @@ static int __crypt_remove_device(int arg, struct setup_backend *backend, return -EBUSY; } - return backend->remove(0, options); + return dm_remove_device(options->name, 0, 0); } -static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options) +static int __crypt_luks_format(int arg, struct crypt_options *options) { int r; @@ -507,7 +506,7 @@ static int __crypt_luks_format(int arg, struct setup_backend *backend, struct cr if(r < 0) goto out; /* Set key, also writes phdr */ - r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, backend); + r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk); if(r < 0) goto out; r = 0; @@ -517,7 +516,7 @@ out: return r; } -static int __crypt_luks_open(int arg, struct setup_backend *backend, struct crypt_options *options) +static int __crypt_luks_open(int arg, struct crypt_options *options) { struct luks_masterkey *mk=NULL; struct luks_phdr hdr; @@ -525,14 +524,11 @@ static int __crypt_luks_open(int arg, struct setup_backend *backend, struct cryp char *password; unsigned int passwordLen; struct device_infos infos; - 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 ; - r = backend->status(0, &tmp, NULL); + r = dm_status_device(options->name); if (r >= 0) { set_error("Device %s already exists.", options->name); return -EEXIST; @@ -569,7 +565,7 @@ start: r = -EINVAL; goto out; } - r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend); + r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk); if (r == -EPERM) set_error("No key available with this passphrase.\n"); if (r < 0) @@ -599,7 +595,10 @@ start: 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); + r = dm_create_device(options->name, options->device, options->cipher, + excl ? hdr.uuid : NULL, options->size, + 0, options->offset, mk->keyLength, mk->key, + options->flags & CRYPT_FLAG_READONLY, 0); out2: free(dmCipherSpec); @@ -616,7 +615,7 @@ start: return r; } -static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct crypt_options *options) +static int __crypt_luks_add_key(int arg, struct crypt_options *options) { struct luks_masterkey *mk=NULL; struct luks_phdr hdr; @@ -650,7 +649,7 @@ static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct c if(!password) { r = -EINVAL; goto out; } - r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend); + r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk); if(r < 0) { options->icb->log(CRYPT_LOG_ERROR,"No key available with this passphrase.\n"); r = -EPERM; goto out; @@ -675,7 +674,7 @@ static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct c if (r < 0) goto out; hdr.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000)); - r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, backend); + r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk); if(r < 0) goto out; r = 0; @@ -685,7 +684,7 @@ out: 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(int arg, struct crypt_options *options, int supply_it) { struct luks_masterkey *mk; struct luks_phdr hdr; @@ -706,7 +705,7 @@ static int luks_remove_helper(int arg, struct setup_backend *backend, struct cry r = -EINVAL; goto out; } - keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend); + keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk); if(keyIndex < 0) { options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n"); r = -EPERM; goto out; @@ -743,7 +742,7 @@ static int luks_remove_helper(int arg, struct setup_backend *backend, struct cry if(!last_slot) hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED; - openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, backend); + openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk); /* Clean up */ if (openedIndex >= 0) { LUKS_dealloc_masterkey(mk); @@ -764,40 +763,28 @@ out: return r; } -static int __crypt_luks_kill_slot(int arg, struct setup_backend *backend, struct crypt_options *options) { - return luks_remove_helper(arg, backend, options, 0); +static int __crypt_luks_kill_slot(int arg, struct crypt_options *options) { + return luks_remove_helper(arg, options, 0); } -static int __crypt_luks_remove_key(int arg, struct setup_backend *backend, struct crypt_options *options) { - return luks_remove_helper(arg, backend, options, 1); +static int __crypt_luks_remove_key(int arg, struct crypt_options *options) { + return luks_remove_helper(arg, options, 1); } -static int crypt_job(int (*job)(int arg, struct setup_backend *backend, - struct crypt_options *options), +static int crypt_job(int (*job)(int arg, struct crypt_options *options), int arg, struct crypt_options *options) { - struct setup_backend *backend; int r; - backend = get_setup_backend(default_backend); - - if (setup_enter(backend,options->icb->log) < 0) { - r = -ENOSYS; - goto out; - } - - if (!backend) { - set_error("No setup backend available"); + if (setup_enter(options->icb->log) < 0) { r = -ENOSYS; goto out; } - r = job(arg, backend, options); + r = job(arg, options); out: - setup_leave(backend); - if (backend) - put_setup_backend(backend); + setup_leave(); if (r >= 0) set_error(NULL); @@ -948,33 +935,7 @@ void crypt_put_options(struct crypt_options *options) } } -void crypt_set_default_backend(const char *backend) -{ - if (default_backend) - free(default_backend); - if (backend) - default_backend = strdup(backend); - else - default_backend = NULL; -} - const char *crypt_get_dir(void) { - struct setup_backend *backend; - const char *dir; - - backend = get_setup_backend(default_backend); - if (!backend) - return NULL; - - dir = backend->dir(); - - put_setup_backend(backend); - - return dir; + return dm_get_dir(); } - -// Local Variables: -// c-basic-offset: 8 -// indent-tabs-mode: nil -// End: diff --git a/luks/keyencryption.c b/luks/keyencryption.c index e989a6d..7bd8913 100644 --- a/luks/keyencryption.c +++ b/luks/keyencryption.c @@ -33,9 +33,9 @@ #include #include "luks.h" -#include "../lib/libcryptsetup.h" +//#include "../lib/libcryptsetup.h" #include "../lib/internal.h" -#include "../lib/blockdev.h" +//#include "../lib/blockdev.h" #define div_round_up(a,b) ({ \ typeof(a) __a = (a); \ @@ -47,22 +47,18 @@ static inline int round_up_modulo(int x, int m) { return div_round_up(x, m) * m; } -static struct setup_backend *cleaner_backend=NULL; static const char *cleaner_name=NULL; static uint64_t cleaner_size = 0; static int devfd=-1; -static int setup_mapping(const char *cipher, const char *name, +static int setup_mapping(const char *cipher, const char *name, const char *device, unsigned int payloadOffset, - const char *key, size_t keyLength, - unsigned int sector, size_t srcLength, - struct setup_backend *backend, + const char *key, size_t keyLength, + unsigned int sector, size_t srcLength, int mode) { - struct crypt_options k = {0}; - struct crypt_options *options = &k; int device_sector_size = sector_size_for_device(device); - int r; + uint64_t size; /* * we need to round this to nearest multiple of the underlying @@ -72,45 +68,24 @@ static int setup_mapping(const char *cipher, const char *name, set_error(_("Unable to obtain sector size for %s"),device); return -EINVAL; } - options->size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE; - cleaner_size = options->size; - - options->offset = sector; - options->cipher = cipher; - options->key_size = keyLength; - options->skip = 0; - options->flags = 0; - options->name = name; - options->device = device; - - if (mode == O_RDONLY) { - options->flags |= CRYPT_FLAG_READONLY; - } - set_error(NULL); + size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE; + cleaner_size = size; - r = backend->create(0, options, key, NULL); - - return r; -} - -static int clear_mapping(const char *name, uint64_t size, struct setup_backend *backend) -{ - struct crypt_options options = {0}; - options.name=name; - options.size = size; - return backend->remove(1, &options); + return dm_create_device(name, device, cipher, NULL, size, 0, sector, + keyLength, key, (mode == O_RDONLY), 0); } static void sigint_handler(int sig) { - if(devfd >= 0) - close(devfd); - devfd = -1; - if(cleaner_backend && cleaner_name) - clear_mapping(cleaner_name, cleaner_size, cleaner_backend); - signal(SIGINT, SIG_DFL); - kill(getpid(), SIGINT); + if(devfd >= 0) + close(devfd); + devfd = -1; + if(cleaner_name) + dm_remove_device(cleaner_name, 1, cleaner_size); + + signal(SIGINT, SIG_DFL); + kill(getpid(), SIGINT); } static char *_error_hint(char *cipherName, char *cipherMode, size_t keyLength) @@ -148,14 +123,14 @@ static int LUKS_endec_template(char *src, size_t srcLength, struct luks_phdr *hdr, char *key, size_t keyLength, const char *device, - unsigned int sector, struct setup_backend *backend, + unsigned int sector, ssize_t (*func)(int, void *, size_t), int mode) { char *name = NULL; char *fullpath = NULL; char *dmCipherSpec = NULL; - const char *dmDir = backend->dir(); + const char *dmDir = dm_get_dir(); int r = -1; if(dmDir == NULL) { @@ -171,9 +146,9 @@ static int LUKS_endec_template(char *src, size_t srcLength, signal(SIGINT, sigint_handler); cleaner_name = name; - cleaner_backend = backend; - r = setup_mapping(dmCipherSpec,name,device,hdr->payloadOffset,key,keyLength,sector,srcLength,backend,mode); + r = setup_mapping(dmCipherSpec, name, device, hdr->payloadOffset, + key, keyLength, sector, srcLength, mode); if(r < 0) { set_error("Failed to setup dm-crypt key mapping for device %s.\n" "Check that kernel supports %s cipher (check syslog for more info).\n%s", @@ -184,49 +159,50 @@ static int LUKS_endec_template(char *src, size_t srcLength, } devfd = open(fullpath, mode | O_DIRECT | O_SYNC); /* devfd is a global var */ - if(devfd == -1) { r = -EIO; goto out2; } + if(devfd == -1) { + r = -EIO; + goto out2; + } r = func(devfd,src,srcLength); - if(r < 0) { r = -EIO; goto out3; } + if(r < 0) { + r = -EIO; + goto out3; + } r = 0; out3: close(devfd); devfd = -1; out2: - clear_mapping(cleaner_name, cleaner_size, cleaner_backend); + dm_remove_device(cleaner_name, 1, cleaner_size); out1: signal(SIGINT, SIG_DFL); cleaner_name = NULL; - cleaner_backend = NULL; cleaner_size = 0; free(dmCipherSpec); - free(fullpath); - free(name); + free(fullpath); + free(name); return r; } -int LUKS_encrypt_to_storage(char *src, size_t srcLength, - struct luks_phdr *hdr, - char *key, size_t keyLength, - const char *device, - unsigned int sector, struct setup_backend *backend) -{ - - return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device, sector, backend, - (ssize_t (*)(int, void *, size_t)) write_blockwise, O_RDWR); -} - -int LUKS_decrypt_from_storage(char *dst, size_t dstLength, - struct luks_phdr *hdr, - char *key, size_t keyLength, - const char *device, - unsigned int sector, struct setup_backend *backend) +int LUKS_encrypt_to_storage(char *src, size_t srcLength, + struct luks_phdr *hdr, + char *key, size_t keyLength, + const char *device, + unsigned int sector) { - return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device, sector, backend, read_blockwise, O_RDONLY); + return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device, sector, + (ssize_t (*)(int, void *, size_t)) write_blockwise, + O_RDWR); } -// Local Variables: -// c-basic-offset: 8 -// indent-tabs-mode: nil -// End: +int LUKS_decrypt_from_storage(char *dst, size_t dstLength, + struct luks_phdr *hdr, + char *key, size_t keyLength, + const char *device, + unsigned int sector) +{ + return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device, + sector, read_blockwise, O_RDONLY); +} diff --git a/luks/keymanage.c b/luks/keymanage.c index dbc6f2e..20604bf 100644 --- a/luks/keymanage.c +++ b/luks/keymanage.c @@ -223,8 +223,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, int LUKS_set_key(const char *device, unsigned int keyIndex, const char *password, size_t passwordLen, - struct luks_phdr *hdr, struct luks_masterkey *mk, - struct setup_backend *backend) + struct luks_phdr *hdr, struct luks_masterkey *mk) { char derivedKey[hdr->keyBytes]; char *AfKey; @@ -268,8 +267,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex, derivedKey, hdr->keyBytes, device, - hdr->keyblock[keyIndex].keyMaterialOffset, - backend); + hdr->keyblock[keyIndex].keyMaterialOffset); if(r < 0) { if(!get_error()) set_error("Failed to write to key storage"); @@ -293,8 +291,7 @@ int LUKS_open_key(const char *device, const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct luks_masterkey *mk, - struct setup_backend *backend) + struct luks_masterkey *mk) { char derivedKey[hdr->keyBytes]; char *AfKey; @@ -324,8 +321,7 @@ int LUKS_open_key(const char *device, derivedKey, hdr->keyBytes, device, - hdr->keyblock[keyIndex].keyMaterialOffset, - backend); + hdr->keyblock[keyIndex].keyMaterialOffset); if(r < 0) goto out; r = AF_merge(AfKey,mk->key,mk->keyLength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); @@ -353,30 +349,28 @@ int LUKS_open_any_key(const char *device, const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct luks_masterkey **mk, - struct setup_backend *backend) + struct luks_masterkey **mk) { int r; r = LUKS_read_phdr(device, hdr); if(r < 0) return r; - return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk,backend); + return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk); } int LUKS_open_any_key_with_hdr(const char *device, const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct luks_masterkey **mk, - struct setup_backend *backend) + struct luks_masterkey **mk) { unsigned int i; int r; *mk=LUKS_alloc_masterkey(hdr->keyBytes); for(i=0; i