Enhance status of active device.
authorMilan Broz <gmazyland@gmail.com>
Sat, 9 Jun 2012 16:28:00 +0000 (18:28 +0200)
committerMilan Broz <gmazyland@gmail.com>
Sat, 9 Jun 2012 16:28:00 +0000 (18:28 +0200)
lib/libcryptsetup.h
lib/libcryptsetup.sym
lib/libdevmapper.c
lib/setup.c
lib/utils_dm.h
src/Makefile.am
src/veritysetup.c

index f281a9b..3c67974 100644 (file)
@@ -370,6 +370,7 @@ struct crypt_params_loopaes {
 struct crypt_params_verity {
        const char *hash_name;     /**< hash function */
        const char *data_device;   /**< data_device (CRYPT_VERITY_CREATE_HASH) */
+       const char *hash_device;   /**< hash_device (output only) */
        const char *salt;          /**< salt */
        uint64_t salt_size;        /**< salt size (in bytes) */
        uint32_t data_block_size;  /**< data block size (in bytes) */
@@ -672,6 +673,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
 #define CRYPT_ACTIVATE_ALLOW_DISCARDS (1 << 3)
 /** skip global udev rules in activation ("private device"), input only */
 #define CRYPT_ACTIVATE_PRIVATE (1 << 4)
+/** corruption detected (verity), output only */
+#define CRYPT_ACTIVATE_CORRUPTED (1 << 5)
 
 /**
  * Active device runtime attributes
@@ -924,6 +927,18 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd);
 int crypt_get_volume_key_size(struct crypt_device *cd);
 
 /**
+ * Get device paramaters for CRYPT_VERITY device
+ *
+ * @param cd crypt device handle
+ * @param vp verity device info
+ *
+ * @e 0 on success or negative errno value otherwise.
+ *
+ */
+int crypt_get_verity_info(struct crypt_device *cd,
+       struct crypt_params_verity *vp);
+
+/**
  * @addtogroup keyslot
  * @{
  *
index 88feb22..4f054f2 100644 (file)
@@ -46,6 +46,7 @@ CRYPTSETUP_1.0 {
                crypt_get_iv_offset;
                crypt_get_volume_key_size;
                crypt_get_device_name;
+               crypt_get_verity_info;
 
                crypt_get_type;
                crypt_get_active_device;
index c82c0f5..16a863d 100644 (file)
@@ -959,11 +959,19 @@ int dm_query_device(const char *name, uint32_t get_flags,
        if (!target_type || start != 0 || next)
                goto out;
 
-       if (!strcmp(target_type, DM_CRYPT_TARGET))
+       if (!strcmp(target_type, DM_CRYPT_TARGET)) {
                r = _dm_query_crypt(get_flags, &dmi, params, dmd);
-       else if (!strcmp(target_type, DM_VERITY_TARGET))
+       } else if (!strcmp(target_type, DM_VERITY_TARGET)) {
                r = _dm_query_verity(get_flags, &dmi, params, dmd);
-       else
+               if (r < 0)
+                       goto out;
+               r = dm_status_verity_ok(name);
+               if (r < 0)
+                       goto out;
+               if (r == 0)
+                       dmd->flags |= CRYPT_ACTIVATE_CORRUPTED;
+               r = 0;
+       } else
                r = -EINVAL;
 
        if (r < 0)
index 87afb6f..9637ace 100644 (file)
@@ -772,13 +772,16 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
                cd->verity_root_hash = NULL;
                cd->verity_hdr.hash_name = params.hash_name;
                cd->verity_hdr.data_device = NULL;
+               cd->verity_hdr.hash_device = NULL;
                cd->verity_hdr.data_block_size = params.data_block_size;
                cd->verity_hdr.hash_block_size = params.hash_block_size;
-               cd->verity_hdr.hash_area_offset = params.hash_area_offset;
+               cd->verity_hdr.hash_area_offset = dmd.u.verity.hash_offset;
                cd->verity_hdr.version = params.version;
                cd->verity_hdr.flags = params.flags;
                cd->verity_hdr.salt_size = params.salt_size;
                cd->verity_hdr.salt = params.salt;
+               if (!(cd->metadata_device = strdup(dmd.u.verity.hash_device)))
+                       r = -ENOMEM;
        }
 out:
        free(CONST_CAST(void*)dmd.u.verity.hash_device);
@@ -2397,6 +2400,26 @@ const char *crypt_get_type(struct crypt_device *cd)
        return cd->type;
 }
 
+int crypt_get_verity_info(struct crypt_device *cd,
+       struct crypt_params_verity *vp)
+{
+       if (!isVERITY(cd->type) || !vp)
+               return -EINVAL;
+
+       vp->data_device = cd->device;
+       vp->hash_device = mdata_device(cd);
+       vp->hash_name = cd->verity_hdr.hash_name;
+       vp->salt = cd->verity_hdr.salt;
+       vp->salt_size = cd->verity_hdr.salt_size;
+       vp->data_block_size = cd->verity_hdr.data_block_size;
+       vp->hash_block_size = cd->verity_hdr.hash_block_size;
+       vp->data_size = cd->verity_hdr.data_size;
+       vp->hash_area_offset = cd->verity_hdr.hash_area_offset;
+       vp->version = cd->verity_hdr.version;
+       vp->flags = cd->verity_hdr.flags & CRYPT_VERITY_NO_HEADER;
+       return 0;
+}
+
 int crypt_get_active_device(struct crypt_device *cd __attribute__((unused)),
                            const char *name,
                            struct crypt_active_device *cad)
@@ -2408,7 +2431,7 @@ int crypt_get_active_device(struct crypt_device *cd __attribute__((unused)),
        if (r < 0)
                return r;
 
-       if (dmd.target != DM_CRYPT)
+       if (dmd.target != DM_CRYPT && dmd.target != DM_VERITY)
                return -ENOTSUP;
 
        cad->offset     = dmd.u.crypt.offset;
index 5a0756e..ea64b9e 100644 (file)
@@ -72,7 +72,7 @@ struct crypt_dm_active_device {
                const char *root_hash;
                uint32_t root_hash_size;
 
-               uint64_t hash_offset;   /* hash offset (not header) */
+               uint64_t hash_offset;   /* hash offset in blocks (not header) */
                struct crypt_params_verity *vp;
        } verity;
        } u;
index c35a5d1..473120c 100644 (file)
@@ -41,7 +41,9 @@ endif
 if VERITYSETUP
 
 veritysetup_SOURCES = \
-       veritysetup.c
+       $(top_builddir)/lib/utils_loop.c        \
+       veritysetup.c                           \
+       cryptsetup.h
 
 veritysetup_LDADD = \
        $(top_builddir)/lib/libcryptsetup.la    \
index e672537..591c181 100644 (file)
 #include <stdarg.h>
 #include <errno.h>
 #include <string.h>
+#include <inttypes.h>
 #include <popt.h>
 #include <limits.h>
+#include <sys/stat.h>
 
 #include "cryptsetup.h"
 
@@ -212,8 +214,6 @@ static int _activate(const char *dm_device,
                                         crypt_get_volume_key_size(cd),
                                         activate_flags);
 out:
-       if (!r)
-               crypt_dump(cd);
        crypt_free(cd);
        return r;
 }
@@ -250,13 +250,91 @@ static int action_remove(int arg)
 
 static int action_status(int arg)
 {
+       crypt_status_info ci;
+       struct crypt_active_device cad;
+       struct crypt_params_verity vp = {};
        struct crypt_device *cd = NULL;
-       int r;
+       struct stat st;
+       char *backing_file;
+       int i, path = 0, r = 0;
 
-       r = crypt_init_by_name_and_header(&cd, action_argv[0], NULL);
-       if (!r)
-               r = crypt_dump(cd);
+       /* perhaps a path, not a dm device name */
+       if (strchr(action_argv[0], '/') && !stat(action_argv[0], &st))
+               path = 1;
+
+       ci = crypt_status(NULL, action_argv[0]);
+       switch (ci) {
+       case CRYPT_INVALID:
+               r = -EINVAL;
+               break;
+       case CRYPT_INACTIVE:
+               if (path)
+                       log_std("%s is inactive.\n", action_argv[0]);
+               else
+                       log_std("%s/%s is inactive.\n", crypt_get_dir(), action_argv[0]);
+               r = -ENODEV;
+               break;
+       case CRYPT_ACTIVE:
+       case CRYPT_BUSY:
+               if (path)
+                       log_std("%s is active%s.\n", action_argv[0],
+                               ci == CRYPT_BUSY ? " and is in use" : "");
+               else
+                       log_std("%s/%s is active%s.\n", crypt_get_dir(), action_argv[0],
+                               ci == CRYPT_BUSY ? " and is in use" : "");
+
+               r = crypt_init_by_name_and_header(&cd, action_argv[0], NULL);
+               if (r < 0 || !crypt_get_type(cd))
+                       goto out;
+
+               log_std("  type:        %s\n", crypt_get_type(cd));
+
+               r = crypt_get_active_device(cd, action_argv[0], &cad);
+               if (r < 0)
+                       goto out;
+
+               log_std("  status:      %s\n",
+                       cad.flags & CRYPT_ACTIVATE_CORRUPTED ? "corrupted" : "verified");
+
+               r = crypt_get_verity_info(cd, &vp);
+               if (r < 0)
+                       goto out;
+
+               log_std("  version:     %u\n", vp.version);
+               log_std("  data block:  %u\n", vp.data_block_size);
+               log_std("  hash block:  %u\n", vp.hash_block_size);
+               log_std("  hash name:   %s\n", vp.hash_name);
+               log_std("  salt:        ");
+               if (vp.salt_size)
+                       for(i = 0; i < vp.salt_size; i++)
+                               log_std("%02hhx", (const char)vp.salt[i]);
+               else
+                       log_std("-");
+               log_std("\n");
+
+               log_std("  data device: %s\n", vp.data_device);
+               if (crypt_loop_device(vp.data_device)) {
+                       backing_file = crypt_loop_backing_file(vp.data_device);
+                       log_std("  data loop:   %s\n", backing_file);
+                       free(backing_file);
+               }
+               log_std("  size:        %" PRIu64 " sectors\n", cad.size);
+               log_std("  mode:        %s\n", cad.flags & CRYPT_ACTIVATE_READONLY ?
+                                          "readonly" : "read/write");
+
+               log_std("  hash device: %s\n", vp.hash_device);
+               if (crypt_loop_device(vp.hash_device)) {
+                       backing_file = crypt_loop_backing_file(vp.hash_device);
+                       log_std("  hash loop:   %s\n", backing_file);
+                       free(backing_file);
+               }
+               log_std("  hash offset: %" PRIu64 " sectors\n",
+                       vp.hash_area_offset * vp.hash_block_size / 512);
+       }
+out:
        crypt_free(cd);
+       if (r == -ENOTSUP)
+               r = 0;
        return r;
 }