add support for encrypted block devices
authorDavid Zeuthen <davidz@redhat.com>
Sat, 22 Mar 2008 20:32:39 +0000 (16:32 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Sat, 22 Mar 2008 20:32:39 +0000 (16:32 -0400)
The namespace is abstract and I've implemented this for dm-crypt for
now (not sure what else there is to support on Linux).

This relies on some device-mapper patches, see

 https://bugzilla.redhat.com/show_bug.cgi?id=438604

that needs to go upstream. Next patch will include methods for
locking, unlocking and managing keys.

src/devkit-disks-daemon.c
src/devkit-disks-device-private.h
src/devkit-disks-device.c
src/org.freedesktop.DeviceKit.Disks.Device.xml
tools/devkit-disks.c

index 3c195d5..e3f112e 100644 (file)
@@ -1073,6 +1073,11 @@ devkit_disks_daemon_enumerate_devices (DevkitDisksDaemon     *daemon,
 {
         GPtrArray *object_paths;
 
+        /* TODO: enumerate in the right order wrt. dm/md..
+         *
+         * see also gdu_pool_new() in src/gdu-pool.c in g-d-u
+         */
+
         object_paths = g_ptr_array_new ();
         g_hash_table_foreach (daemon->priv->map_native_path_to_device, enumerate_cb, object_paths);
         dbus_g_method_return (context, object_paths);
index eec886d..29a006c 100644 (file)
@@ -59,6 +59,7 @@ struct DevkitDisksDevicePrivate
                 gboolean device_is_removable;
                 gboolean device_is_media_available;
                 gboolean device_is_drive;
+                gboolean device_is_crypto_cleartext;
                 guint64 device_size;
                 guint64 device_block_size;
                 gboolean device_is_mounted;
@@ -90,6 +91,8 @@ struct DevkitDisksDevicePrivate
                 char *drive_model;
                 char *drive_revision;
                 char *drive_serial;
+
+                char *crypto_cleartext_slave;
         } info;
 };
 
index 7d79352..77d1304 100644 (file)
@@ -79,6 +79,7 @@ enum
         PROP_DEVICE_IS_REMOVABLE,
         PROP_DEVICE_IS_MEDIA_AVAILABLE,
         PROP_DEVICE_IS_DRIVE,
+        PROP_DEVICE_IS_CRYPTO_CLEARTEXT,
         PROP_DEVICE_SIZE,
         PROP_DEVICE_BLOCK_SIZE,
         PROP_DEVICE_IS_MOUNTED,
@@ -114,6 +115,8 @@ enum
         PROP_PARTITION_TABLE_OFFSETS,
         PROP_PARTITION_TABLE_SIZES,
 
+        PROP_CRYPTO_CLEARTEXT_SLAVE,
+
         PROP_DRIVE_VENDOR,
         PROP_DRIVE_MODEL,
         PROP_DRIVE_REVISION,
@@ -236,6 +239,9 @@ get_property (GObject         *object,
        case PROP_DEVICE_IS_DRIVE:
                g_value_set_boolean (value, device->priv->info.device_is_drive);
                break;
+       case PROP_DEVICE_IS_CRYPTO_CLEARTEXT:
+               g_value_set_boolean (value, device->priv->info.device_is_crypto_cleartext);
+               break;
        case PROP_DEVICE_SIZE:
                g_value_set_uint64 (value, device->priv->info.device_size);
                break;
@@ -334,6 +340,13 @@ get_property (GObject         *object,
                g_value_set_boxed (value, device->priv->info.partition_table_sizes);
                break;
 
+       case PROP_CRYPTO_CLEARTEXT_SLAVE:
+                if (device->priv->info.crypto_cleartext_slave != NULL)
+                        g_value_set_boxed (value, device->priv->info.crypto_cleartext_slave);
+                else
+                        g_value_set_boxed (value, "/");
+               break;
+
        case PROP_DRIVE_VENDOR:
                g_value_set_string (value, device->priv->info.drive_vendor);
                break;
@@ -437,6 +450,10 @@ devkit_disks_device_class_init (DevkitDisksDeviceClass *klass)
                 g_param_spec_boolean ("device-is-drive", NULL, NULL, FALSE, G_PARAM_READABLE));
         g_object_class_install_property (
                 object_class,
+                PROP_DEVICE_IS_CRYPTO_CLEARTEXT,
+                g_param_spec_boolean ("device-is-crypto-cleartext", NULL, NULL, FALSE, G_PARAM_READABLE));
+        g_object_class_install_property (
+                object_class,
                 PROP_DEVICE_SIZE,
                 g_param_spec_uint64 ("device-size", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE));
         g_object_class_install_property (
@@ -568,6 +585,11 @@ devkit_disks_device_class_init (DevkitDisksDeviceClass *klass)
 
         g_object_class_install_property (
                 object_class,
+                PROP_CRYPTO_CLEARTEXT_SLAVE,
+                g_param_spec_boxed ("crypto-cleartext-slave", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE));
+
+        g_object_class_install_property (
+                object_class,
                 PROP_DRIVE_VENDOR,
                 g_param_spec_string ("drive-vendor", NULL, NULL, NULL, G_PARAM_READABLE));
         g_object_class_install_property (
@@ -779,6 +801,8 @@ free_info (DevkitDisksDevice *device)
 
         g_free (device->priv->info.partition_table_scheme);
 
+        g_free (device->priv->info.crypto_cleartext_slave);
+
         g_free (device->priv->info.drive_vendor);
         g_free (device->priv->info.drive_model);
         g_free (device->priv->info.drive_revision);
@@ -820,6 +844,47 @@ _dupv8 (const char *s)
         }
 }
 
+#if 0
+// Oh well, may come in handy later
+static char *
+sysfs_resolve_link (const char *sysfs_path, const char *name)
+{
+        char *full_path;
+        char link_path[PATH_MAX];
+        char resolved_path[PATH_MAX];
+        ssize_t num;
+        gboolean found_it;
+
+        found_it = FALSE;
+
+        full_path = g_build_filename (sysfs_path, name, NULL);
+
+        //g_warning ("name='%s'", name);
+        //g_warning ("full_path='%s'", full_path);
+        num = readlink (full_path, link_path, sizeof (link_path) - 1);
+        if (num != -1) {
+                char *absolute_path;
+
+                link_path[num] = '\0';
+
+                //g_warning ("link_path='%s'", link_path);
+                absolute_path = g_build_filename (sysfs_path, link_path, NULL);
+                //g_warning ("absolute_path='%s'", absolute_path);
+                if (realpath (absolute_path, resolved_path) != NULL) {
+                        //g_warning ("resolved_path='%s'", resolved_path);
+                        found_it = TRUE;
+                }
+                g_free (absolute_path);
+        }
+        g_free (full_path);
+
+        if (found_it)
+                return g_strdup (resolved_path);
+        else
+                return NULL;
+}
+#endif
+
 static devkit_bool_t
 update_info_properties_cb (DevKitInfo *info, const char *key, void *user_data)
 {
@@ -914,6 +979,26 @@ update_info_properties_cb (DevKitInfo *info, const char *key, void *user_data)
                         }
                 }
 
+        } else if (strcmp (key, "DM_TARGET_TYPES") == 0) {
+                if (strcmp (devkit_info_property_get_string (info, key), "crypt") == 0) {
+                        char *slaves_path;
+                        GDir *slaves_dir;
+                        const char *slave_name;
+
+                        /* we're a dm-crypt target, find our slave */
+                        slaves_path = g_build_filename (device->priv->native_path, "slaves", NULL);
+                        if((slaves_dir = g_dir_open (slaves_path, 0, NULL)) != NULL) {
+                                while ((slave_name = g_dir_read_name (slaves_dir)) != NULL) {
+                                        device->priv->info.device_is_crypto_cleartext = TRUE;
+                                        device->priv->info.crypto_cleartext_slave =
+                                                compute_object_path_from_basename (slave_name);
+                                }
+                                g_dir_close (slaves_dir);
+                        }
+                        g_free (slaves_path);
+
+                }
+
         } else if (strcmp (key, "MEDIA_AVAILABLE") == 0) {
                 if (device->priv->info.device_is_removable) {
                         device->priv->info.device_is_media_available = devkit_info_property_get_bool (info, key);
index e58aad1..208d934 100644 (file)
     <property name="device-is-media-available" type="b" access="read"/>
     <property name="device-is-drive" type="b" access="read"/>
     <property name="device-is-mounted" type="b" access="read"/>
+    <property name="device-is-crypto-cleartext" type="b" access="read"/>
     <property name="device-mount-path" type="s" access="read"/>
     <property name="device-size" type="t" access="read"/>
     <property name="device-block-size" type="t" access="read"/>
     <property name="id-uuid" type="s" access="read"/>
     <property name="id-label" type="s" access="read"/>
 
+    <!-- The following properties are only set if the device is
+         a clear text device for an encrypted block device (see
+         the property 'device-is-crypto-cleartext').
+
+         The property 'crypto-cleartext-slave' is a reference to the
+         encrypted block device.
+      -->
+    <property name="crypto-cleartext-slave" type="o" access="read"/>
+
     <!-- the following properties are only set if the device is
          a partition (see 'device-is-partition'). Known values
          for the partitioning scheme are
index e8e84da..f04b5b6 100644 (file)
@@ -448,6 +448,7 @@ typedef struct
         gboolean device_is_removable;
         gboolean device_is_media_available;
         gboolean device_is_drive;
+        gboolean device_is_crypto_cleartext;
         gboolean device_is_mounted;
         char    *device_mount_path;
         guint64  device_size;
@@ -483,6 +484,8 @@ typedef struct
         GArray  *partition_table_offsets;
         GArray  *partition_table_sizes;
 
+        char    *crypto_cleartext_slave;
+
         char    *drive_vendor;
         char    *drive_model;
         char    *drive_revision;
@@ -513,6 +516,8 @@ collect_props (const char *key, const GValue *value, DeviceProperties *props)
                 props->device_is_media_available = g_value_get_boolean (value);
         else if (strcmp (key, "device-is-drive") == 0)
                 props->device_is_drive = g_value_get_boolean (value);
+        else if (strcmp (key, "device-is-crypto-cleartext") == 0)
+                props->device_is_crypto_cleartext = g_value_get_boolean (value);
         else if (strcmp (key, "device-is-mounted") == 0)
                 props->device_is_mounted = g_value_get_boolean (value);
         else if (strcmp (key, "device-mount-path") == 0)
@@ -585,6 +590,9 @@ collect_props (const char *key, const GValue *value, DeviceProperties *props)
                 props->partition_table_sizes = g_value_get_boxed (&dest_value);
         }
 
+        else if (strcmp (key, "crypto-cleartext-slave") == 0)
+                props->crypto_cleartext_slave = g_strdup (g_value_get_boxed (value));
+
         else if (strcmp (key, "drive-vendor") == 0)
                 props->drive_vendor = g_strdup (g_value_get_string (value));
         else if (strcmp (key, "drive-model") == 0)
@@ -664,6 +672,7 @@ device_properties_free (DeviceProperties *props)
         g_free (props->partition_table_scheme);
         g_array_free (props->partition_table_offsets, TRUE);
         g_array_free (props->partition_table_sizes, TRUE);
+        g_free (props->crypto_cleartext_slave);
         g_free (props->drive_model);
         g_free (props->drive_vendor);
         g_free (props->drive_revision);
@@ -736,6 +745,10 @@ do_show_info (const char *object_path)
         g_print ("  version:       %s\n", props->id_version);
         g_print ("  uuid:          %s\n", props->id_uuid);
         g_print ("  label:         %s\n", props->id_label);
+        if (props->device_is_crypto_cleartext) {
+                g_print ("  cleartext crypto device:\n");
+                g_print ("    backed by:   %s\n", props->crypto_cleartext_slave);
+        }
         if (props->device_is_partition_table) {
                 g_print ("  partition table:\n");
                 g_print ("    scheme:      %s\n", props->partition_table_scheme);