127 lines
4.4 KiB
Diff
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
|
|
|