]> git.proxmox.com Git - qemu.git/commitdiff
vnc: Fix password expiration through 'change vnc ""' (v2)
authorAnthony Liguori <aliguori@us.ibm.com>
Mon, 31 Jan 2011 20:27:36 +0000 (14:27 -0600)
committerAnthony Liguori <aliguori@us.ibm.com>
Tue, 1 Feb 2011 21:16:48 +0000 (15:16 -0600)
commit 52c18be9e99dabe295321153fda7fce9f76647ac introduced a regression in the
change vnc password command that changed the behavior of setting the VNC
password to an empty string from disabling login to disabling authentication.

This commit refactors the code to eliminate this overloaded semantics in
vnc_display_password and instead introduces the vnc_display_disable_login.   The
monitor implementation then determines the behavior of an empty or missing
string.

Recently, a set_password command was added that allows both the Spice and VNC
password to be set.  This command has not shown up in a release yet so the
behavior is not yet defined.

This patch proposes that an empty password be treated as an empty password with
no special handling.  For specifically disabling login, I believe a new command
should be introduced instead of overloading semantics.

I'm not sure how Spice handles this but I would recommend that we have Spice
and VNC have consistent semantics here for the 0.14.0 release.

Reported-by: Neil Wilson <neil@aldur.co.uk>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - Add a proper return to make sure that login is really disabled instead of
   relying on the VNC server to treat empty passwords specially

console.h
monitor.c
ui/vnc.c

index 3157330eb207109e0c42bd3bc4ba95eb619c58ee..f4e474109113f32f3958fd02e80540b9a6259938 100644 (file)
--- a/console.h
+++ b/console.h
@@ -369,6 +369,7 @@ void vnc_display_init(DisplayState *ds);
 void vnc_display_close(DisplayState *ds);
 int vnc_display_open(DisplayState *ds, const char *display);
 int vnc_display_password(DisplayState *ds, const char *password);
+int vnc_display_disable_login(DisplayState *ds);
 int vnc_display_pw_expire(DisplayState *ds, time_t expires);
 void do_info_vnc_print(Monitor *mon, const QObject *data);
 void do_info_vnc(Monitor *mon, QObject **ret_data);
index c5f54f46c7b4f6ad21ff930ff0debedb47d0c813..64e41e3e7d232c0357776e119e640073ac2d6273 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -1018,6 +1018,14 @@ static int do_quit(Monitor *mon, const QDict *qdict, QObject **ret_data)
 
 static int change_vnc_password(const char *password)
 {
+    if (!password || !password[0]) {
+        if (vnc_display_disable_login(NULL)) {
+            qerror_report(QERR_SET_PASSWD_FAILED);
+            return -1;
+        }
+        return 0;
+    }
+
     if (vnc_display_password(NULL, password) < 0) {
         qerror_report(QERR_SET_PASSWD_FAILED);
         return -1;
@@ -1117,6 +1125,8 @@ static int set_password(Monitor *mon, const QDict *qdict, QObject **ret_data)
             qerror_report(QERR_INVALID_PARAMETER, "connected");
             return -1;
         }
+        /* Note that setting an empty password will not disable login through
+         * this interface. */
         rc = vnc_display_password(NULL, password);
         if (rc != 0) {
             qerror_report(QERR_SET_PASSWD_FAILED);
index 495d6d6ef1ea43e839ccb49d4b8a2cd30d2d11cf..8067b313f7332f2f5f72b7401023c9a1d0cfedd0 100644 (file)
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2084,7 +2084,7 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
     unsigned char key[8];
     time_t now = time(NULL);
 
-    if (!vs->vd->password || !vs->vd->password[0]) {
+    if (!vs->vd->password) {
         VNC_DEBUG("No password configured on server");
         goto reject;
     }
@@ -2484,6 +2484,24 @@ void vnc_display_close(DisplayState *ds)
 #endif
 }
 
+int vnc_display_disable_login(DisplayState *ds)
+{
+    VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+
+    if (!vs) {
+        return -1;
+    }
+
+    if (vs->password) {
+        qemu_free(vs->password);
+    }
+
+    vs->password = NULL;
+    vs->auth = VNC_AUTH_VNC;
+
+    return 0;
+}
+
 int vnc_display_password(DisplayState *ds, const char *password)
 {
     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
@@ -2492,19 +2510,18 @@ int vnc_display_password(DisplayState *ds, const char *password)
         return -1;
     }
 
+    if (!password) {
+        /* This is not the intention of this interface but err on the side
+           of being safe */
+        return vnc_display_disable_login(ds);
+    }
+
     if (vs->password) {
         qemu_free(vs->password);
         vs->password = NULL;
     }
-    if (password && password[0]) {
-        if (!(vs->password = qemu_strdup(password)))
-            return -1;
-        if (vs->auth == VNC_AUTH_NONE) {
-            vs->auth = VNC_AUTH_VNC;
-        }
-    } else {
-        vs->auth = VNC_AUTH_NONE;
-    }
+    vs->password = qemu_strdup(password);
+    vs->auth = VNC_AUTH_VNC;
 
     return 0;
 }