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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list