* Add log macros and make logging modre consitent.
authorMilan Broz <gmazyland@gmail.com>
Sun, 30 Aug 2009 18:07:17 +0000 (18:07 +0000)
committerMilan Broz <gmazyland@gmail.com>
Sun, 30 Aug 2009 18:07:17 +0000 (18:07 +0000)
* Move command successful messages to verbose level.
* Introduce --debug parameter.

Signed-off-by: Milan Broz <mbroz@redhat.com>
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@92 36d66b0a-2a48-0410-832c-cd162a569da5

ChangeLog
lib/internal.h
lib/libcryptsetup.h
lib/libdevmapper.c
lib/setup.c
lib/utils.c
luks/keyencryption.c
luks/keymanage.c
luks/luks.h
src/cryptsetup.c
src/cryptsetup.h

index a2c15ef..e12935f 100644 (file)
--- 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  <mbroz@redhat.com>
        * Fix PBKDF2 speed calculation for large passhrases.
index f3be662..25163b2 100644 (file)
@@ -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);
index f87b736..afee144 100644 (file)
@@ -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);
index 9db687e..7d72a2f 100644 (file)
@@ -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);
index f1989c5..dc4c2e7 100644 (file)
 #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;i<LUKS_NUMKEYS;i++) {
+       log_std(cd, "LUKS header information for %s\n\n", options->device);
+       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();
index a425b69..890e620 100644 (file)
@@ -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;
 }
index 7bd8913..f32729b 100644 (file)
@@ -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);
 }
index 20604bf..f095afa 100644 (file)
@@ -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; i++) {
-               r = LUKS_open_key(device, i, password, passwordLen, hdr, *mk);
+               r = LUKS_open_key(device, i, password, passwordLen, hdr, *mk, ctx);
                if(r == 0)
                        return i;
 
-               /* Do not retry for errors that are no -EPERM or -ENOENT, former meaning password wrong, latter key slot inactive */
+               /* Do not retry for errors that are no -EPERM or -ENOENT,
+                  former meaning password wrong, latter key slot inactive */
                if ((r != -EPERM) && (r != -ENOENT)) 
                        return r;
        }
        /* Warning, early returns above */
+       log_err(ctx, _("No key available with this passphrase.\n"));
        return -EPERM;
 }
 
@@ -417,10 +467,8 @@ static int wipe(const char *device, unsigned int from, unsigned int to)
        int r = 0;
 
        devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
-       if(devfd == -1) {
-               set_error(_("Can't open device %s"), device);
+       if(devfd == -1)
                return -EINVAL;
-       }
 
        buffer = (char *) malloc(bufLen);
        if(!buffer) return -ENOMEM;
@@ -443,17 +491,21 @@ static int wipe(const char *device, unsigned int from, unsigned int to)
        return r;
 }
 
-int LUKS_del_key(const char *device, unsigned int keyIndex)
+int LUKS_del_key(
+       const char *device,
+       unsigned int keyIndex,
+       struct crypt_device *ctx)
 {
        struct luks_phdr hdr;
        unsigned int startOffset, endOffset, stripesLen;
        int r;
 
-       r = LUKS_read_phdr(device, &hdr);
+       r = LUKS_read_phdr(device, &hdr, 1, ctx);
        if(r != 0) {
                /* placeholder */
        } else if(keyIndex >= 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++) {
index 3e14d8b..ab5b575 100644 (file)
@@ -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
index 9c9599d..b660c03 100644 (file)
@@ -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"
                         "<action> 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"
                         "<name> is the device to create under %s\n"
                         "<device> is the encrypted device\n"
                         "<key slot> 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 <n> 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 <n> 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 <action> 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);
 }
index 7e7afa6..1ef75b7 100644 (file)
 #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 */