From: Marc-Andrà Lureau <marcandre.lureau@xxxxxxxxxx> 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@xxxxxxxxxx>. --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list