Base-64 encode the password and pass it to the guest agent
via the 'guest-set-user-password' command.
https://bugzilla.redhat.com/show_bug.cgi?id=1174177
---
src/qemu/qemu_agent.c | 39 +++++++++++++++++++++++++++++++++++
src/qemu/qemu_agent.h | 4 ++++
src/qemu/qemu_driver.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+)
diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index fc23c41..71aed64 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -42,6 +42,7 @@
#include "virtime.h"
#include "virobject.h"
#include "virstring.h"
+#include "base64.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -2117,3 +2118,41 @@ qemuAgentGetInterfaces(qemuAgentPtr mon,
goto cleanup;
}
+
+
+int
+qemuAgentSetUserPassword(qemuAgentPtr mon,
+ const char *user,
+ const char *password,
+ bool crypted)
+{
+ int ret = -1;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+ char *password64 = NULL;
+
+ base64_encode_alloc(password, strlen(password), &password64);
+ if (!password64) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (!(cmd = qemuAgentMakeCommand("guest-set-user-password",
+ "b:crypted", crypted,
+ "s:username", user,
+ "s:password", password64,
+ NULL)))
+ goto cleanup;
+
+ if (qemuAgentCommand(mon, cmd, &reply, true,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ VIR_FREE(password64);
+ return ret;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 988228b..7cbf8eb 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -114,4 +114,8 @@ int qemuAgentSetTime(qemuAgentPtr mon,
int qemuAgentGetInterfaces(qemuAgentPtr mon,
virDomainInterfacePtr **ifaces);
+int qemuAgentSetUserPassword(qemuAgentPtr mon,
+ const char *user,
+ const char *password,
+ bool crypted);
#endif /* __QEMU_AGENT_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2668011..6c7bc86 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20124,6 +20124,60 @@ qemuGetDHCPInterfaces(virDomainPtr dom,
goto cleanup;
}
+
+static int
+qemuDomainSetUserPassword(virDomainPtr dom,
+ const char *user,
+ const char *password,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = dom->conn->privateData;
+ qemuDomainObjPrivatePtr priv;
+ virDomainObjPtr vm;
+ int ret = -1;
+ int rv;
+
+ virCheckFlags(VIR_DOMAIN_PASSWORD_CRYPTED, -1);
+
+ if (!(vm = qemuDomObjFromDomain(dom)))
+ return ret;
+
+ if (virDomainSetUserPasswordEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ priv = vm->privateData;
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
+ if (!qemuDomainAgentAvailable(vm, true))
+ goto endjob;
+
+ qemuDomainObjEnterAgent(vm);
+ rv = qemuAgentSetUserPassword(priv->agent, user, password,
+ flags & VIR_DOMAIN_PASSWORD_CRYPTED);
+ qemuDomainObjExitAgent(vm);
+
+ if (rv < 0)
+ goto endjob;
+
+ ret = 0;
+
+ endjob:
+ qemuDomainObjEndJob(driver, vm);
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ return ret;
+}
+
+
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
.connectOpen = qemuConnectOpen, /* 0.2.0 */
@@ -20330,6 +20384,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.nodeAllocPages = qemuNodeAllocPages, /* 1.2.9 */
.domainGetFSInfo = qemuDomainGetFSInfo, /* 1.2.11 */
.domainInterfaceAddresses = qemuDomainInterfaceAddresses, /* 1.2.14 */
+ .domainSetUserPassword = qemuDomainSetUserPassword, /* 1.2.16 */
};
--
2.0.5