On Mon, Nov 16, 2020 at 13:21:01 +0100, Michal Privoznik wrote:
From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
In QEMU 5.2, the guest agent learned to manipulate a user
~/.ssh/authorized_keys. Bind the JSON API to libvirt.
https://wiki.qemu.org/ChangeLog/5.2#Guest_agent
Signed-off-by: Marc-André Lureau <marcandre.lureau(a)redhat.com>
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_agent.c | 142 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_agent.h | 15 +++++
tests/qemuagenttest.c | 79 +++++++++++++++++++++++
3 files changed, 236 insertions(+)
diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 7fbb4a9431..aeed74ec31 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -2496,3 +2496,145 @@ qemuAgentSetResponseTimeout(qemuAgentPtr agent,
{
agent->timeout = timeout;
}
+
+/**
+ * qemuAgentSSHGetAuthorizedKeys:
+ * @agent: agent object
+ * @user: user to get authorized keys for
+ * @keys: Array of authorized keys
+ *
+ * Fetch the public keys from @user's $HOME/.ssh/authorized_keys.
+ *
+ * Returns: number of keys returned on success,
+ * -1 otherwise (error is reported)
+ */
+int
+qemuAgentSSHGetAuthorizedKeys(qemuAgentPtr agent,
+ const char *user,
+ char ***keys)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+ virJSONValuePtr data = NULL;
+ size_t ndata;
+ size_t i;
+ char **keys_ret = NULL;
+
+ if (!(cmd = qemuAgentMakeCommand("guest-ssh-get-authorized-keys",
+ "s:username", user,
+ NULL)))
+ return -1;
+
+ if (qemuAgentCommand(agent, cmd, &reply, agent->timeout) < 0)
+ return -1;
+
+ if (!(data = virJSONValueObjectGetObject(reply, "return")) ||
+ !(data = virJSONValueObjectGetArray(data, "keys"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu agent didn't return an array of keys"));
+ return -1;
+ }
+
+ ndata = virJSONValueArraySize(data);
+
+ keys_ret = g_new0(char *, ndata);
+ 1
+
+ for (i = 0; i < ndata; i++) {
+ virJSONValuePtr entry = virJSONValueArrayGet(data, i);
+
+ if (!entry) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("array element missing in
guest-ssh-get-authorized-keys return "
+ "value"));
Whole error message should be on a single line.
+ goto error;
+ }
+
+ keys_ret[i] = g_strdup(virJSONValueGetString(entry));
+ }
+
+ *keys = g_steal_pointer(&keys_ret);
+ return ndata;
+
+ error:
+ virStringListFreeCount(keys_ret, ndata);
+ return -1;
+}
[...]
Reviewed-by: Peter Krempa <pkrempa(a)redhat.com>