[Libguestfs] [libguestfs-common PATCH 12/12] options, mltools/tools_utils: add helper for network dependency
Richard W.M. Jones
rjones at redhat.com
Tue Jun 28 14:50:56 UTC 2022
On Tue, Jun 28, 2022 at 01:49:15PM +0200, Laszlo Ersek wrote:
> For "--key ID:clevis" to actually work, the appliance needs network
> connectivity. Some tools allow the user to control that (for example,
> guestfish takes "--network"); those tools can already use "--key
> ID:clevis", provided they enable inspection and networking.
>
> However, other tools have had no use for networking thus far. Introduce a
> helper function for the OCaml utils, and another for the C utils, so that
> the utils can query if there's at least one clevis selector, and if so,
> enable networking for the appliance, before launching the appliance.
>
> Note that we need to implement both helpers separately from each other;
> that is, the OCaml one is not based on the C one. The reason is that
> "struct key_store" (from "options/options.h"), upon which we could
> logically base a common helper, exists in the OCaml tools only
> ephemerally, in guestfs_int_mllib_inspect_decrypt():
>
> inspect_decrypt [mltools/tools_utils.ml]
> c_inspect_decrypt [mltools/tools_utils.ml]
> guestfs_int_mllib_inspect_decrypt [mltools/tools_utils-c.c]
> key_store_import_key() [options/keys.c]
> inspect_do_decrypt() [options/decrypt.c]
> free_key_store() [options/keys.c]
>
> At that time, it's too late for enabling networking for the appliance.
> Therefore, in the OCaml tools, search the "earlier" data structure called
> "cmdline_options.ks". *That* "key_store" type comes from
> "mltools/tools_utils.ml".
>
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1809453
> Signed-off-by: Laszlo Ersek <lersek at redhat.com>
> ---
> options/options.h | 1 +
> mltools/tools_utils.mli | 4 ++++
> mltools/tools_utils.ml | 5 +++++
> options/keys.c | 15 +++++++++++++++
> options/key-option.pod | 3 +++
> 5 files changed, 28 insertions(+)
>
> diff --git a/options/options.h b/options/options.h
> index e7a0364cc926..60d5d8064113 100644
> --- a/options/options.h
> +++ b/options/options.h
> @@ -168,10 +168,11 @@ extern char *read_key (const char *param);
> 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 bool key_store_requires_network (const struct key_store *ks);
> extern void free_key_store (struct key_store *ks);
>
> /* in options.c */
> extern void option_a (const char *arg, const char *format, int blocksize, struct drv **drvsp);
> extern void option_d (const char *arg, struct drv **drvsp);
> diff --git a/mltools/tools_utils.mli b/mltools/tools_utils.mli
> index 8d9af7a0a661..ec900e6389bc 100644
> --- a/mltools/tools_utils.mli
> +++ b/mltools/tools_utils.mli
> @@ -194,10 +194,14 @@ val inspect_mount_root_ro : Guestfs.guestfs -> string -> unit
> read-only. *)
>
> val is_btrfs_subvolume : Guestfs.guestfs -> string -> bool
> (** Checks if a filesystem is a btrfs subvolume. *)
>
> +val key_store_requires_network : key_store -> bool
> +(** [key_store_requires_network ks] returns [true] iff [ks] contains at least
> + one "ID:clevis" selector. *)
> +
> val inspect_decrypt : Guestfs.guestfs -> key_store -> unit
> (** Simple implementation of decryption: look for any encrypted
> partitions and decrypt them, then rescan for VGs. *)
>
> val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a
> diff --git a/mltools/tools_utils.ml b/mltools/tools_utils.ml
> index 1da5850340d4..562bfadc18a8 100644
> --- a/mltools/tools_utils.ml
> +++ b/mltools/tools_utils.ml
> @@ -694,10 +694,15 @@ let is_btrfs_subvolume g fs =
> ignore (g#mountable_subvolume fs); true
> with Guestfs.Error msg as exn ->
> if g#last_errno () = Guestfs.Errno.errno_EINVAL then false
> else raise exn
>
> +let key_store_requires_network ks =
> + List.exists (function
> + | _, KeyClevis -> true
> + | _ -> false) !(ks.keys)
> +
> let inspect_decrypt g ks =
> (* Note we pass original 'g' even though it is not used by the
> * callee. This is so that 'g' is kept as a root on the stack, and
> * so cannot be garbage collected while we are in the c_inspect_decrypt
> * function.
> diff --git a/options/keys.c b/options/keys.c
> index d53e3e774a9b..97da6df93ee6 100644
> --- a/options/keys.c
> +++ b/options/keys.c
> @@ -282,10 +282,25 @@ key_store_import_key (struct key_store *ks, const struct key_store_key *key)
> ++ks->nr_keys;
>
> return ks;
> }
>
> +bool
> +key_store_requires_network (const struct key_store *ks)
> +{
> + size_t i;
> +
> + if (ks == NULL)
> + return false;
> +
> + for (i = 0; i < ks->nr_keys; ++i)
> + if (ks->keys[i].type == key_clevis)
> + return true;
> +
> + return false;
> +}
> +
> void
> free_key_store (struct key_store *ks)
> {
> size_t i;
>
> diff --git a/options/key-option.pod b/options/key-option.pod
> index 34229ce9cbb2..6bc04df177b1 100644
> --- a/options/key-option.pod
> +++ b/options/key-option.pod
> @@ -18,6 +18,9 @@ Read the passphrase from F<FILENAME>.
>
> Attempt passphrase-less unlocking for C<ID> with Clevis, over the
> network. Please refer to L<guestfs(3)/ENCRYPTED DISKS> for more
> information on network-bound disk encryption (NBDE).
>
> +Note that if any such option is present on the command line, QEMU user
> +networking will be automatically enabled for the libguestfs appliance.
> +
> =back
options/ is just one of those crazy pieces of code that
accumulates special cases :-(
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