From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
Use the new set_password and expire_password monitor commands
to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password.
Based on patch by Daniel P. Berrange <berrange(a)redhat.com>.
---
src/qemu/qemu_driver.c | 138 +++++++++++++++++++++++++++++++++++++++++------
1 files changed, 120 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4877692..b4017af 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2516,6 +2516,65 @@ qemudInitCpuAffinity(virDomainObjPtr vm)
static int
+qemuInitGraphicsPasswords(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ int type,
+ virDomainGraphicsAuthDefPtr auth,
+ const char *defaultPasswd)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ time_t now = time(NULL);
+ char expire_time [64];
+ int ret;
+
+ if (!auth->passwd && !driver->vncPassword)
+ return 0;
+
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ ret = qemuMonitorSetPassword(priv->mon,
+ type,
+ auth->passwd ? auth->passwd : defaultPasswd,
+ NULL);
+
+ if (ret == -2) {
+ if (type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Only VNC graphics are supported"));
+ ret = -1;
+ } else {
+ ret = qemuMonitorSetVNCPassword(priv->mon,
+ auth->passwd ? auth->passwd :
defaultPasswd);
+ }
+ }
+
+ if (auth->expires) {
+ time_t lifetime = auth->validTo - now;
+ if (lifetime <= 0)
+ snprintf(expire_time, sizeof (expire_time), "now");
+ else
+ snprintf(expire_time, sizeof (expire_time), "%lu", (long
unsigned)auth->validTo);
+ } else {
+ snprintf(expire_time, sizeof (expire_time), "never");
+ }
+
+ ret = qemuMonitorExpirePassword(priv->mon, type, expire_time);
+
+ if (ret == -2) {
+ /* XXX we could fake this with a timer */
+ if (auth->expires) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Expiry of passwords is not supported"));
+ ret = -1;
+ }
+ }
+
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+ return ret;
+}
+
+
+static int
qemuInitPasswords(virConnectPtr conn,
struct qemud_driver *driver,
virDomainObjPtr vm,
@@ -2523,16 +2582,18 @@ qemuInitPasswords(virConnectPtr conn,
int ret = 0;
qemuDomainObjPrivatePtr priv = vm->privateData;
- if ((vm->def->ngraphics == 1) &&
- vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
- (vm->def->graphics[0]->data.vnc.auth.passwd || driver->vncPassword))
{
-
- qemuDomainObjEnterMonitorWithDriver(driver, vm);
- ret = qemuMonitorSetVNCPassword(priv->mon,
-
vm->def->graphics[0]->data.vnc.auth.passwd ?
-
vm->def->graphics[0]->data.vnc.auth.passwd :
- driver->vncPassword);
- qemuDomainObjExitMonitorWithDriver(driver, vm);
+ if (vm->def->ngraphics == 1) {
+ if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_VNC,
+
&vm->def->graphics[0]->data.vnc.auth,
+ driver->vncPassword);
+ } else if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)
{
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+
&vm->def->graphics[0]->data.vnc.auth,
+ driver->vncPassword);
+ }
}
if (ret < 0)
@@ -8922,7 +8983,6 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
virDomainGraphicsDefPtr dev)
{
virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
- qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
if (!olddev) {
@@ -8950,24 +9010,66 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
return -1;
}
- if (STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd,
dev->data.vnc.auth.passwd)) {
+ /* If a password lifetime was, or is set, then we must always run,
+ * even if new password matches old password */
+ if (olddev->data.vnc.auth.expires ||
+ dev->data.vnc.auth.expires ||
+ STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd,
dev->data.vnc.auth.passwd)) {
VIR_DEBUG("Updating password on VNC server %p %p",
dev->data.vnc.auth.passwd, driver->vncPassword);
- qemuDomainObjEnterMonitorWithDriver(driver, vm);
- ret = qemuMonitorSetVNCPassword(priv->mon,
- dev->data.vnc.auth.passwd ?
- dev->data.vnc.auth.passwd :
- driver->vncPassword);
- qemuDomainObjExitMonitorWithDriver(driver, vm);
+ ret = qemuInitGraphicsPasswords(driver, vm, VIR_DOMAIN_GRAPHICS_TYPE_VNC,
+ &dev->data.vnc.auth,
driver->vncPassword);
/* Steal the new dev's char * reference */
VIR_FREE(olddev->data.vnc.auth.passwd);
olddev->data.vnc.auth.passwd = dev->data.vnc.auth.passwd;
dev->data.vnc.auth.passwd = NULL;
+ olddev->data.vnc.auth.validTo = dev->data.vnc.auth.validTo;
+ olddev->data.vnc.auth.expires = dev->data.vnc.auth.expires;
} else {
+ VIR_DEBUG0("Not updating since password didn't change");
ret = 0;
}
break;
+ case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
+ if ((olddev->data.spice.autoport != dev->data.spice.autoport) ||
+ (!dev->data.spice.autoport && (olddev->data.spice.port !=
dev->data.spice.port)) ||
+ (!dev->data.spice.autoport && (olddev->data.spice.tlsPort !=
dev->data.spice.tlsPort))) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot change port settings on spice
graphics"));
+ return -1;
+ }
+ if (STRNEQ_NULLABLE(olddev->data.spice.listenAddr,
dev->data.spice.listenAddr)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot change listen address setting on spice
graphics"));
+ return -1;
+ }
+ if (STRNEQ_NULLABLE(olddev->data.spice.keymap, dev->data.spice.keymap)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot change keymap setting on spice
graphics"));
+ return -1;
+ }
+
+ /* If a password lifetime was, or is set, then we must always run,
+ * even if new password matches old password */
+ if (olddev->data.spice.auth.expires ||
+ dev->data.spice.auth.expires ||
+ STRNEQ_NULLABLE(olddev->data.spice.auth.passwd,
dev->data.spice.auth.passwd)) {
+ VIR_DEBUG("Updating password on SPICE server %p %p",
dev->data.spice.auth.passwd, driver->spicePassword);
+ ret = qemuInitGraphicsPasswords(driver, vm, VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &dev->data.spice.auth,
driver->spicePassword);
+
+ /* Steal the new dev's char * reference */
+ VIR_FREE(olddev->data.spice.auth.passwd);
+ olddev->data.spice.auth.passwd = dev->data.spice.auth.passwd;
+ dev->data.spice.auth.passwd = NULL;
+ olddev->data.spice.auth.validTo = dev->data.spice.auth.validTo;
+ olddev->data.spice.auth.expires = dev->data.spice.auth.expires;
+ } else {
+ VIR_DEBUG0("Not updating since password didn't change");
+ ret = 0;
+ }
+
default:
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("unable to change config on '%s' graphics
type"),
--
1.7.3.4