[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