]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Use the new set_password monitor command to set password.
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Mon, 10 Jan 2011 11:12:33 +0000 (12:12 +0100)
committerEric Blake <eblake@redhat.com>
Fri, 14 Jan 2011 19:36:00 +0000 (12:36 -0700)
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

Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.

Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
  to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
  initial patch from Daniel:
    - ret = qemuInitGraphicsPasswords(driver, vm,
    -                                 VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
    -                                 &vm->def->graphics[0]->data.vnc.auth,
    -                                 driver->vncPassword);
    + ret = qemuInitGraphicsPasswords(driver, vm,
    +                                 VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
    +                                 &vm->def->graphics[0]->data.spice.auth,
    +                                 driver->spicePassword);

Based on patch by Daniel P. Berrange <berrange@redhat.com>.

src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_hotplug.h

index 29b1d74296a29d60a05a7bb873db6d649cd89a0a..0eeacaf062aa237d49acbb67f12229a1ca777fa9 100644 (file)
@@ -1987,16 +1987,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 = qemuDomainChangeGraphicsPasswords(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 = qemuDomainChangeGraphicsPasswords(driver, vm,
+                                                    VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+                                                    &vm->def->graphics[0]->data.spice.auth,
+                                                    driver->spicePassword);
+        }
     }
 
     if (ret < 0)
index 9d6697ee678eff67758139dee2352dbe74f5d68d..b4088acb6dd1580b65cf41cb5ef0ba160557abad 100644 (file)
@@ -1016,7 +1016,6 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
                          virDomainGraphicsDefPtr dev)
 {
     virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
-    qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
 
     if (!olddev) {
@@ -1044,24 +1043,65 @@ 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 = qemuDomainChangeGraphicsPasswords(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 {
             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 = qemuDomainChangeGraphicsPasswords(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"),
@@ -1679,3 +1719,61 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
 
     return ret;
 }
+
+int
+qemuDomainChangeGraphicsPasswords(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;
+}
index 0e7ca8e0401e95601f44fc340af457a30c213e5b..217785d1b9f6e40dbe509ec168508d4fda26f765 100644 (file)
@@ -70,6 +70,11 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
 int qemuDomainChangeGraphics(struct qemud_driver *driver,
                              virDomainObjPtr vm,
                              virDomainGraphicsDefPtr dev);
+int qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver,
+                                      virDomainObjPtr vm,
+                                      int type,
+                                      virDomainGraphicsAuthDefPtr auth,
+                                      const char *defaultPasswd);
 int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
                                   virDomainObjPtr vm,
                                   virDomainDeviceDefPtr dev,