[Libguestfs] [libguestfs-common PATCH v2 05/12] options: wrap each passphrase from get_keys() into a struct

Laszlo Ersek lersek at redhat.com
Thu Jun 30 12:20:21 UTC 2022


For adding Clevis support later in this patch set, replace the (char *)
element type of the get_keys() result array with a new structure: "struct
matching_key". No behavioral changes.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1809453
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
Reviewed-by: Richard W.M. Jones <rjones at redhat.com>
---

Notes:
    v2:
    - pick up Rich's R-b

 options/options.h | 13 +++++++--
 options/decrypt.c |  6 ++--
 options/keys.c    | 30 ++++++++++++--------
 3 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/options/options.h b/options/options.h
index d7a3aeff6f41..9bd812525d8a 100644
--- a/options/options.h
+++ b/options/options.h
@@ -132,10 +132,17 @@ struct key_store_key {
 struct key_store {
   struct key_store_key *keys;
   size_t nr_keys;
 };
 
+/* A key matching a particular ID (pathname of the libguestfs device node that
+ * stands for the encrypted block device, or LUKS UUID).
+ */
+struct matching_key {
+  char *passphrase;
+};
+
 /* in config.c */
 extern void parse_config (void);
 
 /* in decrypt.c */
 extern void inspect_do_decrypt (guestfs_h *g, struct key_store *ks);
@@ -149,13 +156,13 @@ extern void inspect_mount_root (guestfs_h *g, const char *root);
 #define inspect_mount() inspect_mount_handle (g, ks)
 extern void print_inspect_prompt (void);
 
 /* in key.c */
 extern char *read_key (const char *param);
-extern char **get_keys (struct key_store *ks, const char *device, const char *uuid,
-                        size_t *nr_matches);
-extern void free_keys (char **keys, size_t nr_matches);
+extern struct matching_key *get_keys (struct key_store *ks, const char *device,
+                                      const char *uuid, size_t *nr_matches);
+extern void free_keys (struct matching_key *keys, size_t nr_matches);
 extern struct key_store *key_store_add_from_selector (struct key_store *ks, const char *selector);
 extern struct key_store *key_store_import_key (struct key_store *ks, const struct key_store_key *key);
 extern void free_key_store (struct key_store *ks);
 
 /* in options.c */
diff --git a/options/decrypt.c b/options/decrypt.c
index c25b5888d8b4..421a38c2a11f 100644
--- a/options/decrypt.c
+++ b/options/decrypt.c
@@ -122,11 +122,11 @@ decrypt_mountables (guestfs_h *g, const char * const *mountables,
   const char *mountable;
 
   while ((mountable = *mnt_scan++) != NULL) {
     CLEANUP_FREE char *type = NULL;
     CLEANUP_FREE char *uuid = NULL;
-    char **keys;
+    struct matching_key *keys;
     size_t nr_matches;
     CLEANUP_FREE char *mapname = NULL;
     size_t scan;
 
     type = guestfs_vfs_type (g, mountable);
@@ -151,15 +151,15 @@ decrypt_mountables (guestfs_h *g, const char * const *mountables,
     if (uuid == NULL || asprintf (&mapname, "luks-%s", uuid) == -1)
       mapname = make_mapname (mountable);
 
     /* Try each key in turn. */
     for (scan = 0; scan < nr_matches; ++scan) {
-      const char *key = keys[scan];
+      struct matching_key *key = keys + scan;
       int r;
 
       guestfs_push_error_handler (g, NULL, NULL);
-      r = guestfs_cryptsetup_open (g, mountable, key, mapname, -1);
+      r = guestfs_cryptsetup_open (g, mountable, key->passphrase, mapname, -1);
       guestfs_pop_error_handler (g);
 
       if (r == 0)
         break;
     }
diff --git a/options/keys.c b/options/keys.c
index 1d97d980a460..56fca17a94b5 100644
--- a/options/keys.c
+++ b/options/keys.c
@@ -123,16 +123,16 @@ read_first_line_from_file (const char *filename)
 
 /* Return the key(s) matching this particular device from the
  * keystore.  There may be multiple.  If none are read from the
  * keystore, ask the user.
  */
-char **
+struct matching_key *
 get_keys (struct key_store *ks, const char *device, const char *uuid,
           size_t *nr_matches)
 {
-  size_t i, j, nmemb;
-  char **r;
+  size_t i, nmemb;
+  struct matching_key *r, *match;
   char *s;
 
   /* We know the returned list must have at least one element and not
    * more than ks->nr_keys.
    */
@@ -145,11 +145,11 @@ get_keys (struct key_store *ks, const char *device, const char *uuid,
 
   r = malloc (nmemb * sizeof *r);
   if (r == NULL)
     error (EXIT_FAILURE, errno, "malloc");
 
-  j = 0;
+  match = r;
 
   if (ks) {
     for (i = 0; i < ks->nr_keys; ++i) {
       struct key_store_key *key = &ks->keys[i];
 
@@ -159,39 +159,45 @@ get_keys (struct key_store *ks, const char *device, const char *uuid,
       switch (key->type) {
       case key_string:
         s = strdup (key->string.s);
         if (!s)
           error (EXIT_FAILURE, errno, "strdup");
-        r[j++] = s;
+        match->passphrase = s;
+        ++match;
         break;
       case key_file:
         s = read_first_line_from_file (key->file.name);
-        r[j++] = s;
+        match->passphrase = s;
+        ++match;
         break;
       }
     }
   }
 
-  if (j == 0) {
+  if (match == r) {
     /* Key not found in the key store, ask the user for it. */
     s = read_key (device);
     if (!s)
       error (EXIT_FAILURE, 0, _("could not read key from user"));
-    r[j++] = s;
+    match->passphrase = s;
+    ++match;
   }
 
-  *nr_matches = j;
+  *nr_matches = (size_t)(match - r);
   return r;
 }
 
 void
-free_keys (char **keys, size_t nr_matches)
+free_keys (struct matching_key *keys, size_t nr_matches)
 {
   size_t i;
 
-  for (i = 0; i < nr_matches; ++i)
-    free (keys[i]);
+  for (i = 0; i < nr_matches; ++i) {
+    struct matching_key *key = keys + i;
+
+    free (key->passphrase);
+  }
   free (keys);
 }
 
 struct key_store *
 key_store_add_from_selector (struct key_store *ks, const char *selector)
-- 
2.19.1.3.g30247aa5d201




More information about the Libguestfs mailing list