On Mon, Nov 16, 2020 at 13:21:01 +0100, Michal Privoznik wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > > 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@xxxxxxxxxx> > Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > --- > 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@xxxxxxxxxx>