libguestfs/0020-daemon-Allow-base64-text-as-a-prefix-on-Key-paramete.patch
2026-08-06 09:36:18 -04:00

127 lines
4.4 KiB
Diff

From 20b5a3f5d4a4ebd51354b0ab92141dd4f80e0ef9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Apr 2026 09:33:06 +0100
Subject: [PATCH] daemon: Allow base64:/text: as a prefix on Key parameters
To support 8 bit keys, allow Key parameters to be passed with the
prefix "base64:..." where the key that follows is base64-encoded.
"text:..." can be used to prefix plaintext passphrases. Or, for
backwards compat, they can be passed without prefix, but this is now
slightly ambiguous.
Base64 keys are passed through all the APIs as opaque strings, and
then decoded in the daemon just before calling the cryptsetup command.
(cherry picked from commit 9324859875bd8845e63edd918885ef70bb47211b)
---
daemon/utils.ml | 23 ++++++++++++++++++++++-
daemon/utils.mli | 3 +++
generator/types.mli | 6 ++++++
lib/guestfs.pod | 23 +++++++++++++++++++++++
4 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/daemon/utils.ml b/daemon/utils.ml
index 2a03c7190..2ee303a41 100644
--- a/daemon/utils.ml
+++ b/daemon/utils.ml
@@ -296,8 +296,29 @@ let hex_of_string s =
let bytes = String.map_chars (fun c -> sprintf "%02x" (Char.code c)) s in
String.concat " " bytes
-let write_key_to_tmp_file key =
+let rec write_key_to_tmp_file key =
+ (* If the key starts with a prefix then it may need decoding. *)
+ let len = String.length key in
+ if String.starts_with "base64:" key then
+ _decode_base64_key (String.sub key 7 (len-7))
+ else if String.starts_with "text:" key then
+ _write_key (String.sub key 5 (len-5))
+ else
+ _write_key key
+
+and _write_key key =
let filename, chan = Filename.open_temp_file "key" ".out" in
output_string chan key;
close_out chan;
filename
+
+and _decode_base64_key b64 =
+ let b64file, chan = Filename.open_temp_file "key" ".b64" in
+ output_string chan b64;
+ close_out chan;
+ let keyfile = Filename.temp_file "key" ".out" in
+ let cmd = sprintf "base64 -d < %s > %s" (quote b64file) (quote keyfile) in
+ if Sys.command cmd <> 0 then
+ failwithf "could not decode base64-encoded key";
+ unlink b64file;
+ keyfile
diff --git a/daemon/utils.mli b/daemon/utils.mli
index 730e4af38..57f33dea8 100644
--- a/daemon/utils.mli
+++ b/daemon/utils.mli
@@ -129,6 +129,9 @@ val write_key_to_tmp_file : string -> string
(** Write a Key parameter to a temporary file. Returns the name of
the temporary file.
+ This handles the special "base64:..." or "text:..." prefixes
+ introduced in libguestfs 1.60.
+
The caller must call {!Unix.unlink} on the file. *)
(**/**)
diff --git a/generator/types.mli b/generator/types.mli
index 01f00044e..9416974db 100644
--- a/generator/types.mli
+++ b/generator/types.mli
@@ -190,6 +190,12 @@ and stringt =
Currently the only difference from 'PlainString' is the way
that guestfish requests these parameters from the user.
+ In libguestfs >= 1.60, these strings can be prefixed with
+ 'base64:...' to pass in a base64 encoded string (supporting
+ arbitrary 8 bit binary). 'text:...' can be used for plain
+ passphrases, or (for backwards compat) the passphrase can be
+ unprefixed.
+
Eventually we should treat this as sensitive and mlock it
into physical RAM. This is highly complex because of all
the places that XDR-encoded strings can end up. *)
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
index 07737c839..fe74f5542 100644
--- a/lib/guestfs.pod
+++ b/lib/guestfs.pod
@@ -1218,6 +1218,29 @@ representation. Also consider how it might work in guestfish.
Certain libguestfs calls take a parameter that contains sensitive key
material, passed in as a C string.
+In libguestfs E<ge> 1.60 you can pass in 8 bit binary key data
+(allowing C<'\n'> or C<'\0'>) by prefixing the string with:
+
+=over 4
+
+=item C<base64:...>
+
+Pass in base64-encoded key data. This supports 8 bit binary key
+data.
+
+=item C<text:...>
+
+Pass in regular text passphrase. This does not support 8 bit binary
+key data.
+
+=item Unprefixed
+
+For backwards compatibility with libguestfs E<le> 1.58, a text
+passphrase can be passed in unprefixed. However this does not support
+8 bit binary key data.
+
+=back
+
In the future we would hope to change the libguestfs implementation so
that keys are L<mlock(2)>-ed into physical RAM, and thus can never end
up in swap. However this is I<not> done at the moment, because of the
--
2.47.3