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

Richard W.M. Jones rjones at redhat.com
Tue Jun 28 14:27:04 UTC 2022


On Tue, Jun 28, 2022 at 01:49:09PM +0200, Laszlo Ersek wrote:
> 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>
> ---
>  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)
> -- 

_Really need the vector "class" from nbdkit in libguestfs ..._

Reviewed-by: Richard W.M. Jones <rjones at redhat.com>


-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top


More information about the Libguestfs mailing list