File libvirt-Support-password-expiry-and-connected-in-the-QEMU-driver.patch of Package libvirt

From 83bd72177970e7736af1d18500898588f5f12f8c Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Tue, 9 Aug 2011 14:50:14 +0800
Subject: [PATCH] Support password expiry and 'connected' in the QEMU driver
To: libvir-list@redhat.com

From: Daniel P. Berrange <berrange@redhat.com>

RHEL-6 only, no upstream

The RHEL6 build of QEMU has a custom monitor command that allows
an expiry time to be set. We try to use that command first when
setting a VNC/SPICE password. If that doesn't work we fallback
to upstream way which supports this via to separate commands
(set_password and expire_password).
Also, send 'connected' attribute with command to support
action_if_connected actions.

This patch was missing check for action_if_connected being NULL
in qemuMonitorSetPasswordRH function.

Signed-off-by: Daniel Veillard <veillard@redhat.com>
---
 src/qemu/qemu_hotplug.c      | 28 +++++++++++++++++++++++++++-
 src/qemu/qemu_monitor.c      | 33 +++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor.h      |  5 +++++
 src/qemu/qemu_monitor_json.c | 37 +++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |  5 +++++
 5 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index bcf3081..4022c07 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2326,6 +2326,7 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver,
     time_t now = time(NULL);
     char expire_time [64];
     const char *connected = NULL;
+    time_t lifetime;
     int ret;
 
     if (!auth->passwd && !driver->vncPassword)
@@ -2335,6 +2336,31 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver,
         connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
+
+    /* try rhel-only command first */
+    if (auth->expires) {
+        lifetime = auth->validTo - now;
+        /* QEMU treats '0' as dont expire, so we need to force it to expire
+         * immediately */
+        if (lifetime <= 0)
+            lifetime = -1;
+    } else {
+        lifetime = 0; /* don't expire */
+    }
+
+    ret = qemuMonitorSetPasswordRH(priv->mon,
+                                   type,
+                                   auth->passwd ? auth->passwd : defaultPasswd,
+                                   connected,
+                                   lifetime);
+    if (ret == -2) {
+        VIR_DEBUG("__com.redhat_set_password command not supported,"
+                  " trying the upstream way");
+    } else {
+        /* either success or normal error, so skip the upstream way */
+        goto cleanup;
+    }
+
     ret = qemuMonitorSetPassword(priv->mon,
                                  type,
                                  auth->passwd ? auth->passwd : defaultPasswd,
@@ -2354,7 +2380,7 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver,
         goto cleanup;
 
     if (auth->expires) {
-        time_t lifetime = auth->validTo - now;
+        lifetime = auth->validTo - now;
         if (lifetime <= 0)
             snprintf(expire_time, sizeof(expire_time), "now");
         else
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index fa3b7b2..1f9cd40 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1568,6 +1568,39 @@ static const char* qemuMonitorTypeToProtocol(int type)
 }
 
 /* Returns -2 if not supported with this monitor connection */
+int qemuMonitorSetPasswordRH(qemuMonitorPtr mon,
+                             int type,
+                             const char *password,
+                             const char *action_if_connected,
+                             int expiry)
+{
+    const char *protocol = qemuMonitorTypeToProtocol(type);
+    int ret;
+
+    VIR_DEBUG("mon=%p, fd=%d type=%d(%s), password=%p, "
+              "action_if_connected=%s expiry=%d",
+              mon, mon->fd, type, protocol, password,
+              action_if_connected, expiry);
+
+    if (!protocol)
+        return -1;
+
+    if (!password)
+        password = "";
+
+    if (!action_if_connected)
+        action_if_connected = "keep";
+
+    if (mon->json)
+        ret = qemuMonitorJSONSetPasswordRH(mon, protocol, password,
+                                           action_if_connected, expiry);
+    else {
+        ret = -2;
+    }
+    return ret;
+}
+
+/* Returns -2 if not supported with this monitor connection */
 int qemuMonitorSetPassword(qemuMonitorPtr mon,
                            int type,
                            const char *password,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 6b4eb6f..d4a6469 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -286,6 +286,11 @@ int qemuMonitorBlockResize(qemuMonitorPtr mon,
                            unsigned long long size);
 int qemuMonitorSetVNCPassword(qemuMonitorPtr mon,
                               const char *password);
+int qemuMonitorSetPasswordRH(qemuMonitorPtr mon,
+                             int type,
+                             const char *password,
+                             const char *action_if_connected,
+                             int expiry);
 int qemuMonitorSetPassword(qemuMonitorPtr mon,
                            int type,
                            const char *password,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 2aa28cb..67bc2c1 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2067,6 +2067,43 @@ int qemuMonitorJSONSetVNCPassword(qemuMonitorPtr mon,
 }
 
 /* Returns -1 on error, -2 if not supported */
+int qemuMonitorJSONSetPasswordRH(qemuMonitorPtr mon,
+                                 const char *protocol,
+                                 const char *password,
+                                 const char *action_if_connected,
+                                 int expiry)
+{
+    int ret = -1;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+
+    cmd = qemuMonitorJSONMakeCommand("__com.redhat_set_password",
+                                     "s:protocol", protocol,
+                                     "s:password", password,
+                                     "s:connected", action_if_connected,
+                                     "i:expiration", expiry,
+                                     NULL);
+    if (!cmd)
+        return -1;
+
+    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+    if (ret == 0) {
+        if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+            ret = -2;
+            goto cleanup;
+        }
+
+        ret = qemuMonitorJSONCheckError(cmd, reply);
+    }
+
+cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+/* Returns -1 on error, -2 if not supported */
 int qemuMonitorJSONSetPassword(qemuMonitorPtr mon,
                                const char *protocol,
                                const char *password,
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index e531eb1..b7f608e 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -90,6 +90,11 @@ int qemuMonitorJSONBlockResize(qemuMonitorPtr mon,
 
 int qemuMonitorJSONSetVNCPassword(qemuMonitorPtr mon,
                                   const char *password);
+int qemuMonitorJSONSetPasswordRH(qemuMonitorPtr mon,
+                                 const char *protocol,
+                                 const char *password,
+                                 const char *action_if_connected,
+                                 int expiry);
 int qemuMonitorJSONSetPassword(qemuMonitorPtr mon,
                                const char *protocol,
                                const char *password,
-- 
1.7.11.4

openSUSE Build Service is sponsored by