From: Milan Broz Date: Sun, 30 Aug 2009 18:07:17 +0000 (+0000) Subject: * Add log macros and make logging modre consitent. X-Git-Tag: upstream/1.6~735 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bf7819ccefcdd7f20e1816f8d549a5b93ab81919;p=platform%2Fupstream%2Fcryptsetup.git * Add log macros and make logging modre consitent. * Move command successful messages to verbose level. * Introduce --debug parameter. Signed-off-by: Milan Broz git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@92 36d66b0a-2a48-0410-832c-cd162a569da5 --- diff --git a/ChangeLog b/ChangeLog index a2c15ef..e12935f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ * Require device device-mapper to build and do not use backend wrapper for dm calls. * Move memory locking and dm initialization to command layer. * Increase priority of process if memory is locked. + * Add log macros and make logging modre consitent. + * Move command successful messages to verbose level. + * Introduce --debug parameter. 2009-08-17 Milan Broz * Fix PBKDF2 speed calculation for large passhrases. diff --git a/lib/internal.h b/lib/internal.h index f3be662..25163b2 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -17,6 +17,8 @@ #define SECTOR_SIZE (1 << SECTOR_SHIFT) #define DEFAULT_ALIGNMENT 4096 +#define MAX_TTY_PASSWORD_LEN 512 + /* private struct crypt_options flags */ #define CRYPT_FLAG_FREE_DEVICE (1 << 24) @@ -46,6 +48,7 @@ void *safe_alloc(size_t size); void safe_free(void *data); void *safe_realloc(void *data, size_t size); char *safe_strdup(const char *s); +void set_debug_level(int level); struct hash_backend *get_hash_backend(const char *name); void put_hash_backend(struct hash_backend *backend); @@ -82,7 +85,15 @@ ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offse int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, - const char *key_file, int passphrase_fd, int timeout, int how2verify); + const char *key_file, int passphrase_fd, int timeout, int how2verify, struct crypt_device *cd); + +void set_default_log(void (*log)(int class, char *msg)); +void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...); +#define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x) +#define log_std(c, x...) logger(c, CRYPT_LOG_NORMAL, __FILE__, __LINE__, x) +#define log_err(c, x...) do { \ + logger(c, CRYPT_LOG_ERROR, __FILE__, __LINE__, x); \ + set_error(x); } while(0) int memlock_inc(struct crypt_device *ctx); int memlock_dec(struct crypt_device *ctx); diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index f87b736..afee144 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -9,6 +9,7 @@ extern "C" { #define CRYPT_LOG_NORMAL 0 #define CRYPT_LOG_ERROR 1 +#define CRYPT_LOG_DEBUG -1 /* always on stdout */ struct interface_callbacks { int (*yesDialog)(char *msg); diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index 9db687e..7d72a2f 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -21,13 +21,18 @@ static struct crypt_device *_context = NULL; static void set_dm_error(int level, const char *file, int line, const char *f, ...) { + char *msg = NULL; va_list va; - if (level > 3) - return; - va_start(va, f); - set_error_va(f, va); + if (vasprintf(&msg, f, va) > 0) { + if (level < 4) { + log_err(_context, msg); + log_err(_context, "\n"); + } else + log_dbg(msg); + } + free(msg); va_end(va); } @@ -36,6 +41,8 @@ static int _dm_simple(int task, const char *name); int dm_init(struct crypt_device *context, int check_kernel) { if (!_dm_use_count++) { + log_dbg("Initialising device-mapper backend%s.", + check_kernel ? "" : " (NO kernel check requested)"); if (check_kernel && !_dm_simple(DM_DEVICE_LIST_VERSIONS, NULL)) return -1; dm_log_init(set_dm_error); @@ -51,6 +58,7 @@ int dm_init(struct crypt_device *context, int check_kernel) void dm_exit(void) { if (_dm_use_count && (!--_dm_use_count)) { + log_dbg("Releasing device-mapper backend."); dm_log_init_verbose(0); dm_log_init(NULL); dm_lib_release(); @@ -239,6 +247,8 @@ int dm_remove_device(const char *name, int force, uint64_t size) do { r = _dm_simple(DM_DEVICE_REMOVE, name) ? 0 : -EINVAL; if (--retries && r) { + log_dbg("WARNING: other process locked internal device %s, %s.", + name, retries ? "retrying remove" : "giving up"); sleep(1); } } while (r == -EINVAL && retries); diff --git a/lib/setup.c b/lib/setup.c index f1989c5..dc4c2e7 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -15,6 +15,13 @@ #include "internal.h" #include "blockdev.h" #include "luks.h" +#include "internal.h" + +struct crypt_device { + /* callbacks definitions */ + void (*log)(int class, const char *msg, void *usrptr); + void *log_usrptr; +}; struct device_infos { uint64_t size; @@ -23,24 +30,52 @@ struct device_infos { #define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; }) -static void logger(struct crypt_options *options, int class, char *format, ...) { +/* Log helper */ +static void (*_default_log)(int class, char *msg) = NULL; +static int _debug_level = 0; + +void crypt_set_debug_level(int level) +{ + _debug_level = level; +} + +void set_default_log(void (*log)(int class, char *msg)) +{ + _default_log = log; +} + +void logger(struct crypt_device *cd, int class, const char *file, + int line, const char *format, ...) +{ va_list argp; char *target = NULL; va_start(argp, format); - if (vasprintf(&target, format, argp) > 0) - options->icb->log(class, target); + if (vasprintf(&target, format, argp) > 0) { + if (class >= 0) { + if (cd && cd->log) + cd->log(class, target, cd->log_usrptr); + else if (_default_log) + _default_log(class, target); +#ifdef CRYPT_DEBUG + } else if (_debug_level) + printf("# %s:%d %s\n", file ?: "?", line, target); +#else + } else if (_debug_level) + printf("# %s\n", target); +#endif + } va_end(argp); free(target); } -static void hexprintICB(struct crypt_options *options, int class, char *d, int n) +static void hexprintICB(struct crypt_device *cd, char *d, int n) { int i; for(i = 0; i < n; i++) - logger(options, class, "%02hhx ", (char)d[i]); + log_std(cd, "%02hhx ", (char)d[i]); } /* @@ -49,19 +84,21 @@ static void hexprintICB(struct crypt_options *options, int class, char *d, int n * from binary file: check if there is sufficently large key material * interactive & from fd: hash if requested, otherwise crop or pad with '0' */ - -static char *process_key(struct crypt_options *options, char *pass, int passLen) { +static char *process_key(struct crypt_device *cd, + struct crypt_options *options, + const char *pass, size_t passLen) +{ char *key = safe_alloc(options->key_size); memset(key, 0, options->key_size); /* key is coming from binary file */ if (options->key_file && strcmp(options->key_file, "-")) { if(passLen < options->key_size) { - set_error("Could not read %d bytes from key file", - options->key_size); + log_err(cd, _("Cannot not read %d bytes from key file %s.\n"), + options->key_size, options->key_file); safe_free(key); return NULL; - } + } memcpy(key,pass,options->key_size); return key; } @@ -72,6 +109,7 @@ static char *process_key(struct crypt_options *options, char *pass, int passLen) key, options->key_size, pass, passLen) < 0) { + log_err(cd, _("Key processing error.\n")); safe_free(key); return NULL; } @@ -184,8 +222,7 @@ static int wipe_device_header(const char *device, int sectors) return r; } -static int parse_into_name_and_mode(const char *nameAndMode, char *name, - char *mode) +static int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode) { /* Token content stringification, see info cpp/stringification */ #define str(s) #s @@ -196,27 +233,25 @@ static int parse_into_name_and_mode(const char *nameAndMode, char *name, int r; if(sscanf(nameAndMode,scanpattern1, name, mode) != 2) { - if((r = sscanf(nameAndMode,scanpattern2,name)) == 1) { + if((r = sscanf(nameAndMode,scanpattern2,name)) == 1) strncpy(mode,"cbc-plain",10); - } - else { - set_error("no known cipher-spec pattern detected"); + else return -EINVAL; - } } return 0; -#undef sp1 -#undef sp2 +#undef scanpattern1 +#undef scanpattern2 #undef str #undef xstr } -static int keyslot_is_valid(int keySlotIndex, struct crypt_options *options) +static int keyslot_is_valid(struct crypt_device *cd, int keySlotIndex) { if(keySlotIndex >= LUKS_NUMKEYS || keySlotIndex < 0) { - logger(options,CRYPT_LOG_ERROR,"Key slot %d is invalid, please pick between 0 and %d.\n", keySlotIndex, LUKS_NUMKEYS - 1); + log_err(cd, _("Key slot %d is invalid, please select between 0 and %d.\n"), + keySlotIndex, LUKS_NUMKEYS - 1); return 0; } @@ -224,12 +259,13 @@ static int keyslot_is_valid(int keySlotIndex, struct crypt_options *options) } /* Select free keyslot or verifies that the one specified is empty */ -static int keyslot_from_option(int keySlotOption, struct luks_phdr *hdr, struct crypt_options *options) { +static int keyslot_from_option(struct crypt_device *cd, int keySlotOption, struct luks_phdr *hdr) { if(keySlotOption >= 0) { - if(!keyslot_is_valid(keySlotOption, options)) + if(!keyslot_is_valid(cd, keySlotOption)) return -EINVAL; else if(hdr->keyblock[keySlotOption].active != LUKS_KEY_DISABLED) { - logger(options,CRYPT_LOG_ERROR,"Key slot %d is full, please pick another one", keySlotOption); + log_err(cd, _("Key slot %d is full, please select another one.\n"), + keySlotOption); return -EINVAL; } else { return keySlotOption; @@ -241,15 +277,16 @@ static int keyslot_from_option(int keySlotOption, struct luks_phdr *hdr, struct if(hdr->keyblock[i].active == LUKS_KEY_DISABLED) break; } if(i==LUKS_NUMKEYS) { - logger(options,CRYPT_LOG_ERROR,"All slots full"); + log_err(cd, _("All key slots full.\n")); return -EINVAL; } return i; } } -static int __crypt_create_device(int reload, struct crypt_options *options) +static int create_device_helper(int reload, struct crypt_options *options) { + struct crypt_device *cd = NULL; struct device_infos infos; char *key = NULL; unsigned int keyLen; @@ -262,7 +299,7 @@ static int __crypt_create_device(int reload, struct crypt_options *options) return r; } else { if (r >= 0) { - set_error("Device %s already exists.", options->name); + log_err(cd, _("Device %s already exists.\n"), options->name); return -EEXIST; } if (r != -ENODEV) @@ -270,7 +307,7 @@ static int __crypt_create_device(int reload, struct crypt_options *options) } if (options->key_size < 0 || options->key_size > 1024) { - set_error("Invalid key size"); + log_err(cd, _("Invalid key size %d.\n"), options->key_size); return -EINVAL; } @@ -280,11 +317,11 @@ static int __crypt_create_device(int reload, struct crypt_options *options) if (!options->size) { options->size = infos.size; if (!options->size) { - set_error("Not a block device"); + log_err(cd, "Not a block device"); return -ENOTBLK; } if (options->size <= options->offset) { - set_error("Invalid offset"); + log_err(cd, "Invalid offset"); return -EINVAL; } options->size -= options->offset; @@ -293,26 +330,18 @@ static int __crypt_create_device(int reload, struct crypt_options *options) if (infos.readonly) options->flags |= CRYPT_FLAG_READONLY; - get_key("Enter passphrase: ", &key, &keyLen, options->key_size, options->key_file, options->passphrase_fd, options->timeout, options->flags); + get_key("Enter passphrase: ", &key, &keyLen, options->key_size, + options->key_file, options->passphrase_fd, options->timeout, options->flags, NULL); if (!key) { - set_error("Key reading error"); + log_err(cd, "Key reading error"); return -ENOENT; } - processed_key = process_key(options,key,keyLen); + processed_key = process_key(cd, options, key, keyLen); safe_free(key); - if (!processed_key) { - const char *error=get_error(); - if(error) { - char *c_error_handling_sucks = NULL; - if (asprintf(&c_error_handling_sucks,"Key processing error: %s",error) > 0) - set_error(c_error_handling_sucks); - free(c_error_handling_sucks); - } else - set_error("Key processing error"); + if (!processed_key) return -ENOENT; - } r = dm_create_device(options->name, options->device, options->cipher, NULL, options->size, options->skip, options->offset, @@ -324,32 +353,105 @@ static int __crypt_create_device(int reload, struct crypt_options *options) return r; } -static int __crypt_query_device(int details, struct crypt_options *options) +static int luks_remove_helper(struct crypt_device *cd, + struct crypt_options *options, int supply_it) { - int read_only, r; + struct luks_masterkey *mk; + struct luks_phdr hdr; + char *password=NULL; + unsigned int passwordLen; + const char *device = options->device; + int keyIndex; + int openedIndex; + int r, last_slot; - r = dm_status_device(options->name); - if (r == -ENODEV) - return 0; + if (!LUKS_device_ready(options->device, O_RDWR)) + return -ENOTBLK; - 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(supply_it) { + get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file, + options->passphrase_fd, options->timeout, options->flags, cd); + if(!password) { + r = -EINVAL; goto out; + } - if (r < 0) - return r; + keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, cd); + if(keyIndex < 0) { + log_err(cd, "No remaining key available with this passphrase.\n"); + r = -EPERM; goto out; + } else + log_std(cd ,"key slot %d selected for deletion.\n", keyIndex); - if (read_only) - options->flags |= CRYPT_FLAG_READONLY; + safe_free(password); + password = NULL; + } else { + keyIndex = options->key_slot; + if (!keyslot_is_valid(cd, keyIndex)) { + r = -EINVAL; goto out; + } + } - options->flags |= CRYPT_FLAG_FREE_DEVICE; - options->flags |= CRYPT_FLAG_FREE_CIPHER; + last_slot = LUKS_is_last_keyslot(options->device, keyIndex); + if(last_slot && !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) { + r = -EINVAL; goto out; + } - return 1; + if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) { + options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY; + get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file, + options->passphrase_fd, options->timeout, options->flags, cd); + if(!password) { + r = -EINVAL; goto out; + } + + r = LUKS_read_phdr(device, &hdr, 1, cd); + if(r < 0) { + options->icb->log(CRYPT_LOG_ERROR,"Failed to access device.\n"); + r = -EIO; goto out; + } + + if(!last_slot) + hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED; + + openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, cd); + /* Clean up */ + if (openedIndex >= 0) { + LUKS_dealloc_masterkey(mk); + mk = NULL; + } + if(openedIndex < 0) { + log_err(cd, "No remaining key available with this passphrase.\n"); + r = -EPERM; goto out; + } else + log_std(cd, "key slot %d verified.\n", openedIndex); + } + r = LUKS_del_key(device, keyIndex, cd); + if(r < 0) goto out; + + r = 0; +out: + safe_free(password); + return r; +} + +/* OPTIONS: name, cipher, device, hash, key_file, key_size, key_slot, + * offset, size, skip, timeout, tries, passphrase_fd (ignored), + * flags, icb */ +int crypt_create_device(struct crypt_options *options) +{ + return create_device_helper(0, options); +} + +/* OPTIONS: same as create above */ +int crypt_update_device(struct crypt_options *options) +{ + return create_device_helper(1, options); } -static int __crypt_resize_device(int details, struct crypt_options *options) +/* OPTIONS: name, size, icb */ +int crypt_resize_device(struct crypt_options *options) { + struct crypt_device *cd = NULL; char *device, *cipher, *key = NULL; uint64_t size, skip, offset; int key_size, read_only, r; @@ -366,11 +468,11 @@ static int __crypt_resize_device(int details, struct crypt_options *options) if (!options->size) { options->size = infos.size; if (!options->size) { - set_error("Not a block device"); + log_err(cd, "Not a block device"); return -ENOTBLK; } if (options->size <= offset) { - set_error("Invalid offset"); + log_err(cd, "Invalid offset"); return -EINVAL; } options->size -= offset; @@ -390,7 +492,33 @@ static int __crypt_resize_device(int details, struct crypt_options *options) return r; } -static int __crypt_remove_device(int arg, struct crypt_options *options) +/* OPTIONS: name, icb */ +int crypt_query_device(struct crypt_options *options) +{ + int read_only, r; + + r = dm_status_device(options->name); + if (r == -ENODEV) + return 0; + + 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; +} + +/* OPTIONS: name, icb */ +int crypt_remove_device(struct crypt_options *options) { int r; @@ -398,17 +526,18 @@ static int __crypt_remove_device(int arg, struct crypt_options *options) if (r < 0) return r; if (r > 0) { - set_error("Device busy"); + log_err(NULL, "Device busy"); return -EBUSY; } return dm_remove_device(options->name, 0, 0); } -static int __crypt_luks_format(int arg, struct crypt_options *options) +/* OPTIONS: device, cipher, hash, align_payload, key_size (master key), key_slot + * new_key_file, iteration_time, timeout, flags, icb */ +int crypt_luksFormat(struct crypt_options *options) { - int r; - + struct crypt_device *cd = NULL; struct luks_phdr header; struct luks_masterkey *mk=NULL; char *password=NULL; @@ -416,7 +545,7 @@ static int __crypt_luks_format(int arg, struct crypt_options *options) char cipherMode[LUKS_CIPHERMODE_L]; unsigned int passwordLen; unsigned int PBKDF2perSecond = 0; - int keyIndex; + int r, keyIndex; if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL)) return -ENOTBLK; @@ -429,8 +558,7 @@ static int __crypt_luks_format(int arg, struct crypt_options *options) logger(options, CRYPT_LOG_ERROR, \ "offset of " #entry " = %d\n", (char *)(&header.entry)-(char *)(&header)) - logger(options, CRYPT_LOG_ERROR, - "sizeof phdr %d, sizeof key slot %d\n", + log_err("sizeof phdr %d, sizeof key slot %d\n", sizeof(struct luks_phdr), sizeof(header.keyblock[0])); @@ -448,12 +576,15 @@ static int __crypt_luks_format(int arg, struct crypt_options *options) #endif r = parse_into_name_and_mode(options->cipher, cipherName, cipherMode); - if(r < 0) return r; + if(r < 0) { + log_err(cd, _("No known cipher specification pattern detected.\n")); + return r; + } - r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, LUKS_STRIPES, options->align_payload); + r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, LUKS_STRIPES, options->align_payload, NULL); if(r < 0) return r; - keyIndex = keyslot_from_option(options->key_slot, &header, options); + keyIndex = keyslot_from_option(NULL, options->key_slot, &header); if(keyIndex == -EINVAL) { r = -EINVAL; goto out; } @@ -465,7 +596,8 @@ static int __crypt_luks_format(int arg, struct crypt_options *options) #ifdef LUKS_DEBUG logger(options, CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations); #endif - get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file, options->passphrase_fd, options->timeout, options->flags); + get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file, + options->passphrase_fd, options->timeout, options->flags, NULL); if(!password) { r = -EINVAL; goto out; } @@ -475,7 +607,7 @@ static int __crypt_luks_format(int arg, struct crypt_options *options) if(r < 0) goto out; /* Set key, also writes phdr */ - r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk); + r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, NULL); if(r < 0) goto out; r = 0; @@ -485,8 +617,10 @@ out: return r; } -static int __crypt_luks_open(int arg, struct crypt_options *options) +/* OPTIONS: name, device, key_size, key_file, timeout, tries, flags, icb */ +int crypt_luksOpen(struct crypt_options *options) { + struct crypt_device *cd = NULL; struct luks_masterkey *mk=NULL; struct luks_phdr hdr; char *prompt = NULL; @@ -499,7 +633,7 @@ static int __crypt_luks_open(int arg, struct crypt_options *options) r = dm_status_device(options->name); if (r >= 0) { - set_error("Device %s already exists.", options->name); + log_err(cd, "Device %s already exists.", options->name); return -EEXIST; } @@ -507,7 +641,7 @@ static int __crypt_luks_open(int arg, struct crypt_options *options) return -ENOTBLK; if (get_device_infos(options->device, &infos) < 0) { - set_error("Can't get device information.\n"); + log_err(cd, "Can't get device information.\n"); return -ENOTBLK; } @@ -525,7 +659,8 @@ start: password = safe_alloc(passwordLen + 1); strncpy(password, options->passphrase, passwordLen + 1); tries = 0; - } else if(get_key(prompt, &password, &passwordLen, options->key_size, options->key_file, options->passphrase_fd, options->timeout, options->flags)) + } else if(get_key(prompt, &password, &passwordLen, options->key_size, options->key_file, + options->passphrase_fd, options->timeout, options->flags, cd)) tries--; else tries = 0; @@ -534,13 +669,13 @@ start: r = -EINVAL; goto out; } - r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk); + r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, cd); if (r == -EPERM) - set_error("No key available with this passphrase.\n"); + log_err(cd, "No key available with this passphrase.\n"); if (r < 0) goto out1; - logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r); + log_err(NULL, "key slot %d unlocked.\n", r); options->offset = hdr.payloadOffset; @@ -554,11 +689,11 @@ start: options->size = infos.size; if (!options->size) { - set_error("Not a block device.\n"); + log_err(cd, "Not a block device.\n"); r = -ENOTBLK; goto out2; } if (options->size <= options->offset) { - set_error("Invalid offset"); + log_err(cd, "Invalid offset"); r = -EINVAL; goto out2; } options->size -= options->offset; @@ -584,8 +719,23 @@ start: return r; } -static int __crypt_luks_add_key(int arg, struct crypt_options *options) +/* OPTIONS: device, keys_slot, key_file, timeout, flags, icb */ +int crypt_luksKillSlot(struct crypt_options *options) { + return luks_remove_helper(NULL, options, 0); +} + +/* OPTIONS: device, new_key_file, key_file, timeout, flags, icb */ +int crypt_luksRemoveKey(struct crypt_options *options) +{ + return luks_remove_helper(NULL, options, 1); +} + +/* OPTIONS: device, new_key_file, key_file, key_slot, flags, + iteration_time, timeout, icb */ +int crypt_luksAddKey(struct crypt_options *options) +{ + struct crypt_device *cd = NULL; struct luks_masterkey *mk=NULL; struct luks_phdr hdr; char *password=NULL; unsigned int passwordLen; @@ -597,11 +747,11 @@ static int __crypt_luks_add_key(int arg, struct crypt_options *options) if (!LUKS_device_ready(options->device, O_RDWR)) return -ENOTBLK; - r = LUKS_read_phdr(device, &hdr); + r = LUKS_read_phdr(device, &hdr, 1, cd); if(r < 0) return r; - keyIndex = keyslot_from_option(options->key_slot, &hdr, options); + keyIndex = keyslot_from_option(cd, options->key_slot, &hdr); if(keyIndex == -EINVAL) { r = -EINVAL; goto out; } @@ -613,18 +763,16 @@ static int __crypt_luks_add_key(int arg, struct crypt_options *options) options->key_file, options->passphrase_fd, options->timeout, - options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE)); + options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE), cd); if(!password) { r = -EINVAL; goto out; } - r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk); + r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, cd); if(r < 0) { options->icb->log(CRYPT_LOG_ERROR,"No key available with this passphrase.\n"); r = -EPERM; goto out; - } else - logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r); - + } safe_free(password); get_key("Enter new passphrase for key slot: ", @@ -634,7 +782,7 @@ static int __crypt_luks_add_key(int arg, struct crypt_options *options) options->new_key_file, options->passphrase_fd, options->timeout, - options->flags); + options->flags, cd); if(!password) { r = -EINVAL; goto out; } @@ -643,7 +791,7 @@ static int __crypt_luks_add_key(int arg, struct crypt_options *options) 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); + r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, cd); if(r < 0) goto out; r = 0; @@ -653,163 +801,14 @@ out: return r; } -static int luks_remove_helper(int arg, struct crypt_options *options, int supply_it) -{ - struct luks_masterkey *mk; - struct luks_phdr hdr; - char *password=NULL; - unsigned int passwordLen; - const char *device = options->device; - int keyIndex; - int openedIndex; - int r, last_slot; - - if (!LUKS_device_ready(options->device, O_RDWR)) - return -ENOTBLK; - - if(supply_it) { - get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file, - options->passphrase_fd, options->timeout, options->flags); - if(!password) { - r = -EINVAL; goto out; - } - - 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; - } else - logger(options, CRYPT_LOG_NORMAL,"key slot %d selected for deletion.\n", keyIndex); - - safe_free(password); - password = NULL; - } else { - keyIndex = options->key_slot; - if (!keyslot_is_valid(keyIndex, options)) { - r = -EINVAL; goto out; - } - } - - last_slot = LUKS_is_last_keyslot(options->device, keyIndex); - if(last_slot && !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) { - r = -EINVAL; goto out; - } - - if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) { - options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY; - get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file, options->passphrase_fd, options->timeout, options->flags); - if(!password) { - r = -EINVAL; goto out; - } - - r = LUKS_read_phdr(device, &hdr); - if(r < 0) { - options->icb->log(CRYPT_LOG_ERROR,"Failed to access device.\n"); - r = -EIO; goto out; - } - - if(!last_slot) - hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED; - - openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk); - /* Clean up */ - if (openedIndex >= 0) { - LUKS_dealloc_masterkey(mk); - mk = NULL; - } - if(openedIndex < 0) { - options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n"); - r = -EPERM; goto out; - } else - logger(options, CRYPT_LOG_NORMAL,"key slot %d verified.\n", openedIndex); - } - r = LUKS_del_key(device, keyIndex); - if(r < 0) goto out; - - r = 0; -out: - safe_free(password); - return r; -} - -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 crypt_options *options) { - return luks_remove_helper(arg, options, 1); -} - -static int crypt_job(int (*job)(int arg, struct crypt_options *options), - int arg, struct crypt_options *options) -{ - int r; - - r = job(arg, options); - - if (r >= 0) - set_error(NULL); - - return r; -} - -int crypt_create_device(struct crypt_options *options) -{ - return crypt_job(__crypt_create_device, 0, options); -} - -int crypt_update_device(struct crypt_options *options) -{ - return crypt_job(__crypt_create_device, 1, options); -} - -int crypt_resize_device(struct crypt_options *options) -{ - return crypt_job(__crypt_resize_device, 0, options); -} - -int crypt_query_device(struct crypt_options *options) -{ - return crypt_job(__crypt_query_device, 1, options); -} - -int crypt_remove_device(struct crypt_options *options) -{ - return crypt_job(__crypt_remove_device, 0, options); - -} - -int crypt_luksFormat(struct crypt_options *options) -{ - return crypt_job(__crypt_luks_format, 0, options); -} - -int crypt_luksOpen(struct crypt_options *options) -{ - return crypt_job(__crypt_luks_open, 0, options); -} - -int crypt_luksKillSlot(struct crypt_options *options) -{ - return crypt_job(__crypt_luks_kill_slot, 0, options); -} - -int crypt_luksRemoveKey(struct crypt_options *options) -{ - return crypt_job(__crypt_luks_remove_key, 0, options); -} - -int crypt_luksAddKey(struct crypt_options *options) -{ - return crypt_job(__crypt_luks_add_key, 0, options); -} - +/* OPTIONS: device, icb */ int crypt_luksUUID(struct crypt_options *options) { + struct crypt_device *cd = NULL; struct luks_phdr hdr; int r; - r = LUKS_read_phdr(options->device,&hdr); + r = LUKS_read_phdr(options->device, &hdr, 1, cd); if(r < 0) return r; options->icb->log(CRYPT_LOG_NORMAL,hdr.uuid); @@ -817,57 +816,65 @@ int crypt_luksUUID(struct crypt_options *options) return 0; } +/* OPTIONS: device, icb */ int crypt_isLuks(struct crypt_options *options) { + struct crypt_device *cd = NULL; struct luks_phdr hdr; - return LUKS_read_phdr(options->device,&hdr); + return LUKS_read_phdr(options->device, &hdr, 0, cd); } +/* OPTIONS: device, icb */ int crypt_luksDump(struct crypt_options *options) { + struct crypt_device *cd = NULL; struct luks_phdr hdr; int r,i; - r = LUKS_read_phdr(options->device,&hdr); + r = LUKS_read_phdr(options->device, &hdr, 1, cd); if(r < 0) return r; - logger(options, CRYPT_LOG_NORMAL, "LUKS header information for %s\n\n",options->device); - logger(options, CRYPT_LOG_NORMAL, "Version: \t%d\n",hdr.version); - logger(options, CRYPT_LOG_NORMAL, "Cipher name: \t%s\n",hdr.cipherName); - logger(options, CRYPT_LOG_NORMAL, "Cipher mode: \t%s\n",hdr.cipherMode); - logger(options, CRYPT_LOG_NORMAL, "Hash spec: \t%s\n",hdr.hashSpec); - logger(options, CRYPT_LOG_NORMAL, "Payload offset:\t%d\n",hdr.payloadOffset); - logger(options, CRYPT_LOG_NORMAL, "MK bits: \t%d\n",hdr.keyBytes*8); - logger(options, CRYPT_LOG_NORMAL, "MK digest: \t"); - hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigest,LUKS_DIGESTSIZE); - logger(options, CRYPT_LOG_NORMAL, "\n"); - logger(options, CRYPT_LOG_NORMAL, "MK salt: \t"); - hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt,LUKS_SALTSIZE/2); - logger(options, CRYPT_LOG_NORMAL, "\n \t"); - hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2); - logger(options, CRYPT_LOG_NORMAL, "\n"); - logger(options, CRYPT_LOG_NORMAL, "MK iterations: \t%d\n",hdr.mkDigestIterations); - logger(options, CRYPT_LOG_NORMAL, "UUID: \t%s\n\n",hdr.uuid); - for(i=0;idevice); + log_std(cd, "Version: \t%d\n", hdr.version); + log_std(cd, "Cipher name: \t%s\n", hdr.cipherName); + log_std(cd, "Cipher mode: \t%s\n", hdr.cipherMode); + log_std(cd, "Hash spec: \t%s\n", hdr.hashSpec); + log_std(cd, "Payload offset:\t%d\n", hdr.payloadOffset); + log_std(cd, "MK bits: \t%d\n", hdr.keyBytes * 8); + log_std(cd, "MK digest: \t"); + hexprintICB(cd, hdr.mkDigest, LUKS_DIGESTSIZE); + log_std(cd, "\n"); + log_std(cd, "MK salt: \t"); + hexprintICB(cd, hdr.mkDigestSalt, LUKS_SALTSIZE/2); + log_std(cd, "\n \t"); + hexprintICB(cd, hdr.mkDigestSalt+LUKS_SALTSIZE/2, LUKS_SALTSIZE/2); + log_std(cd, "\n"); + log_std(cd, "MK iterations: \t%d\n", hdr.mkDigestIterations); + log_std(cd, "UUID: \t%s\n\n", hdr.uuid); + for(i = 0; i < LUKS_NUMKEYS; i++) { if(hdr.keyblock[i].active == LUKS_KEY_ENABLED) { - logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: ENABLED\n",i); - logger(options, CRYPT_LOG_NORMAL, "\tIterations: \t%d\n",hdr.keyblock[i].passwordIterations); - logger(options, CRYPT_LOG_NORMAL, "\tSalt: \t"); - hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt,LUKS_SALTSIZE/2); - logger(options, CRYPT_LOG_NORMAL, "\n\t \t"); - hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2); - logger(options, CRYPT_LOG_NORMAL, "\n"); - - logger(options, CRYPT_LOG_NORMAL, "\tKey material offset:\t%d\n",hdr.keyblock[i].keyMaterialOffset); - logger(options, CRYPT_LOG_NORMAL, "\tAF stripes: \t%d\n",hdr.keyblock[i].stripes); + log_std(cd, "Key Slot %d: ENABLED\n",i); + log_std(cd, "\tIterations: \t%d\n", + hdr.keyblock[i].passwordIterations); + log_std(cd, "\tSalt: \t"); + hexprintICB(cd, hdr.keyblock[i].passwordSalt, + LUKS_SALTSIZE/2); + log_std(cd, "\n\t \t"); + hexprintICB(cd, hdr.keyblock[i].passwordSalt + + LUKS_SALTSIZE/2, LUKS_SALTSIZE/2); + log_std(cd, "\n"); + + log_std(cd, "\tKey material offset:\t%d\n", + hdr.keyblock[i].keyMaterialOffset); + log_std(cd, "\tAF stripes: \t%d\n", + hdr.keyblock[i].stripes); } else - logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: DISABLED\n",i); + log_std(cd, "Key Slot %d: DISABLED\n", i); } return 0; } - void crypt_get_error(char *buf, size_t size) { const char *error = get_error(); diff --git a/lib/utils.c b/lib/utils.c index a425b69..890e620 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -18,7 +18,6 @@ #include "libcryptsetup.h" #include "internal.h" - struct safe_allocation { size_t size; char data[1]; @@ -28,18 +27,24 @@ static char *error=NULL; void set_error_va(const char *fmt, va_list va) { + int r; if(error) { - free(error); - error=NULL; + free(error); + error = NULL; } if(!fmt) return; - if (vasprintf(&error, fmt, va) < 0) { + r = vasprintf(&error, fmt, va); + if (r < 0) { free(error); error = NULL; + return; } + + if (r && error[r - 1] == '\n') + error[r - 1] = '\0'; } void set_error(const char *fmt, ...) @@ -239,10 +244,8 @@ ssize_t read_blockwise(int fd, void *orig_buf, size_t count) { buf = orig_buf; r = read(fd, buf, solid); - if(r < 0 || r != solid) { - set_error("read failed in read_blockwise.\n"); + if(r < 0 || r != solid) goto out; - } if (hangover) { hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment); @@ -331,8 +334,7 @@ static int timed_read(int fd, char *pass, size_t maxlen, long timeout) if (select(fd+1, &fds, NULL, NULL, &t) > 0) failed = untimed_read(fd, pass, maxlen); - else - set_error("Operation timed out"); + return failed; } @@ -352,10 +354,9 @@ static int interactive_pass(const char *prompt, char *pass, size_t maxlen, outfd = STDERR_FILENO; } - if (tcgetattr(infd, &orig)) { - set_error("Unable to get terminal"); + if (tcgetattr(infd, &orig)) goto out_err; - } + memcpy(&tmp, &orig, sizeof(tmp)); tmp.c_lflag &= ~ECHO; @@ -395,7 +396,7 @@ out_err: */ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, - const char *key_file, int passphrase_fd, int timeout, int how2verify) + const char *key_file, int passphrase_fd, int timeout, int how2verify, struct crypt_device *cd) { int fd; const int verify = how2verify & CRYPT_FLAG_VERIFY; @@ -412,9 +413,7 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, } else if (key_file) { fd = open(key_file, O_RDONLY); if (fd < 0) { - char buf[128]; - set_error("Error opening key file: %s", - strerror_r(errno, buf, 128)); + log_err(cd, "Failed to open key file %s.\n", key_file); goto out_err; } newline_stop = 0; @@ -423,7 +422,7 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, * of key bytes (default or passed by -s) */ read_horizon = key_size; } else { - fd = passphrase_fd; + fd = STDIN_FILENO; newline_stop = 1; read_horizon = 0; /* Infinite, if read from terminal or fd */ } @@ -432,16 +431,16 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, if(isatty(fd)) { int i; - pass = safe_alloc(512); - if (!pass || (i = interactive_pass(prompt, pass, 512, timeout))) { - set_error("Error reading passphrase"); + pass = safe_alloc(MAX_TTY_PASSWORD_LEN); + if (!pass || (i = interactive_pass(prompt, pass, MAX_TTY_PASSWORD_LEN, timeout))) { + log_err(cd, "Error reading passphrase from terminal.\n"); goto out_err; } if (verify || verify_if_possible) { - char pass_verify[512]; + char pass_verify[MAX_TTY_PASSWORD_LEN]; i = interactive_pass("Verify passphrase: ", pass_verify, sizeof(pass_verify), timeout); if (i || strcmp(pass, pass_verify) != 0) { - set_error("Passphrases do not match"); + log_err(cd, "Passphrases do not match.\n"); goto out_err; } memset(pass_verify, 0, sizeof(pass_verify)); @@ -456,7 +455,7 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, int buflen, i; if(verify) { - set_error("Can't do passphrase verification on non-tty inputs"); + log_err(cd, "Can't do passphrase verification on non-tty inputs.\n"); goto out_err; } /* The following for control loop does an exhausting @@ -469,13 +468,13 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, if(key_file && strcmp(key_file, "-") && read_horizon == 0) { struct stat st; if(stat(key_file, &st) < 0) { - set_error("Can't stat key file"); + log_err(cd, "Failed to stat key file %s.\n", key_file); goto out_err; } if(!S_ISREG(st.st_mode)) { - // set_error("Can't do exhausting read on non regular files"); - // goto out_err; - fprintf(stderr,"Warning: exhausting read requested, but key file is not a regular file, function might never return.\n"); + log_err(cd, "Warning: exhausting read requested, but key file %s" + " is not a regular file, function might never return.\n", + key_file); } } buflen = 0; @@ -484,8 +483,7 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size, buflen += 128; pass = safe_realloc(pass, buflen); if (!pass) { - set_error("Not enough memory while " - "reading passphrase"); + log_err(cd, "Out of memory while reading passphrase.\n"); goto out_err; } } @@ -519,17 +517,18 @@ static int _memlock_count = 0; int memlock_inc(struct crypt_device *ctx) { if (!_memlock_count++) { + log_dbg("Locking memory."); if (mlockall(MCL_CURRENT | MCL_FUTURE)) { - set_error(_("WARNING!!! Possibly insecure memory. Are you root?\n")); + log_err(ctx, _("WARNING!!! Possibly insecure memory. Are you root?\n")); _memlock_count--; return 0; } errno = 0; if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno) - set_error(_("Cannot get process priority.\n")); + log_err(ctx, _("Cannot get process priority.\n")); else if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY)) - set_error(_("setpriority %u failed: %s"), + log_err(ctx, _("setpriority %u failed: %s"), DEFAULT_PROCESS_PRIORITY, strerror(errno)); } return _memlock_count ? 1 : 0; @@ -538,10 +537,11 @@ int memlock_inc(struct crypt_device *ctx) int memlock_dec(struct crypt_device *ctx) { if (_memlock_count && (!--_memlock_count)) { + log_dbg("Unlocking memory."); if (munlockall()) - set_error(_("Cannot unlock memory.")); + log_err(ctx, _("Cannot unlock memory.")); if (setpriority(PRIO_PROCESS, 0, _priority)) - set_error(_("setpriority %u failed: %s"), _priority, strerror(errno)); + log_err(ctx, _("setpriority %u failed: %s"), _priority, strerror(errno)); } return _memlock_count ? 1 : 0; } diff --git a/luks/keyencryption.c b/luks/keyencryption.c index 7bd8913..f32729b 100644 --- a/luks/keyencryption.c +++ b/luks/keyencryption.c @@ -55,7 +55,7 @@ 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, - int mode) + int mode, struct crypt_device *ctx) { int device_sector_size = sector_size_for_device(device); uint64_t size; @@ -65,10 +65,9 @@ static int setup_mapping(const char *cipher, const char *name, * device's sector size, otherwise the mapping will be refused. */ if(device_sector_size < 0) { - set_error(_("Unable to obtain sector size for %s"),device); + log_err(ctx, _("Unable to obtain sector size for %s"), device); return -EINVAL; } - set_error(NULL); size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE; cleaner_size = size; @@ -125,7 +124,8 @@ static int LUKS_endec_template(char *src, size_t srcLength, const char *device, unsigned int sector, ssize_t (*func)(int, void *, size_t), - int mode) + int mode, + struct crypt_device *ctx) { char *name = NULL; char *fullpath = NULL; @@ -134,7 +134,7 @@ static int LUKS_endec_template(char *src, size_t srcLength, int r = -1; if(dmDir == NULL) { - fputs(_("Failed to obtain device mapper directory."), stderr); + log_err(ctx, _("Failed to obtain device mapper directory.")); return -1; } if(asprintf(&name,"temporary-cryptsetup-%d",getpid()) == -1 || @@ -143,29 +143,31 @@ static int LUKS_endec_template(char *src, size_t srcLength, r = -ENOMEM; goto out1; } - + signal(SIGINT, sigint_handler); cleaner_name = name; r = setup_mapping(dmCipherSpec, name, device, hdr->payloadOffset, - key, keyLength, sector, srcLength, mode); + key, keyLength, sector, srcLength, mode, ctx); 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", - device, dmCipherSpec, - _error_hint(hdr->cipherName, hdr->cipherMode, keyLength * 8)); + log_err(ctx, _("Failed to setup dm-crypt key mapping for device %s.\n" + "Check that kernel supports %s cipher (check syslog for more info).\n%s"), + device, dmCipherSpec, + _error_hint(hdr->cipherName, hdr->cipherMode, keyLength * 8)); r = -EIO; goto out1; } devfd = open(fullpath, mode | O_DIRECT | O_SYNC); /* devfd is a global var */ if(devfd == -1) { + log_err(ctx, _("Failed to open temporary keystore device.\n")); r = -EIO; goto out2; } r = func(devfd,src,srcLength); if(r < 0) { + log_err(ctx, _("Failed to access temporary keystore device.\n")); r = -EIO; goto out3; } @@ -190,19 +192,21 @@ 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) + unsigned int sector, + struct crypt_device *ctx) { return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device, sector, (ssize_t (*)(int, void *, size_t)) write_blockwise, - O_RDWR); + O_RDWR, ctx); } 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) + unsigned int sector, + struct crypt_device *ctx) { return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device, - sector, read_blockwise, O_RDONLY); + sector, read_blockwise, O_RDONLY, ctx); } diff --git a/luks/keymanage.c b/luks/keymanage.c index 20604bf..f095afa 100644 --- a/luks/keymanage.c +++ b/luks/keymanage.c @@ -77,29 +77,40 @@ struct luks_masterkey *LUKS_generate_masterkey(int keylength) return mk; } -int LUKS_read_phdr(const char *device, struct luks_phdr *hdr) +int LUKS_read_phdr( + const char *device, + struct luks_phdr *hdr, + int require_luks_device, + struct crypt_device *ctx) { int devfd = 0, r = 0; unsigned int i; uint64_t size; char luksMagic[] = LUKS_MAGIC; + log_dbg("Reading LUKS header of size %d from device %s", + sizeof(struct luks_phdr), device); + devfd = open(device,O_RDONLY | O_DIRECT | O_SYNC); if(-1 == devfd) { - set_error(_("Can't open device: %s\n"), device); + log_err(ctx, _("Cannot open device %s.\n"), device); return -EINVAL; } if(read_blockwise(devfd, hdr, sizeof(struct luks_phdr)) < sizeof(struct luks_phdr)) { r = -EIO; } else if(memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */ - set_error(_("%s is not a LUKS partition\n"), device); + log_dbg("LUKS header not detected."); + if (require_luks_device) + log_err(ctx, _("%s is not a LUKS device.\n"), device); + else + set_error(_("%s is not a LUKS device."), device); r = -EINVAL; } else if((hdr->version = ntohs(hdr->version)) != 1) { /* Convert every uint16/32_t item from network byte order */ - set_error(_("unknown LUKS version %d\n"), hdr->version); + log_err(ctx, _("Unsupported LUKS version %d.\n"), hdr->version); r = -EINVAL; } else if (PBKDF2_HMAC_ready(hdr->hashSpec) < 0) { - set_error(_("Requested LUKS hash %s is not supported.\n"), hdr->hashSpec); + log_err(ctx, _("Requested LUKS hash %s is not supported.\n"), hdr->hashSpec); r = -EINVAL; } else { hdr->payloadOffset = ntohl(hdr->payloadOffset); @@ -115,9 +126,9 @@ int LUKS_read_phdr(const char *device, struct luks_phdr *hdr) } #ifdef BLKGETSIZE64 - if (ioctl(devfd, BLKGETSIZE64, &size) < 0 || - size < (uint64_t)hdr->payloadOffset) { - set_error(_("LUKS header detected but device %s is too small.\n"), device); + if (r == 0 && (ioctl(devfd, BLKGETSIZE64, &size) < 0 || + size < (uint64_t)hdr->payloadOffset)) { + log_err(ctx, _("LUKS header detected but device %s is too small.\n"), device); r = -EINVAL; } #endif @@ -126,16 +137,22 @@ int LUKS_read_phdr(const char *device, struct luks_phdr *hdr) return r; } -int LUKS_write_phdr(const char *device, struct luks_phdr *hdr) +int LUKS_write_phdr( + const char *device, + struct luks_phdr *hdr, + struct crypt_device *ctx) { int devfd = 0; unsigned int i; struct luks_phdr convHdr; int r; + log_dbg("Updating LUKS header of size %d on device %s", + sizeof(struct luks_phdr), device); + devfd = open(device,O_RDWR | O_DIRECT | O_SYNC); if(-1 == devfd) { - set_error(_("Can't open device %s"), device); + log_err(ctx, _("Cannot open device %s.\n"), device); return -EINVAL; } @@ -155,16 +172,20 @@ int LUKS_write_phdr(const char *device, struct luks_phdr *hdr) } r = write_blockwise(devfd, &convHdr, sizeof(struct luks_phdr)) < sizeof(struct luks_phdr) ? -EIO : 0; - + if (r) + log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device); close(devfd); + return r; } -int LUKS_generate_phdr(struct luks_phdr *header, - const struct luks_masterkey *mk, - const char *cipherName, const char *cipherMode, const char *hashSpec, - unsigned int stripes, - unsigned int alignPayload) +int LUKS_generate_phdr( + struct luks_phdr *header, + const struct luks_masterkey *mk, + const char *cipherName, const char *cipherMode, const char *hashSpec, + unsigned int stripes, + unsigned int alignPayload, + struct crypt_device *ctx) { unsigned int i=0; unsigned int blocksPerStripeSet = div_round_up(mk->keyLength*stripes,SECTOR_SIZE); @@ -187,9 +208,13 @@ int LUKS_generate_phdr(struct luks_phdr *header, header->keyBytes=mk->keyLength; + log_dbg("Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes", + header->version, header->hashSpec ,header->cipherName, header->cipherMode, + header->keyBytes); + r = getRandom(header->mkDigestSalt,LUKS_SALTSIZE); if(r < 0) { - set_error( _("Cannot create LUKS header: reading random salt failed.")); + log_err(ctx, _("Cannot create LUKS header: reading random salt failed.\n")); return r; } @@ -200,7 +225,8 @@ int LUKS_generate_phdr(struct luks_phdr *header, header->mkDigestIterations, header->mkDigest,LUKS_DIGESTSIZE); if(r < 0) { - set_error( _("Cannot create LUKS header: header digest failed (using hash %s)."), header->hashSpec); + log_err(ctx, _("Cannot create LUKS header: header digest failed (using hash %s).\n"), + header->hashSpec); return r; } @@ -218,12 +244,19 @@ int LUKS_generate_phdr(struct luks_phdr *header, uuid_generate(partitionUuid); uuid_unparse(partitionUuid, header->uuid); + log_dbg("Data offset %d, UUID %s", header->payloadOffset, header->uuid); + return 0; } -int LUKS_set_key(const char *device, unsigned int keyIndex, - const char *password, size_t passwordLen, - struct luks_phdr *hdr, struct luks_masterkey *mk) +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 crypt_device *ctx) { char derivedKey[hdr->keyBytes]; char *AfKey; @@ -231,14 +264,16 @@ int LUKS_set_key(const char *device, unsigned int keyIndex, int r; if(hdr->keyblock[keyIndex].active != LUKS_KEY_DISABLED) { - set_error( _("key %d active, purge first"), keyIndex); + log_err(ctx, _("Key slot %d active, purge first.\n"), keyIndex); return -EINVAL; } if(hdr->keyblock[keyIndex].stripes < LUKS_STRIPES) { - set_error(_("key material section %d includes too few stripes. Header manipulation?"),keyIndex); + log_err(ctx, _("Key slot %d material includes too few stripes. Header manipulation?\n"), + keyIndex); return -EINVAL; } + r = getRandom(hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE); if(r < 0) return r; @@ -257,9 +292,13 @@ int LUKS_set_key(const char *device, unsigned int keyIndex, AfKey = (char *)malloc(AFEKSize); if(AfKey == NULL) return -ENOMEM; + log_dbg("Using hash %s for AF in key slot %d, %d stripes", + hdr->hashSpec, keyIndex, hdr->keyblock[keyIndex].stripes); r = AF_split(mk->key,AfKey,mk->keyLength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); if(r < 0) goto out; + log_dbg("Updating key slot %d [0x%04x] area on device %s.", keyIndex, + hdr->keyblock[keyIndex].keyMaterialOffset << 9, device); /* Encryption via dm */ r = LUKS_encrypt_to_storage(AfKey, AFEKSize, @@ -267,16 +306,17 @@ int LUKS_set_key(const char *device, unsigned int keyIndex, derivedKey, hdr->keyBytes, device, - hdr->keyblock[keyIndex].keyMaterialOffset); + hdr->keyblock[keyIndex].keyMaterialOffset, + ctx); if(r < 0) { if(!get_error()) - set_error("Failed to write to key storage"); + log_err(ctx, _("Failed to write to key storage.\n")); goto out; } /* Mark the key as active in phdr */ hdr->keyblock[keyIndex].active = LUKS_KEY_ENABLED; - r = LUKS_write_phdr(device,hdr); + r = LUKS_write_phdr(device, hdr, ctx); if(r < 0) goto out; r = 0; @@ -286,12 +326,14 @@ out: } /* Try to open a particular key slot */ -int LUKS_open_key(const char *device, - unsigned int keyIndex, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey *mk) +int LUKS_open_key( + const char *device, + unsigned int keyIndex, + const char *password, + size_t passwordLen, + struct luks_phdr *hdr, + struct luks_masterkey *mk, + struct crypt_device *ctx) { char derivedKey[hdr->keyBytes]; char *AfKey; @@ -315,14 +357,19 @@ int LUKS_open_key(const char *device, derivedKey, hdr->keyBytes); if(r < 0) goto out; + log_dbg("Reading key slot %d area.", keyIndex); r = LUKS_decrypt_from_storage(AfKey, AFEKSize, hdr, derivedKey, hdr->keyBytes, device, - hdr->keyblock[keyIndex].keyMaterialOffset); - if(r < 0) goto out; + hdr->keyblock[keyIndex].keyMaterialOffset, + ctx); + if(r < 0) { + log_err(ctx, _("Failed to read from key storage.\n")); + goto out; + } r = AF_merge(AfKey,mk->key,mk->keyLength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); if(r < 0) goto out; @@ -334,51 +381,54 @@ int LUKS_open_key(const char *device, if(r < 0) goto out; r = (memcmp(checkHashBuf,hdr->mkDigest, LUKS_DIGESTSIZE) == 0)?0:-EPERM; + if (r >= 0) + log_std(ctx, _("Key slot %d unlocked.\n"), keyIndex); out: free(AfKey); - - if( r < 0 && !get_error()) - set_error("Failed to read from key storage."); - return r; } - /* Tries to open any key from a given LUKS device reading the header on its own */ -int LUKS_open_any_key(const char *device, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey **mk) +int LUKS_open_any_key( + const char *device, + const char *password, + size_t passwordLen, + struct luks_phdr *hdr, + struct luks_masterkey **mk, + struct crypt_device *ctx) { int r; - r = LUKS_read_phdr(device, hdr); + r = LUKS_read_phdr(device, hdr, 1, ctx); if(r < 0) return r; - return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk); + return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk, ctx); } -int LUKS_open_any_key_with_hdr(const char *device, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey **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 crypt_device *ctx) { unsigned int i; int r; *mk=LUKS_alloc_masterkey(hdr->keyBytes); for(i=0; i= LUKS_NUMKEYS || hdr.keyblock[keyIndex].active != LUKS_KEY_ENABLED) { - set_error(_("Key %d not active. Can't wipe.\n"), keyIndex); + log_err(ctx, _("Key slot %d is invalid, please select keyslot between 0 and %d.\n"), + keyIndex, LUKS_NUMKEYS - 1); r = -ENOENT; } else { /* secure deletion of key material */ @@ -465,7 +517,7 @@ int LUKS_del_key(const char *device, unsigned int keyIndex) if(r == 0) { /* mark the key as inactive in header */ hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED; - r = LUKS_write_phdr(device, &hdr); + r = LUKS_write_phdr(device, &hdr, ctx); } } @@ -478,7 +530,7 @@ int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex) unsigned int i; int r; - r = LUKS_read_phdr(device, &hdr); + r = LUKS_read_phdr(device, &hdr, 1, NULL); if(r < 0) return r; for(i = 0; i < LUKS_NUMKEYS; i++) { diff --git a/luks/luks.h b/luks/luks.h index 3e14d8b..ab5b575 100644 --- a/luks/luks.h +++ b/luks/luks.h @@ -84,57 +84,82 @@ void LUKS_dealloc_masterkey(struct luks_masterkey *mk); struct luks_masterkey *LUKS_generate_masterkey(int keylength); -int LUKS_generate_phdr(struct luks_phdr *header, - const struct luks_masterkey *mk, - const char *cipherName, const char *cipherMode, const char *hashSpec, - unsigned int stripes, - unsigned int alignPayload); - -int LUKS_read_phdr(const char *device, struct luks_phdr *hdr); - -int LUKS_write_phdr(const char *device, struct luks_phdr *hdr); - -int LUKS_set_key(const char *device, - unsigned int keyIndex, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey *mk); - -int LUKS_open_key(const char *device, - unsigned int keyIndex, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey *mk); - -int LUKS_open_any_key(const char *device, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey **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); - - -int LUKS_del_key(const char *device, unsigned int keyIndex); +int LUKS_generate_phdr( + struct luks_phdr *header, + const struct luks_masterkey *mk, + const char *cipherName, const char *cipherMode, const char *hashSpec, + unsigned int stripes, + unsigned int alignPayload, + struct crypt_device *ctx); + +int LUKS_read_phdr( + const char *device, + struct luks_phdr *hdr, + int require_luks_device, + struct crypt_device *ctx); + +int LUKS_write_phdr( + const char *device, + struct luks_phdr *hdr, + struct crypt_device *ctx); + +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 crypt_device *ctx); + +int LUKS_open_key( + const char *device, + unsigned int keyIndex, + const char *password, + size_t passwordLen, + struct luks_phdr *hdr, + struct luks_masterkey *mk, + struct crypt_device *ctx); + +int LUKS_open_any_key( + const char *device, + const char *password, + size_t passwordLen, + struct luks_phdr *hdr, + struct luks_masterkey **mk, + struct crypt_device *ctx); + +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 crypt_device *ctx); + +int LUKS_del_key( + const char *device, + unsigned int keyIndex, + struct crypt_device *ctx); + int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex); int LUKS_benchmarkt_iterations(const char *hash, unsigned int *count); -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); - -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); +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 crypt_device *ctx); + +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 crypt_device *ctx); + int LUKS_device_ready(const char *device, int mode); #endif diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 9c9599d..b660c03 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -15,7 +15,8 @@ #include "cryptsetup.h" -static int opt_verbose = 1; +static int opt_verbose = 0; +static int opt_debug = 0; static char *opt_cipher = NULL; static char *opt_hash = NULL; static int opt_verify_passphrase = 0; @@ -88,8 +89,8 @@ static int yesDialog(char *msg) int r = 1; if(isatty(0) && !opt_batch_mode) { - fprintf(stderr, "\nWARNING!\n========\n"); - fprintf(stderr, "%s\n\nAre you sure? (Type uppercase yes): ", msg); + log_std("\nWARNING!\n========\n"); + log_std("%s\n\nAre you sure? (Type uppercase yes): ", msg); if(getline(&answer, &size, stdin) == -1) { perror("getline"); free(answer); @@ -129,12 +130,13 @@ static void show_status(int errcode) { char error[256]; - if(!errcode) { - fprintf(stderr, _("Command successful.\n")); - return; + if(!errcode && opt_verbose) { + log_std(_("Command successful.\n")); + return; } crypt_get_error(error, sizeof(error)); + if (!opt_verbose) { char *error_ = strerror_r(errcode, error, sizeof(error)); if (error_ != error) { @@ -143,11 +145,11 @@ static void show_status(int errcode) } } - fprintf(stderr, _("Command failed")); + log_err(_("Command failed")); if (*error) - fprintf(stderr, ": %s\n", error); + log_err(": %s\n", error); else - fputs(".\n", stderr); + log_err(".\n"); return; } @@ -173,7 +175,7 @@ static int action_create(int reload) int r; if(reload) - fprintf(stderr, _("The reload action is deprecated. Please use \"dmsetup reload\" in case you really need this functionality.\nWARNING: do not use reload to touch LUKS devices. If that is the case, hit Ctrl-C now.\n")); + log_err(_("The reload action is deprecated. Please use \"dmsetup reload\" in case you really need this functionality.\nWARNING: do not use reload to touch LUKS devices. If that is the case, hit Ctrl-C now.\n")); if (options.hash && strcmp(options.hash, "plain") == 0) options.hash = NULL; @@ -225,19 +227,19 @@ static int action_status(int arg) if (r == 0) { /* inactive */ - printf("%s/%s is inactive.\n", crypt_get_dir(), options.name); + log_std("%s/%s is inactive.\n", crypt_get_dir(), options.name); r = 1; } else { /* active */ - printf("%s/%s is active:\n", crypt_get_dir(), options.name); - printf(" cipher: %s\n", options.cipher); - printf(" keysize: %d bits\n", options.key_size * 8); - printf(" device: %s\n", options.device); - printf(" offset: %" PRIu64 " sectors\n", options.offset); - printf(" size: %" PRIu64 " sectors\n", options.size); + log_std("%s/%s is active:\n", crypt_get_dir(), options.name); + log_std(" cipher: %s\n", options.cipher); + log_std(" keysize: %d bits\n", options.key_size * 8); + log_std(" device: %s\n", options.device); + log_std(" offset: %" PRIu64 " sectors\n", options.offset); + log_std(" size: %" PRIu64 " sectors\n", options.size); if (options.skip) - printf(" skipped: %" PRIu64 " sectors\n", options.skip); - printf(" mode: %s\n", (options.flags & CRYPT_FLAG_READONLY) + log_std(" skipped: %" PRIu64 " sectors\n", options.skip); + log_std(" mode: %s\n", (options.flags & CRYPT_FLAG_READONLY) ? "readonly" : "read/write"); crypt_put_options(&options); r = 0; @@ -385,7 +387,7 @@ static void usage(poptContext popt_context, int exitcode, { poptPrintUsage(popt_context, stderr, 0); if (error) - fprintf(stderr, "%s: %s\n", more, error); + log_err("%s: %s\n", more, error); exit(exitcode); } @@ -395,17 +397,17 @@ static void help(poptContext popt_context, enum poptCallbackReason reason, if (key->shortName == '?') { struct action_type *action; - fprintf(stdout, "%s\n",PACKAGE_STRING); + log_std("%s\n",PACKAGE_STRING); poptPrintHelp(popt_context, stdout, 0); - printf(_("\n" + log_std(_("\n" " is one of:\n")); for(action = action_types; action->type; action++) - printf("\t%s %s - %s\n", action->type, _(action->arg_desc), _(action->desc)); - - printf(_("\n" + log_std("\t%s %s - %s\n", action->type, _(action->arg_desc), _(action->desc)); + + log_std(_("\n" " is the device to create under %s\n" " is the encrypted device\n" " is the LUKS key slot number to modify\n" @@ -416,12 +418,27 @@ static void help(poptContext popt_context, enum poptCallbackReason reason, usage(popt_context, 0, NULL, NULL); } +void set_debug_level(int level); + +static void _dbg_version_and_cmd(int argc, char **argv) +{ + int i; + + log_std("# %s %s processing \"", PACKAGE_NAME, PACKAGE_VERSION); + for (i = 0; i < argc; i++) { + if (i) + log_std(" "); + log_std(argv[i]); + } + log_std("\"\n"); +} + static int run_action(struct action_type *action) { int r; if (dm_init(NULL, action->required_dm_backend) < 1) { - fprintf(stderr,_("Cannot communicate with device-mapper. Is dm_mod kernel module loaded?\n")); + log_err("Cannot communicate with device-mapper. Is dm_mod kernel module loaded?\n"); return -ENOSYS; } @@ -454,6 +471,7 @@ int main(int argc, char **argv) static struct poptOption popt_options[] = { { NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_help_options, 0, N_("Help options:"), NULL }, { "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 0, N_("Shows more detailed error messages"), NULL }, + { "debug", '\0', POPT_ARG_NONE, &opt_debug, 0, N_("Show debug messsgages"), NULL }, { "cipher", 'c', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &opt_cipher, 0, N_("The cipher used to encrypt the disk (see /proc/crypto)"), NULL }, { "hash", 'h', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &opt_hash, 0, N_("The hash used to create the encryption key from the passphrase"), NULL }, { "verify-passphrase", 'y', POPT_ARG_NONE, &opt_verify_passphrase, 0, N_("Verifies the passphrase by asking for it twice"), NULL }, @@ -468,10 +486,10 @@ int main(int argc, char **argv) N_("msecs") }, { "batch-mode", 'q', POPT_ARG_NONE, &opt_batch_mode, 0, N_("Do not ask for confirmation"), NULL }, { "version", '\0', POPT_ARG_NONE, &opt_version_mode, 0, N_("Print package version"), NULL }, - { "timeout", 't', POPT_ARG_INT, &opt_timeout, 0, N_("Timeout for interactive passphrase prompt (in seconds)"), N_("secs") }, - { "tries", 'T', POPT_ARG_INT, &opt_tries, 0, N_("How often the input of the passphrase can be retried"), NULL }, - { "align-payload", '\0', POPT_ARG_INT, &opt_align_payload, 0, N_("Align payload at sector boundaries - for luksFormat"), N_("SECTORS") }, - { "non-exclusive", '\0', POPT_ARG_NONE, &opt_non_exclusive, 0, N_("Allows non-exclusive access for luksOpen, WARNING see manpage."), NULL }, + { "timeout", 't', POPT_ARG_INT, &opt_timeout, 0, N_("Timeout for interactive passphrase prompt (in seconds)"), N_("secs") }, + { "tries", 'T', POPT_ARG_INT, &opt_tries, 0, N_("How often the input of the passphrase canbe retried"), NULL }, + { "align-payload", '\0', POPT_ARG_INT, &opt_align_payload, 0, N_("Align payload at sector boundaries - for luksFormat"), N_("SECTORS") }, + { "non-exclusive", '\0', POPT_ARG_NONE, &opt_non_exclusive, 0, N_("Allows non-exclusive access for luksOpen, WARNING see manpage."), NULL }, POPT_TABLEEND }; poptContext popt_context; @@ -480,6 +498,8 @@ int main(int argc, char **argv) int r; const char *null_action_argv[] = {NULL}; + set_default_log(cmdLineLog); + setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -517,15 +537,15 @@ int main(int argc, char **argv) usage(popt_context, 1, poptStrerror(r), poptBadOption(popt_context, POPT_BADOPTION_NOALIAS)); if (opt_version_mode) { - printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION); + log_std("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION); exit(0); } - + if (opt_key_size % 8) usage(popt_context, 1, _("Key size must be a multiple of 8 bits"), poptGetInvocationName(popt_context)); - + if (!(aname = (char *)poptGetArg(popt_context))) usage(popt_context, 1, _("Argument missing."), poptGetInvocationName(popt_context)); @@ -541,7 +561,7 @@ int main(int argc, char **argv) /* Make return values of poptGetArgs more consistent in case of remaining argc = 0 */ if(!action_argv) action_argv = null_action_argv; - + /* Count args, somewhat unnice, change? */ while(action_argv[action_argc] != NULL) action_argc++; @@ -553,5 +573,11 @@ int main(int argc, char **argv) poptGetInvocationName(popt_context)); } + if (opt_debug) { + opt_verbose = 1; + crypt_set_debug_level(-1); + _dbg_version_and_cmd(argc, argv); + } + return run_action(action); } diff --git a/src/cryptsetup.h b/src/cryptsetup.h index 7e7afa6..1ef75b7 100644 --- a/src/cryptsetup.h +++ b/src/cryptsetup.h @@ -33,11 +33,21 @@ #define DEFAULT_KEY_SIZE 256 #define DEFAULT_LUKS_KEY_SIZE 128 +#define MAX_CIPHER_LEN 32 + /* Helper funcions provided by internal libcryptsetup objects */ struct crypt_device; +void crypt_set_debug_level(int level); +void set_default_log(void (*log)(int class, char *msg)); +void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...); +#define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x) +#define log_std(x...) logger(NULL, CRYPT_LOG_NORMAL, __FILE__, __LINE__, x) +#define log_err(x...) logger(NULL, CRYPT_LOG_ERROR, __FILE__, __LINE__, x) + extern int memlock_inc(struct crypt_device *ctx); extern int memlock_dec(struct crypt_device *ctx); extern int dm_init(struct crypt_device *context, int check_kernel); extern void dm_exit(void); +extern int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode); #endif /* CRYPTSETUP_H */