The necessity to specify the secret value as command argument is
insecure. Allow reading the secret from a file.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
docs/manpages/virsh.rst | 7 +++++--
tools/virsh-secret.c | 38 +++++++++++++++++++++++++++++++++-----
2 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 0e6eb4cf35..a7551b9709 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -6563,10 +6563,13 @@ secret-set-value
.. code-block::
- secret-set-value secret base64
+ secret-set-value secret (--file filename | base64)
Set the value associated with *secret* (specified by its UUID) to the value
-Base64-encoded value *base64*.
+Base64-encoded value *base64* or Base-64-encoded contents of file named
+*filename*.
+
+Note that *--file* and *base64* options are mutually exclusive.
secret-get-value
diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c
index ead740dd8f..66852173b5 100644
--- a/tools/virsh-secret.c
+++ b/tools/virsh-secret.c
@@ -177,9 +177,13 @@ static const vshCmdOptDef opts_secret_set_value[] = {
.help = N_("secret UUID"),
.completer = virshSecretUUIDCompleter,
},
+ {.name = "file",
+ .type = VSH_OT_STRING,
+ .flags = VSH_OFLAG_REQ_OPT,
+ .help = N_("read secret from file"),
+ },
{.name = "base64",
- .type = VSH_OT_DATA,
- .flags = VSH_OFLAG_REQ,
+ .type = VSH_OT_STRING,
.help = N_("base64-encoded secret value")
},
{.name = NULL}
@@ -189,22 +193,46 @@ static bool
cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(virshSecret) secret = NULL;
- size_t value_size;
const char *base64 = NULL;
+ const char *filename = NULL;
+ char *file_buf = NULL;
+ size_t file_len = 0;
unsigned char *value;
+ size_t value_size;
int res;
+ VSH_EXCLUSIVE_OPTIONS("file", "base64");
+
if (!(secret = virshCommandOptSecret(ctl, cmd, NULL)))
return false;
if (vshCommandOptStringReq(ctl, cmd, "base64", &base64) < 0)
return false;
+ if (vshCommandOptStringReq(ctl, cmd, "file", &filename) < 0)
+ return false;
+
+ if (!base64 && !filename) {
+ vshError(ctl, _("Input secret value is missing"));
+ return false;
+ }
+
+ if (filename) {
+ ssize_t read_ret;
+ if ((read_ret = virFileReadAll(filename, 1024, &file_buf)) < 0) {
+ vshSaveLibvirtError();
+ return false;
+ }
+
+ file_len = read_ret;
+ base64 = file_buf;
+ }
+
value = g_base64_decode(base64, &value_size);
res = virSecretSetValue(secret, value, value_size, 0);
- memset(value, 0, value_size);
- VIR_FREE(value);
+ VIR_DISPOSE_N(value, value_size);
+ VIR_DISPOSE_N(file_buf, file_len);
if (res != 0) {
vshError(ctl, "%s", _("Failed to set secret value"));
--
2.24.1