diff --git a/.cvsignore b/.cvsignore
index d7cbda4..a075ebc 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1 +1 @@
-kvm-84.git-snapshot-20090303.tar.gz
+kvm-84.git-snapshot-20090310.tar.gz
diff --git a/qemu-sasl-01-tls-handshake-fix.patch b/qemu-sasl-01-tls-handshake-fix.patch
deleted file mode 100644
index ded8e4d..0000000
--- a/qemu-sasl-01-tls-handshake-fix.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-This patch was previously posted here:
-
-  http://lists.gnu.org/archive/html/qemu-devel/2009-02/msg00820.html
-
-In the case where the TLS handshake does *not* block on I/O, QEMU
-sends the next 'start sub-auth' message twice. This seriously confuses
-the VNC client :-) Fortunately the chances of the handshake not blocking
-are close to zero for a TCP socket, which is why it has not been noticed
-thus far. Even with both client & server on localhost, I can only hit the
-bug 1 time in 20.
-
-NB, the diff context here is not too informative. If you look at the
-full code you'll see that a few lines early we called vnc_start_tls()
-which called vnc_continue_handshake() which called the method
-start_auth_vencrypt_subauth(). Hence, fixing the bug, just involves
-removing the 2nd bogus call to start_auth_vencrypt_subauth() as per
-this patch.
-
-
- vnc.c |    8 --------
- 1 file changed, 8 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -2096,14 +2096,6 @@ static int protocol_client_vencrypt_auth
- 	    VNC_DEBUG("Failed to complete TLS\n");
- 	    return 0;
- 	}
--
--	if (vs->wiremode == VNC_WIREMODE_TLS) {
--	    VNC_DEBUG("Starting VeNCrypt subauth\n");
--	    return start_auth_vencrypt_subauth(vs);
--	} else {
--	    VNC_DEBUG("TLS handshake blocked\n");
--	    return 0;
--	}
-     }
-     return 0;
- }
diff --git a/qemu-sasl-02-vnc-monitor-info.patch b/qemu-sasl-02-vnc-monitor-info.patch
deleted file mode 100644
index 3af5b99..0000000
--- a/qemu-sasl-02-vnc-monitor-info.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-The current 'info vnc' monitor output just displays the VNC server address
-as provided by the -vnc command line flag. This isn't particularly useful
-since it doesn't tell you what VNC is actually listening on. eg, if you
-use '-vnc :1' it is useful to know whether this translated to '0.0.0.0:5901'
-or chose IPv6 ':::5901'.  It is also useful to know the address of the
-client that is currently connected. It is also useful to know the active
-authentication (if any).
-
-This patch tweaks the monitor output to look like:
-
-   (qemu) info vnc
-    Server:
-         address: 0.0.0.0:5902
-            auth: vencrypt+x509
-    Client: none
-
-And when 2 clients are connected
-
-   (qemu) info vnc
-    Server:
-         address: 0.0.0.0:5902
-            auth: vencrypt+x509
-    Client:
-         address: 10.33.6.67:38621
-    Client:
-         address: 10.33.6.63:38620
-
-More data will be added to this later in the patch series...
-
-The 'addr_to_string' helper method in this patch is overly generic
-for the needs of this patch alone. This is because it will be re-used
-by the later SASL patches in this series, where the flexibility is
-important.
-
-
- vnc.c |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 127 insertions(+), 10 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -166,19 +166,136 @@ struct VncState
- static VncDisplay *vnc_display; /* needed for info vnc */
- static DisplayChangeListener *dcl;
- 
-+static char *addr_to_string(const char *format,
-+			    struct sockaddr_storage *sa,
-+			    socklen_t salen) {
-+    char *addr;
-+    char host[NI_MAXHOST];
-+    char serv[NI_MAXSERV];
-+    int err;
-+
-+    if ((err = getnameinfo((struct sockaddr *)sa, salen,
-+			   host, sizeof(host),
-+			   serv, sizeof(serv),
-+			   NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
-+	VNC_DEBUG("Cannot resolve address %d: %s\n",
-+		  err, gai_strerror(err));
-+	return NULL;
-+    }
-+
-+    if (asprintf(&addr, format, host, serv) < 0)
-+	return NULL;
-+
-+    return addr;
-+}
-+
-+static char *vnc_socket_local_addr(const char *format, int fd) {
-+    struct sockaddr_storage sa;
-+    socklen_t salen;
-+
-+    salen = sizeof(sa);
-+    if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
-+	return NULL;
-+
-+    return addr_to_string(format, &sa, salen);
-+}
-+
-+static char *vnc_socket_remote_addr(const char *format, int fd) {
-+    struct sockaddr_storage sa;
-+    socklen_t salen;
-+
-+    salen = sizeof(sa);
-+    if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
-+	return NULL;
-+
-+    return addr_to_string(format, &sa, salen);
-+}
-+
-+static const char *vnc_auth_name(VncDisplay *vd) {
-+    switch (vd->auth) {
-+    case VNC_AUTH_INVALID:
-+	return "invalid";
-+    case VNC_AUTH_NONE:
-+	return "none";
-+    case VNC_AUTH_VNC:
-+	return "vnc";
-+    case VNC_AUTH_RA2:
-+	return "ra2";
-+    case VNC_AUTH_RA2NE:
-+	return "ra2ne";
-+    case VNC_AUTH_TIGHT:
-+	return "tight";
-+    case VNC_AUTH_ULTRA:
-+	return "ultra";
-+    case VNC_AUTH_TLS:
-+	return "tls";
-+    case VNC_AUTH_VENCRYPT:
-+#ifdef CONFIG_VNC_TLS
-+	switch (vd->subauth) {
-+	case VNC_AUTH_VENCRYPT_PLAIN:
-+	    return "vencrypt+plain";
-+	case VNC_AUTH_VENCRYPT_TLSNONE:
-+	    return "vencrypt+tls+none";
-+	case VNC_AUTH_VENCRYPT_TLSVNC:
-+	    return "vencrypt+tls+vnc";
-+	case VNC_AUTH_VENCRYPT_TLSPLAIN:
-+	    return "vencrypt+tls+plain";
-+	case VNC_AUTH_VENCRYPT_X509NONE:
-+	    return "vencrypt+x509+none";
-+	case VNC_AUTH_VENCRYPT_X509VNC:
-+	    return "vencrypt+x509+vnc";
-+	case VNC_AUTH_VENCRYPT_X509PLAIN:
-+	    return "vencrypt+x509+plain";
-+	default:
-+	    return "vencrypt";
-+	}
-+#else
-+	return "vencrypt";
-+#endif
-+    }
-+    return "unknown";
-+}
-+
-+#define VNC_SOCKET_FORMAT_PRETTY "local %s:%s"
-+
-+static void do_info_vnc_client(VncState *client)
-+{
-+    char *clientAddr =
-+	vnc_socket_remote_addr("     address: %s:%s\n",
-+			       client->csock);
-+    if (!clientAddr)
-+	return;
-+
-+    term_puts("Client:\n");
-+    term_puts(clientAddr);
-+    free(clientAddr);
-+}
-+
- void do_info_vnc(void)
- {
--    if (vnc_display == NULL || vnc_display->display == NULL)
--	term_printf("VNC server disabled\n");
--    else {
--	term_printf("VNC server active on: ");
--	term_print_filename(vnc_display->display);
--	term_printf("\n");
--
--	if (vnc_display->clients == NULL)
--	    term_printf("No client connected\n");
--	else
--	    term_printf("Client connected\n");
-+    if (vnc_display == NULL || vnc_display->display == NULL) {
-+	term_printf("Server: disabled\n");
-+    } else {
-+	char *serverAddr = vnc_socket_local_addr("     address: %s:%s\n",
-+						 vnc_display->lsock);
-+
-+	if (!serverAddr)
-+	    return;
-+
-+	term_puts("Server:\n");
-+	term_puts(serverAddr);
-+	free(serverAddr);
-+	term_printf("        auth: %s\n", vnc_auth_name(vnc_display));
-+
-+	if (vnc_display->clients) {
-+	    VncState *client = vnc_display->clients;
-+	    while (client) {
-+		do_info_vnc_client(client);
-+		client = client->next;
-+	    }
-+	} else {
-+	    term_printf("Client: none\n");
-+	}
-     }
- }
- 
diff --git a/qemu-sasl-03-display-keymaps.patch b/qemu-sasl-03-display-keymaps.patch
deleted file mode 100644
index 250deee..0000000
--- a/qemu-sasl-03-display-keymaps.patch
+++ /dev/null
@@ -1,352 +0,0 @@
-Each of the graphical frontends #include a .c file, for keymap code
-resulting in duplicated definitions & duplicated compiled code. A
-couple of small changes allowed this to be sanitized, so instead of
-doing a #include "keymaps.c", duplicating all code, we can have a
-shared keymaps.h file, and only compile code once. This allows the
-next patch to move the VncState struct out into a header file without
-causing clashing definitions.
-
-
- Makefile      |    9 +++++---
- b/keymaps.h   |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- curses.c      |    3 --
- curses_keys.h |    9 +++-----
- keymaps.c     |   45 ++++++++++++++++---------------------------
- sdl.c         |    3 --
- sdl_keysym.h  |    7 ++----
- vnc.c         |    5 +---
- vnc_keysym.h  |    7 ++----
- 9 files changed, 97 insertions(+), 51 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/Makefile
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/Makefile
-+++ kvm-84.git-snapshot-20090303/qemu/Makefile
-@@ -141,6 +141,7 @@ endif
- AUDIO_OBJS+= wavcapture.o
- OBJS+=$(addprefix audio/, $(AUDIO_OBJS))
- 
-+OBJS+=keymaps.o
- ifdef CONFIG_SDL
- OBJS+=sdl.o x_keymap.o
- endif
-@@ -165,15 +166,17 @@ LIBS+=$(VDE_LIBS)
- 
- cocoa.o: cocoa.m
- 
--sdl.o: sdl.c keymaps.c sdl_keysym.h
-+keymaps.o: keymaps.c keymaps.h
-+
-+sdl.o: sdl.c keymaps.h sdl_keysym.h
- 
- sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
- 
--vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
-+vnc.o: vnc.c keymaps.h sdl_keysym.h vnchextile.h d3des.c d3des.h
- 
- vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
- 
--curses.o: curses.c keymaps.c curses_keys.h
-+curses.o: curses.c keymaps.h curses_keys.h
- 
- bt-host.o: CFLAGS += $(CONFIG_BLUEZ_CFLAGS)
- 
-Index: kvm-84.git-snapshot-20090303/qemu/curses.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/curses.c
-+++ kvm-84.git-snapshot-20090303/qemu/curses.c
-@@ -158,7 +158,6 @@ static void curses_cursor_position(Displ
- /* generic keyboard conversion */
- 
- #include "curses_keys.h"
--#include "keymaps.c"
- 
- static kbd_layout_t *kbd_layout = 0;
- static int keycode2keysym[CURSES_KEYS];
-@@ -311,7 +310,7 @@ static void curses_keyboard_setup(void)
-         keyboard_layout = "en-us";
- #endif
-     if(keyboard_layout) {
--        kbd_layout = init_keyboard_layout(keyboard_layout);
-+        kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
-         if (!kbd_layout)
-             exit(1);
-     }
-Index: kvm-84.git-snapshot-20090303/qemu/curses_keys.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/curses_keys.h
-+++ kvm-84.git-snapshot-20090303/qemu/curses_keys.h
-@@ -21,6 +21,10 @@
-  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-  * THE SOFTWARE.
-  */
-+
-+#include "keymaps.h"
-+
-+
- #define KEY_RELEASE         0x80
- #define KEY_MASK            0x7f
- #define SHIFT_CODE          0x2a
-@@ -239,11 +243,6 @@ static const int curses2keysym[CURSES_KE
- 
- };
- 
--typedef struct {
--	const char* name;
--	int keysym;
--} name2keysym_t;
--
- static const name2keysym_t name2keysym[] = {
-     /* Plain ASCII */
-     { "space", 0x020 },
-Index: kvm-84.git-snapshot-20090303/qemu/keymaps.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/keymaps.c
-+++ kvm-84.git-snapshot-20090303/qemu/keymaps.c
-@@ -22,34 +22,20 @@
-  * THE SOFTWARE.
-  */
- 
--static int get_keysym(const char *name)
-+#include "keymaps.h"
-+#include "sysemu.h"
-+
-+static int get_keysym(const name2keysym_t *table,
-+		      const char *name)
- {
-     const name2keysym_t *p;
--    for(p = name2keysym; p->name != NULL; p++) {
-+    for(p = table; p->name != NULL; p++) {
-         if (!strcmp(p->name, name))
-             return p->keysym;
-     }
-     return 0;
- }
- 
--struct key_range {
--    int start;
--    int end;
--    struct key_range *next;
--};
--
--#define MAX_NORMAL_KEYCODE 512
--#define MAX_EXTRA_COUNT 256
--typedef struct {
--    uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
--    struct {
--	int keysym;
--	uint16_t keycode;
--    } keysym2keycode_extra[MAX_EXTRA_COUNT];
--    int extra_count;
--    struct key_range *keypad_range;
--    struct key_range *numlock_range;
--} kbd_layout_t;
- 
- static void add_to_key_range(struct key_range **krp, int code) {
-     struct key_range *kr;
-@@ -73,7 +59,8 @@ static void add_to_key_range(struct key_
-     }
- }
- 
--static kbd_layout_t *parse_keyboard_layout(const char *language,
-+static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
-+					   const char *language,
- 					   kbd_layout_t * k)
- {
-     FILE *f;
-@@ -102,7 +89,7 @@ static kbd_layout_t *parse_keyboard_layo
- 	if (!strncmp(line, "map ", 4))
- 	    continue;
- 	if (!strncmp(line, "include ", 8)) {
--	    parse_keyboard_layout(line + 8, k);
-+	    parse_keyboard_layout(table, line + 8, k);
-         } else {
- 	    char *end_of_keysym = line;
- 	    while (*end_of_keysym != 0 && *end_of_keysym != ' ')
-@@ -110,7 +97,7 @@ static kbd_layout_t *parse_keyboard_layo
- 	    if (*end_of_keysym) {
- 		int keysym;
- 		*end_of_keysym = 0;
--		keysym = get_keysym(line);
-+		keysym = get_keysym(table, line);
- 		if (keysym == 0) {
-                     //		    fprintf(stderr, "Warning: unknown keysym %s\n", line);
- 		} else {
-@@ -154,12 +141,14 @@ static kbd_layout_t *parse_keyboard_layo
-     return k;
- }
- 
--static void *init_keyboard_layout(const char *language)
-+
-+void *init_keyboard_layout(const name2keysym_t *table, const char *language)
- {
--    return parse_keyboard_layout(language, 0);
-+    return parse_keyboard_layout(table, language, 0);
- }
- 
--static int keysym2scancode(void *kbd_layout, int keysym)
-+
-+int keysym2scancode(void *kbd_layout, int keysym)
- {
-     kbd_layout_t *k = kbd_layout;
-     if (keysym < MAX_NORMAL_KEYCODE) {
-@@ -180,7 +169,7 @@ static int keysym2scancode(void *kbd_lay
-     return 0;
- }
- 
--static inline int keycode_is_keypad(void *kbd_layout, int keycode)
-+int keycode_is_keypad(void *kbd_layout, int keycode)
- {
-     kbd_layout_t *k = kbd_layout;
-     struct key_range *kr;
-@@ -191,7 +180,7 @@ static inline int keycode_is_keypad(void
-     return 0;
- }
- 
--static inline int keysym_is_numlock(void *kbd_layout, int keysym)
-+int keysym_is_numlock(void *kbd_layout, int keysym)
- {
-     kbd_layout_t *k = kbd_layout;
-     struct key_range *kr;
-Index: kvm-84.git-snapshot-20090303/qemu/keymaps.h
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/keymaps.h
-@@ -0,0 +1,60 @@
-+/*
-+ * QEMU keysym to keycode conversion using rdesktop keymaps
-+ *
-+ * Copyright (c) 2004 Johannes Schindelin
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#ifndef __QEMU_KEYMAPS_H__
-+#define __QEMU_KEYMAPS_H__
-+
-+#include "qemu-common.h"
-+
-+typedef struct {
-+	const char* name;
-+	int keysym;
-+} name2keysym_t;
-+
-+struct key_range {
-+    int start;
-+    int end;
-+    struct key_range *next;
-+};
-+
-+#define MAX_NORMAL_KEYCODE 512
-+#define MAX_EXTRA_COUNT 256
-+typedef struct {
-+    uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
-+    struct {
-+	int keysym;
-+	uint16_t keycode;
-+    } keysym2keycode_extra[MAX_EXTRA_COUNT];
-+    int extra_count;
-+    struct key_range *keypad_range;
-+    struct key_range *numlock_range;
-+} kbd_layout_t;
-+
-+
-+void *init_keyboard_layout(const name2keysym_t *table, const char *language);
-+int keysym2scancode(void *kbd_layout, int keysym);
-+int keycode_is_keypad(void *kbd_layout, int keycode);
-+int keysym_is_numlock(void *kbd_layout, int keysym);
-+
-+#endif /* __QEMU_KEYMAPS_H__ */
-Index: kvm-84.git-snapshot-20090303/qemu/sdl.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/sdl.c
-+++ kvm-84.git-snapshot-20090303/qemu/sdl.c
-@@ -107,7 +107,6 @@ static void sdl_resize(DisplayState *ds)
- /* generic keyboard conversion */
- 
- #include "sdl_keysym.h"
--#include "keymaps.c"
- 
- static kbd_layout_t *kbd_layout = NULL;
- 
-@@ -623,7 +622,7 @@ void sdl_display_init(DisplayState *ds, 
-         keyboard_layout = "en-us";
- #endif
-     if(keyboard_layout) {
--        kbd_layout = init_keyboard_layout(keyboard_layout);
-+        kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
-         if (!kbd_layout)
-             exit(1);
-     }
-Index: kvm-84.git-snapshot-20090303/qemu/sdl_keysym.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/sdl_keysym.h
-+++ kvm-84.git-snapshot-20090303/qemu/sdl_keysym.h
-@@ -1,7 +1,6 @@
--typedef struct {
--	const char* name;
--	int keysym;
--} name2keysym_t;
-+
-+#include "keymaps.h"
-+
- static const name2keysym_t name2keysym[]={
- /* ascii */
-     { "space",                0x020},
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -35,7 +35,6 @@
- 
- #include "vnc.h"
- #include "vnc_keysym.h"
--#include "keymaps.c"
- #include "d3des.h"
- 
- #ifdef CONFIG_VNC_TLS
-@@ -2420,9 +2419,9 @@ void vnc_display_init(DisplayState *ds)
-     vs->ds = ds;
- 
-     if (keyboard_layout)
--        vs->kbd_layout = init_keyboard_layout(keyboard_layout);
-+        vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
-     else
--        vs->kbd_layout = init_keyboard_layout("en-us");
-+        vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
- 
-     if (!vs->kbd_layout)
- 	exit(1);
-Index: kvm-84.git-snapshot-20090303/qemu/vnc_keysym.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc_keysym.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc_keysym.h
-@@ -1,7 +1,6 @@
--typedef struct {
--	const char* name;
--	int keysym;
--} name2keysym_t;
-+
-+#include "keymaps.h"
-+
- static const name2keysym_t name2keysym[]={
- /* ascii */
-     { "space",                0x020},
diff --git a/qemu-sasl-04-vnc-struct.patch b/qemu-sasl-04-vnc-struct.patch
deleted file mode 100644
index 0863596..0000000
--- a/qemu-sasl-04-vnc-struct.patch
+++ /dev/null
@@ -1,315 +0,0 @@
-This patch moves the definitions of VncState and VncDisplay structs
-out into a vnc.h header file. This is to allow the code for TLS
-and SASL auth mechanisms to be moved out of the main vnc.c file.
-
-
- vnc.c |  109 ------------------------------------------------
- vnc.h |  149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 148 insertions(+), 110 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -3,6 +3,7 @@
-  *
-  * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
-  * Copyright (C) 2006 Fabrice Bellard
-+ * Copyright (C) 2009 Red Hat, Inc
-  *
-  * Permission is hereby granted, free of charge, to any person obtaining a copy
-  * of this software and associated documentation files (the "Software"), to deal
-@@ -23,25 +24,16 @@
-  * THE SOFTWARE.
-  */
- 
--#include "qemu-common.h"
--#include "console.h"
-+#include "vnc.h"
- #include "sysemu.h"
- #include "qemu_socket.h"
- #include "qemu-timer.h"
--#include "audio/audio.h"
--#include <zlib.h>
- 
- #define VNC_REFRESH_INTERVAL (1000 / 30)
- 
--#include "vnc.h"
- #include "vnc_keysym.h"
- #include "d3des.h"
- 
--#ifdef CONFIG_VNC_TLS
--#include <gnutls/gnutls.h>
--#include <gnutls/x509.h>
--#endif /* CONFIG_VNC_TLS */
--
- // #define _VNC_DEBUG 1
- 
- #ifdef _VNC_DEBUG
-@@ -64,103 +56,6 @@ static void vnc_debug_gnutls_log(int lev
-     } \
- }
- 
--typedef struct Buffer
--{
--    size_t capacity;
--    size_t offset;
--    uint8_t *buffer;
--} Buffer;
--
--typedef struct VncState VncState;
--
--typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
--
--typedef void VncWritePixels(VncState *vs, void *data, int size);
--
--typedef void VncSendHextileTile(VncState *vs,
--                                int x, int y, int w, int h,
--                                void *last_bg,
--                                void *last_fg,
--                                int *has_bg, int *has_fg);
--
--#define VNC_MAX_WIDTH 2048
--#define VNC_MAX_HEIGHT 2048
--#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
--
--#define VNC_AUTH_CHALLENGE_SIZE 16
--
--typedef struct VncDisplay VncDisplay;
--
--struct VncDisplay
--{
--    int lsock;
--    DisplayState *ds;
--    VncState *clients;
--    kbd_layout_t *kbd_layout;
--
--    char *display;
--    char *password;
--    int auth;
--#ifdef CONFIG_VNC_TLS
--    int subauth;
--    int x509verify;
--
--    char *x509cacert;
--    char *x509cacrl;
--    char *x509cert;
--    char *x509key;
--#endif
--};
--
--struct VncState
--{
--    QEMUTimer *timer;
--    int csock;
--    DisplayState *ds;
--    VncDisplay *vd;
--    int need_update;
--    uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
--    char *old_data;
--    uint32_t features;
--    int absolute;
--    int last_x;
--    int last_y;
--
--    uint32_t vnc_encoding;
--    uint8_t tight_quality;
--    uint8_t tight_compression;
--
--    int major;
--    int minor;
--
--    char challenge[VNC_AUTH_CHALLENGE_SIZE];
--
--#ifdef CONFIG_VNC_TLS
--    int wiremode;
--    gnutls_session_t tls_session;
--#endif
--
--    Buffer output;
--    Buffer input;
--    /* current output mode information */
--    VncWritePixels *write_pixels;
--    VncSendHextileTile *send_hextile_tile;
--    DisplaySurface clientds, serverds;
--
--    CaptureVoiceOut *audio_cap;
--    struct audsettings as;
--
--    VncReadEvent *read_handler;
--    size_t read_handler_expect;
--    /* input */
--    uint8_t modifiers_state[256];
--
--    Buffer zlib;
--    Buffer zlib_tmp;
--    z_stream zlib_stream[4];
--
--    VncState *next;
--};
- 
- static VncDisplay *vnc_display; /* needed for info vnc */
- static DisplayChangeListener *dcl;
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.h
-@@ -1,5 +1,148 @@
--#ifndef __VNCTIGHT_H
--#define __VNCTIGHT_H
-+/*
-+ * QEMU VNC display driver
-+ *
-+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
-+ * Copyright (C) 2006 Fabrice Bellard
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#ifndef __QEMU_VNC_H
-+#define __QEMU_VNC_H
-+
-+#include "qemu-common.h"
-+#include "console.h"
-+#include "audio/audio.h"
-+#include <zlib.h>
-+
-+#ifdef CONFIG_VNC_TLS
-+#include <gnutls/gnutls.h>
-+#include <gnutls/x509.h>
-+#endif /* CONFIG_VNC_TLS */
-+
-+#include "keymaps.h"
-+
-+/*****************************************************************************
-+ *
-+ * Core data structures
-+ *
-+ *****************************************************************************/
-+
-+typedef struct Buffer
-+{
-+    size_t capacity;
-+    size_t offset;
-+    uint8_t *buffer;
-+} Buffer;
-+
-+typedef struct VncState VncState;
-+
-+typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
-+
-+typedef void VncWritePixels(VncState *vs, void *data, int size);
-+
-+typedef void VncSendHextileTile(VncState *vs,
-+                                int x, int y, int w, int h,
-+                                void *last_bg,
-+                                void *last_fg,
-+                                int *has_bg, int *has_fg);
-+
-+#define VNC_MAX_WIDTH 2048
-+#define VNC_MAX_HEIGHT 2048
-+#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
-+
-+#define VNC_AUTH_CHALLENGE_SIZE 16
-+
-+typedef struct VncDisplay VncDisplay;
-+
-+struct VncDisplay
-+{
-+    int lsock;
-+    DisplayState *ds;
-+    VncState *clients;
-+    kbd_layout_t *kbd_layout;
-+
-+    char *display;
-+    char *password;
-+    int auth;
-+#ifdef CONFIG_VNC_TLS
-+    int subauth;
-+    int x509verify;
-+
-+    char *x509cacert;
-+    char *x509cacrl;
-+    char *x509cert;
-+    char *x509key;
-+#endif
-+};
-+
-+struct VncState
-+{
-+    QEMUTimer *timer;
-+    int csock;
-+    DisplayState *ds;
-+    VncDisplay *vd;
-+    int need_update;
-+    uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
-+    char *old_data;
-+    uint32_t features;
-+    int absolute;
-+    int last_x;
-+    int last_y;
-+
-+    uint32_t vnc_encoding;
-+    uint8_t tight_quality;
-+    uint8_t tight_compression;
-+
-+    int major;
-+    int minor;
-+
-+    char challenge[VNC_AUTH_CHALLENGE_SIZE];
-+
-+#ifdef CONFIG_VNC_TLS
-+    int wiremode;
-+    gnutls_session_t tls_session;
-+#endif
-+
-+    Buffer output;
-+    Buffer input;
-+    /* current output mode information */
-+    VncWritePixels *write_pixels;
-+    VncSendHextileTile *send_hextile_tile;
-+    DisplaySurface clientds, serverds;
-+
-+    CaptureVoiceOut *audio_cap;
-+    struct audsettings as;
-+
-+    VncReadEvent *read_handler;
-+    size_t read_handler_expect;
-+    /* input */
-+    uint8_t modifiers_state[256];
-+
-+    Buffer zlib;
-+    Buffer zlib_tmp;
-+    z_stream zlib_stream[4];
-+
-+    VncState *next;
-+};
-+
- 
- /*****************************************************************************
-  *
-@@ -111,4 +254,4 @@ enum {
- #define VNC_FEATURE_ZLIB_MASK                (1 << VNC_FEATURE_ZLIB)
- #define VNC_FEATURE_COPYRECT_MASK            (1 << VNC_FEATURE_COPYRECT)
- 
--#endif /* __VNCTIGHT_H */
-+#endif /* __QEMU_VNC_H */
diff --git a/qemu-sasl-05-vnc-tls-vencrypt.patch b/qemu-sasl-05-vnc-tls-vencrypt.patch
deleted file mode 100644
index c9fadea..0000000
--- a/qemu-sasl-05-vnc-tls-vencrypt.patch
+++ /dev/null
@@ -1,1681 +0,0 @@
-This patch refactors the existing TLS code to make the main VNC code
-more managable. The code moves to two new files
-
- - vnc-tls.c: generic helpers for TLS handshake & credential setup
- - vnc-auth-vencrypt.c: the actual VNC TLS authentication mechanism.
-
-The reason for this split is that there are other TLS based auth
-mechanisms which we may like to use in the future. These can all
-share the same vnc-tls.c routines. In addition this will facilitate
-anyone who may want to port the vnc-tls.c file to allow for choice
-of GNUTLS & NSS for impl.
-
-The TLS state is moved out of the VncState struct, and into a separate
-VncStateTLS struct, defined in vnc-tls.h. This is then referenced from
-the main VncState. End size of the struct is the same, but it keeps
-things a little more managable.
-
-The vnc.h file gains a bunch more function prototypes, for functions
-in vnc.c that were previously static, but now need to be accessed
-from the separate auth code files.
-
-The only TLS related code still in the main vl.c is the command line
-argument handling / setup, and the low level I/O routines calling
-gnutls_send/recv.
-
-
- Makefile              |   11 
- b/vnc-auth-vencrypt.c |  167 ++++++++++++++
- b/vnc-auth-vencrypt.h |   33 ++
- b/vnc-tls.c           |  414 +++++++++++++++++++++++++++++++++++
- b/vnc-tls.h           |   70 ++++++
- vnc.c                 |  581 +++-----------------------------------------------
- vnc.h                 |   76 ++++--
- 7 files changed, 780 insertions(+), 572 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/Makefile
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/Makefile
-+++ kvm-84.git-snapshot-20090303/qemu/Makefile
-@@ -149,6 +149,9 @@ ifdef CONFIG_CURSES
- OBJS+=curses.o
- endif
- OBJS+=vnc.o d3des.o
-+ifdef CONFIG_VNC_TLS
-+OBJS+=vnc-tls.o vnc-auth-vencrypt.o
-+endif
- 
- ifdef CONFIG_COCOA
- OBJS+=cocoa.o
-@@ -172,10 +175,16 @@ sdl.o: sdl.c keymaps.h sdl_keysym.h
- 
- sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
- 
--vnc.o: vnc.c keymaps.h sdl_keysym.h vnchextile.h d3des.c d3des.h
-+vnc.h: vnc-tls.h vnc-auth-vencrypt.h keymaps.h
-+
-+vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h
- 
- vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
- 
-+vnc-tls.o: vnc-tls.c vnc.h
-+
-+vnc-auth-vencrypt.o: vnc-auth-vencrypt.c vnc.h
-+
- curses.o: curses.c keymaps.h curses_keys.h
- 
- bt-host.o: CFLAGS += $(CONFIG_BLUEZ_CFLAGS)
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-vencrypt.c
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-vencrypt.c
-@@ -0,0 +1,167 @@
-+/*
-+ * QEMU VNC display driver: VeNCrypt authentication setup
-+ *
-+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
-+ * Copyright (C) 2006 Fabrice Bellard
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "vnc.h"
-+
-+
-+static void start_auth_vencrypt_subauth(VncState *vs)
-+{
-+    switch (vs->vd->subauth) {
-+    case VNC_AUTH_VENCRYPT_TLSNONE:
-+    case VNC_AUTH_VENCRYPT_X509NONE:
-+       VNC_DEBUG("Accept TLS auth none\n");
-+       vnc_write_u32(vs, 0); /* Accept auth completion */
-+       start_client_init(vs);
-+       break;
-+
-+    case VNC_AUTH_VENCRYPT_TLSVNC:
-+    case VNC_AUTH_VENCRYPT_X509VNC:
-+       VNC_DEBUG("Start TLS auth VNC\n");
-+       start_auth_vnc(vs);
-+       break;
-+
-+    default: /* Should not be possible, but just in case */
-+       VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
-+       vnc_write_u8(vs, 1);
-+       if (vs->minor >= 8) {
-+           static const char err[] = "Unsupported authentication type";
-+           vnc_write_u32(vs, sizeof(err));
-+           vnc_write(vs, err, sizeof(err));
-+       }
-+       vnc_client_error(vs);
-+    }
-+}
-+
-+static void vnc_tls_handshake_io(void *opaque);
-+
-+static int vnc_start_vencrypt_handshake(struct VncState *vs) {
-+    int ret;
-+
-+    if ((ret = gnutls_handshake(vs->tls.session)) < 0) {
-+       if (!gnutls_error_is_fatal(ret)) {
-+           VNC_DEBUG("Handshake interrupted (blocking)\n");
-+           if (!gnutls_record_get_direction(vs->tls.session))
-+               qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs);
-+           else
-+               qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs);
-+           return 0;
-+       }
-+       VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
-+       vnc_client_error(vs);
-+       return -1;
-+    }
-+
-+    if (vs->vd->tls.x509verify) {
-+	if (vnc_tls_validate_certificate(vs) < 0) {
-+	    VNC_DEBUG("Client verification failed\n");
-+	    vnc_client_error(vs);
-+	    return -1;
-+	} else {
-+	    VNC_DEBUG("Client verification passed\n");
-+	}
-+    }
-+
-+    VNC_DEBUG("Handshake done, switching to TLS data mode\n");
-+    vs->tls.wiremode = VNC_WIREMODE_TLS;
-+    qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
-+
-+    start_auth_vencrypt_subauth(vs);
-+
-+    return 0;
-+}
-+
-+static void vnc_tls_handshake_io(void *opaque) {
-+    struct VncState *vs = (struct VncState *)opaque;
-+
-+    VNC_DEBUG("Handshake IO continue\n");
-+    vnc_start_vencrypt_handshake(vs);
-+}
-+
-+
-+
-+#define NEED_X509_AUTH(vs)			      \
-+    ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
-+     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
-+     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
-+
-+
-+static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
-+{
-+    int auth = read_u32(data, 0);
-+
-+    if (auth != vs->vd->subauth) {
-+	VNC_DEBUG("Rejecting auth %d\n", auth);
-+	vnc_write_u8(vs, 0); /* Reject auth */
-+	vnc_flush(vs);
-+	vnc_client_error(vs);
-+    } else {
-+	VNC_DEBUG("Accepting auth %d, setting up TLS for handshake\n", auth);
-+	vnc_write_u8(vs, 1); /* Accept auth */
-+	vnc_flush(vs);
-+
-+	if (vnc_tls_client_setup(vs, NEED_X509_AUTH(vs)) < 0) {
-+	    VNC_DEBUG("Failed to setup TLS\n");
-+	    return 0;
-+	}
-+
-+	VNC_DEBUG("Start TLS VeNCrypt handshake process\n");
-+	if (vnc_start_vencrypt_handshake(vs) < 0) {
-+	    VNC_DEBUG("Failed to start TLS handshake\n");
-+	    return 0;
-+	}
-+    }
-+    return 0;
-+}
-+
-+static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
-+{
-+    if (data[0] != 0 ||
-+	data[1] != 2) {
-+	VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
-+	vnc_write_u8(vs, 1); /* Reject version */
-+	vnc_flush(vs);
-+	vnc_client_error(vs);
-+    } else {
-+	VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);
-+	vnc_write_u8(vs, 0); /* Accept version */
-+	vnc_write_u8(vs, 1); /* Number of sub-auths */
-+	vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */
-+	vnc_flush(vs);
-+	vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
-+    }
-+    return 0;
-+}
-+
-+
-+void start_auth_vencrypt(VncState *vs)
-+{
-+    /* Send VeNCrypt version 0.2 */
-+    vnc_write_u8(vs, 0);
-+    vnc_write_u8(vs, 2);
-+
-+    vnc_read_when(vs, protocol_client_vencrypt_init, 2);
-+}
-+
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-vencrypt.h
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-vencrypt.h
-@@ -0,0 +1,33 @@
-+/*
-+ * QEMU VNC display driver
-+ *
-+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
-+ * Copyright (C) 2006 Fabrice Bellard
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+
-+#ifndef __QEMU_VNC_AUTH_VENCRYPT_H__
-+#define __QEMU_VNC_AUTH_VENCRYPT_H__
-+
-+void start_auth_vencrypt(VncState *vs);
-+
-+#endif /* __QEMU_VNC_AUTH_VENCRYPT_H__ */
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
-@@ -0,0 +1,414 @@
-+/*
-+ * QEMU VNC display driver: TLS helpers
-+ *
-+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
-+ * Copyright (C) 2006 Fabrice Bellard
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "vnc.h"
-+#include "qemu_socket.h"
-+
-+#if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
-+/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
-+static void vnc_debug_gnutls_log(int level, const char* str) {
-+    VNC_DEBUG("%d %s", level, str);
-+}
-+#endif /* defined(_VNC_DEBUG) && _VNC_DEBUG >= 2 */
-+
-+
-+#define DH_BITS 1024
-+static gnutls_dh_params_t dh_params;
-+
-+static int vnc_tls_initialize(void)
-+{
-+    static int tlsinitialized = 0;
-+
-+    if (tlsinitialized)
-+	return 1;
-+
-+    if (gnutls_global_init () < 0)
-+	return 0;
-+
-+    /* XXX ought to re-generate diffie-hellmen params periodically */
-+    if (gnutls_dh_params_init (&dh_params) < 0)
-+	return 0;
-+    if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
-+	return 0;
-+
-+#if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
-+    gnutls_global_set_log_level(10);
-+    gnutls_global_set_log_function(vnc_debug_gnutls_log);
-+#endif
-+
-+    tlsinitialized = 1;
-+
-+    return 1;
-+}
-+
-+static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
-+			    const void *data,
-+			    size_t len) {
-+    struct VncState *vs = (struct VncState *)transport;
-+    int ret;
-+
-+ retry:
-+    ret = send(vs->csock, data, len, 0);
-+    if (ret < 0) {
-+	if (errno == EINTR)
-+	    goto retry;
-+	return -1;
-+    }
-+    return ret;
-+}
-+
-+
-+static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
-+			    void *data,
-+			    size_t len) {
-+    struct VncState *vs = (struct VncState *)transport;
-+    int ret;
-+
-+ retry:
-+    ret = recv(vs->csock, data, len, 0);
-+    if (ret < 0) {
-+	if (errno == EINTR)
-+	    goto retry;
-+	return -1;
-+    }
-+    return ret;
-+}
-+
-+
-+static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
-+{
-+    gnutls_anon_server_credentials anon_cred;
-+    int ret;
-+
-+    if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
-+	VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
-+	return NULL;
-+    }
-+
-+    gnutls_anon_set_server_dh_params(anon_cred, dh_params);
-+
-+    return anon_cred;
-+}
-+
-+
-+static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncDisplay *vd)
-+{
-+    gnutls_certificate_credentials_t x509_cred;
-+    int ret;
-+
-+    if (!vd->tls.x509cacert) {
-+	VNC_DEBUG("No CA x509 certificate specified\n");
-+	return NULL;
-+    }
-+    if (!vd->tls.x509cert) {
-+	VNC_DEBUG("No server x509 certificate specified\n");
-+	return NULL;
-+    }
-+    if (!vd->tls.x509key) {
-+	VNC_DEBUG("No server private key specified\n");
-+	return NULL;
-+    }
-+
-+    if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
-+	VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
-+	return NULL;
-+    }
-+    if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
-+						      vd->tls.x509cacert,
-+						      GNUTLS_X509_FMT_PEM)) < 0) {
-+	VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
-+	gnutls_certificate_free_credentials(x509_cred);
-+	return NULL;
-+    }
-+
-+    if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
-+						     vd->tls.x509cert,
-+						     vd->tls.x509key,
-+						     GNUTLS_X509_FMT_PEM)) < 0) {
-+	VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
-+	gnutls_certificate_free_credentials(x509_cred);
-+	return NULL;
-+    }
-+
-+    if (vd->tls.x509cacrl) {
-+	if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
-+							vd->tls.x509cacrl,
-+							GNUTLS_X509_FMT_PEM)) < 0) {
-+	    VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
-+	    gnutls_certificate_free_credentials(x509_cred);
-+	    return NULL;
-+	}
-+    }
-+
-+    gnutls_certificate_set_dh_params (x509_cred, dh_params);
-+
-+    return x509_cred;
-+}
-+
-+
-+int vnc_tls_validate_certificate(struct VncState *vs)
-+{
-+    int ret;
-+    unsigned int status;
-+    const gnutls_datum_t *certs;
-+    unsigned int nCerts, i;
-+    time_t now;
-+
-+    VNC_DEBUG("Validating client certificate\n");
-+    if ((ret = gnutls_certificate_verify_peers2 (vs->tls.session, &status)) < 0) {
-+	VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
-+	return -1;
-+    }
-+
-+    if ((now = time(NULL)) == ((time_t)-1)) {
-+	return -1;
-+    }
-+
-+    if (status != 0) {
-+	if (status & GNUTLS_CERT_INVALID)
-+	    VNC_DEBUG("The certificate is not trusted.\n");
-+
-+	if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-+	    VNC_DEBUG("The certificate hasn't got a known issuer.\n");
-+
-+	if (status & GNUTLS_CERT_REVOKED)
-+	    VNC_DEBUG("The certificate has been revoked.\n");
-+
-+	if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
-+	    VNC_DEBUG("The certificate uses an insecure algorithm\n");
-+
-+	return -1;
-+    } else {
-+	VNC_DEBUG("Certificate is valid!\n");
-+    }
-+
-+    /* Only support x509 for now */
-+    if (gnutls_certificate_type_get(vs->tls.session) != GNUTLS_CRT_X509)
-+	return -1;
-+
-+    if (!(certs = gnutls_certificate_get_peers(vs->tls.session, &nCerts)))
-+	return -1;
-+
-+    for (i = 0 ; i < nCerts ; i++) {
-+	gnutls_x509_crt_t cert;
-+	VNC_DEBUG ("Checking certificate chain %d\n", i);
-+	if (gnutls_x509_crt_init (&cert) < 0)
-+	    return -1;
-+
-+	if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
-+	    gnutls_x509_crt_deinit (cert);
-+	    return -1;
-+	}
-+
-+	if (gnutls_x509_crt_get_expiration_time (cert) < now) {
-+	    VNC_DEBUG("The certificate has expired\n");
-+	    gnutls_x509_crt_deinit (cert);
-+	    return -1;
-+	}
-+
-+	if (gnutls_x509_crt_get_activation_time (cert) > now) {
-+	    VNC_DEBUG("The certificate is not yet activated\n");
-+	    gnutls_x509_crt_deinit (cert);
-+	    return -1;
-+	}
-+
-+	if (gnutls_x509_crt_get_activation_time (cert) > now) {
-+	    VNC_DEBUG("The certificate is not yet activated\n");
-+	    gnutls_x509_crt_deinit (cert);
-+	    return -1;
-+	}
-+
-+	gnutls_x509_crt_deinit (cert);
-+    }
-+
-+    return 0;
-+}
-+
-+
-+int vnc_tls_client_setup(struct VncState *vs,
-+			 int needX509Creds) {
-+    static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
-+    static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
-+    static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
-+    static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
-+
-+    VNC_DEBUG("Do TLS setup\n");
-+    if (vnc_tls_initialize() < 0) {
-+	VNC_DEBUG("Failed to init TLS\n");
-+	vnc_client_error(vs);
-+	return -1;
-+    }
-+    if (vs->tls.session == NULL) {
-+	if (gnutls_init(&vs->tls.session, GNUTLS_SERVER) < 0) {
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+
-+	if (gnutls_set_default_priority(vs->tls.session) < 0) {
-+	    gnutls_deinit(vs->tls.session);
-+	    vs->tls.session = NULL;
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+
-+	if (gnutls_kx_set_priority(vs->tls.session, needX509Creds ? kx_x509 : kx_anon) < 0) {
-+	    gnutls_deinit(vs->tls.session);
-+	    vs->tls.session = NULL;
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+
-+	if (gnutls_certificate_type_set_priority(vs->tls.session, cert_type_priority) < 0) {
-+	    gnutls_deinit(vs->tls.session);
-+	    vs->tls.session = NULL;
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+
-+	if (gnutls_protocol_set_priority(vs->tls.session, protocol_priority) < 0) {
-+	    gnutls_deinit(vs->tls.session);
-+	    vs->tls.session = NULL;
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+
-+	if (needX509Creds) {
-+	    gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs->vd);
-+	    if (!x509_cred) {
-+		gnutls_deinit(vs->tls.session);
-+		vs->tls.session = NULL;
-+		vnc_client_error(vs);
-+		return -1;
-+	    }
-+	    if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
-+		gnutls_deinit(vs->tls.session);
-+		vs->tls.session = NULL;
-+		gnutls_certificate_free_credentials(x509_cred);
-+		vnc_client_error(vs);
-+		return -1;
-+	    }
-+	    if (vs->vd->tls.x509verify) {
-+		VNC_DEBUG("Requesting a client certificate\n");
-+		gnutls_certificate_server_set_request (vs->tls.session, GNUTLS_CERT_REQUEST);
-+	    }
-+
-+	} else {
-+	    gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
-+	    if (!anon_cred) {
-+		gnutls_deinit(vs->tls.session);
-+		vs->tls.session = NULL;
-+		vnc_client_error(vs);
-+		return -1;
-+	    }
-+	    if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_ANON, anon_cred) < 0) {
-+		gnutls_deinit(vs->tls.session);
-+		vs->tls.session = NULL;
-+		gnutls_anon_free_server_credentials(anon_cred);
-+		vnc_client_error(vs);
-+		return -1;
-+	    }
-+	}
-+
-+	gnutls_transport_set_ptr(vs->tls.session, (gnutls_transport_ptr_t)vs);
-+	gnutls_transport_set_push_function(vs->tls.session, vnc_tls_push);
-+	gnutls_transport_set_pull_function(vs->tls.session, vnc_tls_pull);
-+    }
-+    return 0;
-+}
-+
-+
-+void vnc_tls_client_cleanup(struct VncState *vs)
-+{
-+    if (vs->tls.session) {
-+	gnutls_deinit(vs->tls.session);
-+	vs->tls.session = NULL;
-+    }
-+    vs->tls.wiremode = VNC_WIREMODE_CLEAR;
-+}
-+
-+
-+
-+static int vnc_set_x509_credential(VncDisplay *vd,
-+				   const char *certdir,
-+				   const char *filename,
-+				   char **cred,
-+				   int ignoreMissing)
-+{
-+    struct stat sb;
-+
-+    if (*cred) {
-+	qemu_free(*cred);
-+	*cred = NULL;
-+    }
-+
-+    *cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2);
-+
-+    strcpy(*cred, certdir);
-+    strcat(*cred, "/");
-+    strcat(*cred, filename);
-+
-+    VNC_DEBUG("Check %s\n", *cred);
-+    if (stat(*cred, &sb) < 0) {
-+	qemu_free(*cred);
-+	*cred = NULL;
-+	if (ignoreMissing && errno == ENOENT)
-+	    return 0;
-+	return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+
-+#define X509_CA_CERT_FILE "ca-cert.pem"
-+#define X509_CA_CRL_FILE "ca-crl.pem"
-+#define X509_SERVER_KEY_FILE "server-key.pem"
-+#define X509_SERVER_CERT_FILE "server-cert.pem"
-+
-+
-+int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
-+			       const char *certdir)
-+{
-+    if (vnc_set_x509_credential(vd, certdir, X509_CA_CERT_FILE, &vd->tls.x509cacert, 0) < 0)
-+	goto cleanup;
-+    if (vnc_set_x509_credential(vd, certdir, X509_CA_CRL_FILE, &vd->tls.x509cacrl, 1) < 0)
-+	goto cleanup;
-+    if (vnc_set_x509_credential(vd, certdir, X509_SERVER_CERT_FILE, &vd->tls.x509cert, 0) < 0)
-+	goto cleanup;
-+    if (vnc_set_x509_credential(vd, certdir, X509_SERVER_KEY_FILE, &vd->tls.x509key, 0) < 0)
-+	goto cleanup;
-+
-+    return 0;
-+
-+ cleanup:
-+    qemu_free(vd->tls.x509cacert);
-+    qemu_free(vd->tls.x509cacrl);
-+    qemu_free(vd->tls.x509cert);
-+    qemu_free(vd->tls.x509key);
-+    vd->tls.x509cacert = vd->tls.x509cacrl = vd->tls.x509cert = vd->tls.x509key = NULL;
-+    return -1;
-+}
-+
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
-@@ -0,0 +1,70 @@
-+/*
-+ * QEMU VNC display driver. TLS helpers
-+ *
-+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
-+ * Copyright (C) 2006 Fabrice Bellard
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+
-+#ifndef __QEMU_VNC_TLS_H__
-+#define __QEMU_VNC_TLS_H__
-+
-+#include <gnutls/gnutls.h>
-+#include <gnutls/x509.h>
-+
-+enum {
-+    VNC_WIREMODE_CLEAR,
-+    VNC_WIREMODE_TLS,
-+};
-+
-+typedef struct VncDisplayTLS VncDisplayTLS;
-+typedef struct VncStateTLS VncStateTLS;
-+
-+/* Server state */
-+struct VncDisplayTLS {
-+    int x509verify; /* Non-zero if server requests & validates client cert */
-+
-+    /* Paths to x509 certs/keys */
-+    char *x509cacert;
-+    char *x509cacrl;
-+    char *x509cert;
-+    char *x509key;
-+};
-+
-+/* Per client state */
-+struct VncStateTLS {
-+    /* Whether data is being TLS encrypted yet */
-+    int wiremode;
-+    gnutls_session_t session;
-+};
-+
-+int vnc_tls_client_setup(VncState *vs, int x509Creds);
-+void vnc_tls_client_cleanup(VncState *vs);
-+
-+int vnc_tls_validate_certificate(VncState *vs);
-+
-+int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
-+			       const char *path);
-+
-+
-+#endif /* __QEMU_VNC_TLS_H__ */
-+
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -34,21 +34,6 @@
- #include "vnc_keysym.h"
- #include "d3des.h"
- 
--// #define _VNC_DEBUG 1
--
--#ifdef _VNC_DEBUG
--#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
--
--#if defined(CONFIG_VNC_TLS) && _VNC_DEBUG >= 2
--/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
--static void vnc_debug_gnutls_log(int level, const char* str) {
--    VNC_DEBUG("%d %s", level, str);
--}
--#endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
--#else
--#define VNC_DEBUG(fmt, ...) do { } while (0)
--#endif
--
- #define count_bits(c, v) { \
-     for (c = 0; v; v >>= 1) \
-     { \
-@@ -204,14 +189,7 @@ static inline uint32_t vnc_has_feature(V
-    3) resolutions > 1024
- */
- 
--static void vnc_write(VncState *vs, const void *data, size_t len);
--static void vnc_write_u32(VncState *vs, uint32_t value);
--static void vnc_write_s32(VncState *vs, int32_t value);
--static void vnc_write_u16(VncState *vs, uint16_t value);
--static void vnc_write_u8(VncState *vs, uint8_t value);
--static void vnc_flush(VncState *vs);
- static void vnc_update_client(void *opaque);
--static void vnc_client_read(void *opaque);
- 
- static void vnc_colordepth(VncState *vs);
- 
-@@ -867,10 +845,7 @@ static int vnc_client_io_error(VncState 
-         if (vs->input.buffer) qemu_free(vs->input.buffer);
-         if (vs->output.buffer) qemu_free(vs->output.buffer);
- #ifdef CONFIG_VNC_TLS
--	if (vs->tls_session) {
--	    gnutls_deinit(vs->tls_session);
--	    vs->tls_session = NULL;
--	}
-+	vnc_tls_client_cleanup(vs);
- #endif /* CONFIG_VNC_TLS */
-         audio_del(vs);
- 
-@@ -896,19 +871,20 @@ static int vnc_client_io_error(VncState 
-     return ret;
- }
- 
--static void vnc_client_error(VncState *vs)
-+
-+void vnc_client_error(VncState *vs)
- {
-     vnc_client_io_error(vs, -1, EINVAL);
- }
- 
--static void vnc_client_write(void *opaque)
-+void vnc_client_write(void *opaque)
- {
-     long ret;
-     VncState *vs = opaque;
- 
- #ifdef CONFIG_VNC_TLS
--    if (vs->tls_session) {
--	ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
-+    if (vs->tls.session) {
-+	ret = gnutls_write(vs->tls.session, vs->output.buffer, vs->output.offset);
- 	if (ret < 0) {
- 	    if (ret == GNUTLS_E_AGAIN)
- 		errno = EAGAIN;
-@@ -931,13 +907,13 @@ static void vnc_client_write(void *opaqu
-     }
- }
- 
--static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-+void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
- {
-     vs->read_handler = func;
-     vs->read_handler_expect = expecting;
- }
- 
--static void vnc_client_read(void *opaque)
-+void vnc_client_read(void *opaque)
- {
-     VncState *vs = opaque;
-     long ret;
-@@ -945,8 +921,8 @@ static void vnc_client_read(void *opaque
-     buffer_reserve(&vs->input, 4096);
- 
- #ifdef CONFIG_VNC_TLS
--    if (vs->tls_session) {
--	ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
-+    if (vs->tls.session) {
-+	ret = gnutls_read(vs->tls.session, buffer_end(&vs->input), 4096);
- 	if (ret < 0) {
- 	    if (ret == GNUTLS_E_AGAIN)
- 		errno = EAGAIN;
-@@ -980,7 +956,7 @@ static void vnc_client_read(void *opaque
-     }
- }
- 
--static void vnc_write(VncState *vs, const void *data, size_t len)
-+void vnc_write(VncState *vs, const void *data, size_t len)
- {
-     buffer_reserve(&vs->output, len);
- 
-@@ -991,12 +967,12 @@ static void vnc_write(VncState *vs, cons
-     buffer_append(&vs->output, data, len);
- }
- 
--static void vnc_write_s32(VncState *vs, int32_t value)
-+void vnc_write_s32(VncState *vs, int32_t value)
- {
-     vnc_write_u32(vs, *(uint32_t *)&value);
- }
- 
--static void vnc_write_u32(VncState *vs, uint32_t value)
-+void vnc_write_u32(VncState *vs, uint32_t value)
- {
-     uint8_t buf[4];
- 
-@@ -1008,7 +984,7 @@ static void vnc_write_u32(VncState *vs, 
-     vnc_write(vs, buf, 4);
- }
- 
--static void vnc_write_u16(VncState *vs, uint16_t value)
-+void vnc_write_u16(VncState *vs, uint16_t value)
- {
-     uint8_t buf[2];
- 
-@@ -1018,74 +994,39 @@ static void vnc_write_u16(VncState *vs, 
-     vnc_write(vs, buf, 2);
- }
- 
--static void vnc_write_u8(VncState *vs, uint8_t value)
-+void vnc_write_u8(VncState *vs, uint8_t value)
- {
-     vnc_write(vs, (char *)&value, 1);
- }
- 
--static void vnc_flush(VncState *vs)
-+void vnc_flush(VncState *vs)
- {
-     if (vs->output.offset)
- 	vnc_client_write(vs);
- }
- 
--static uint8_t read_u8(uint8_t *data, size_t offset)
-+uint8_t read_u8(uint8_t *data, size_t offset)
- {
-     return data[offset];
- }
- 
--static uint16_t read_u16(uint8_t *data, size_t offset)
-+uint16_t read_u16(uint8_t *data, size_t offset)
- {
-     return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
- }
- 
--static int32_t read_s32(uint8_t *data, size_t offset)
-+int32_t read_s32(uint8_t *data, size_t offset)
- {
-     return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
- 		     (data[offset + 2] << 8) | data[offset + 3]);
- }
- 
--static uint32_t read_u32(uint8_t *data, size_t offset)
-+uint32_t read_u32(uint8_t *data, size_t offset)
- {
-     return ((data[offset] << 24) | (data[offset + 1] << 16) |
- 	    (data[offset + 2] << 8) | data[offset + 3]);
- }
- 
--#ifdef CONFIG_VNC_TLS
--static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
--                            const void *data,
--                            size_t len) {
--    struct VncState *vs = (struct VncState *)transport;
--    int ret;
--
-- retry:
--    ret = send(vs->csock, data, len, 0);
--    if (ret < 0) {
--	if (errno == EINTR)
--	    goto retry;
--	return -1;
--    }
--    return ret;
--}
--
--
--static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
--                            void *data,
--                            size_t len) {
--    struct VncState *vs = (struct VncState *)transport;
--    int ret;
--
-- retry:
--    ret = recv(vs->csock, data, len, 0);
--    if (ret < 0) {
--	if (errno == EINTR)
--	    goto retry;
--	return -1;
--    }
--    return ret;
--}
--#endif /* CONFIG_VNC_TLS */
--
- static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
- {
- }
-@@ -1668,6 +1609,11 @@ static int protocol_client_init(VncState
-     return 0;
- }
- 
-+void start_client_init(VncState *vs)
-+{
-+    vnc_read_when(vs, protocol_client_init, 1);
-+}
-+
- static void make_challenge(VncState *vs)
- {
-     int i;
-@@ -1723,12 +1669,12 @@ static int protocol_client_auth_vnc(VncS
- 	vnc_write_u32(vs, 0); /* Accept auth */
- 	vnc_flush(vs);
- 
--	vnc_read_when(vs, protocol_client_init, 1);
-+        start_client_init(vs);
-     }
-     return 0;
- }
- 
--static int start_auth_vnc(VncState *vs)
-+void start_auth_vnc(VncState *vs)
- {
-     make_challenge(vs);
-     /* Send client a 'random' challenge */
-@@ -1736,411 +1682,9 @@ static int start_auth_vnc(VncState *vs)
-     vnc_flush(vs);
- 
-     vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
--    return 0;
--}
--
--
--#ifdef CONFIG_VNC_TLS
--#define DH_BITS 1024
--static gnutls_dh_params_t dh_params;
--
--static int vnc_tls_initialize(void)
--{
--    static int tlsinitialized = 0;
--
--    if (tlsinitialized)
--	return 1;
--
--    if (gnutls_global_init () < 0)
--	return 0;
--
--    /* XXX ought to re-generate diffie-hellmen params periodically */
--    if (gnutls_dh_params_init (&dh_params) < 0)
--	return 0;
--    if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
--	return 0;
--
--#if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
--    gnutls_global_set_log_level(10);
--    gnutls_global_set_log_function(vnc_debug_gnutls_log);
--#endif
--
--    tlsinitialized = 1;
--
--    return 1;
--}
--
--static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
--{
--    gnutls_anon_server_credentials anon_cred;
--    int ret;
--
--    if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
--	VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
--	return NULL;
--    }
--
--    gnutls_anon_set_server_dh_params(anon_cred, dh_params);
--
--    return anon_cred;
- }
- 
- 
--static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
--{
--    gnutls_certificate_credentials_t x509_cred;
--    int ret;
--
--    if (!vs->vd->x509cacert) {
--	VNC_DEBUG("No CA x509 certificate specified\n");
--	return NULL;
--    }
--    if (!vs->vd->x509cert) {
--	VNC_DEBUG("No server x509 certificate specified\n");
--	return NULL;
--    }
--    if (!vs->vd->x509key) {
--	VNC_DEBUG("No server private key specified\n");
--	return NULL;
--    }
--
--    if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
--	VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
--	return NULL;
--    }
--    if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
--						      vs->vd->x509cacert,
--						      GNUTLS_X509_FMT_PEM)) < 0) {
--	VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
--	gnutls_certificate_free_credentials(x509_cred);
--	return NULL;
--    }
--
--    if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
--						     vs->vd->x509cert,
--						     vs->vd->x509key,
--						     GNUTLS_X509_FMT_PEM)) < 0) {
--	VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
--	gnutls_certificate_free_credentials(x509_cred);
--	return NULL;
--    }
--
--    if (vs->vd->x509cacrl) {
--	if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
--							vs->vd->x509cacrl,
--							GNUTLS_X509_FMT_PEM)) < 0) {
--	    VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
--	    gnutls_certificate_free_credentials(x509_cred);
--	    return NULL;
--	}
--    }
--
--    gnutls_certificate_set_dh_params (x509_cred, dh_params);
--
--    return x509_cred;
--}
--
--static int vnc_validate_certificate(struct VncState *vs)
--{
--    int ret;
--    unsigned int status;
--    const gnutls_datum_t *certs;
--    unsigned int nCerts, i;
--    time_t now;
--
--    VNC_DEBUG("Validating client certificate\n");
--    if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
--	VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
--	return -1;
--    }
--
--    if ((now = time(NULL)) == ((time_t)-1)) {
--	return -1;
--    }
--
--    if (status != 0) {
--	if (status & GNUTLS_CERT_INVALID)
--	    VNC_DEBUG("The certificate is not trusted.\n");
--
--	if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
--	    VNC_DEBUG("The certificate hasn't got a known issuer.\n");
--
--	if (status & GNUTLS_CERT_REVOKED)
--	    VNC_DEBUG("The certificate has been revoked.\n");
--
--	if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
--	    VNC_DEBUG("The certificate uses an insecure algorithm\n");
--
--	return -1;
--    } else {
--	VNC_DEBUG("Certificate is valid!\n");
--    }
--
--    /* Only support x509 for now */
--    if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
--	return -1;
--
--    if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
--	return -1;
--
--    for (i = 0 ; i < nCerts ; i++) {
--	gnutls_x509_crt_t cert;
--	VNC_DEBUG ("Checking certificate chain %d\n", i);
--	if (gnutls_x509_crt_init (&cert) < 0)
--	    return -1;
--
--	if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
--	    gnutls_x509_crt_deinit (cert);
--	    return -1;
--	}
--
--	if (gnutls_x509_crt_get_expiration_time (cert) < now) {
--	    VNC_DEBUG("The certificate has expired\n");
--	    gnutls_x509_crt_deinit (cert);
--	    return -1;
--	}
--
--	if (gnutls_x509_crt_get_activation_time (cert) > now) {
--	    VNC_DEBUG("The certificate is not yet activated\n");
--	    gnutls_x509_crt_deinit (cert);
--	    return -1;
--	}
--
--	if (gnutls_x509_crt_get_activation_time (cert) > now) {
--	    VNC_DEBUG("The certificate is not yet activated\n");
--	    gnutls_x509_crt_deinit (cert);
--	    return -1;
--	}
--
--	gnutls_x509_crt_deinit (cert);
--    }
--
--    return 0;
--}
--
--
--static int start_auth_vencrypt_subauth(VncState *vs)
--{
--    switch (vs->vd->subauth) {
--    case VNC_AUTH_VENCRYPT_TLSNONE:
--    case VNC_AUTH_VENCRYPT_X509NONE:
--       VNC_DEBUG("Accept TLS auth none\n");
--       vnc_write_u32(vs, 0); /* Accept auth completion */
--       vnc_read_when(vs, protocol_client_init, 1);
--       break;
--
--    case VNC_AUTH_VENCRYPT_TLSVNC:
--    case VNC_AUTH_VENCRYPT_X509VNC:
--       VNC_DEBUG("Start TLS auth VNC\n");
--       return start_auth_vnc(vs);
--
--    default: /* Should not be possible, but just in case */
--       VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
--       vnc_write_u8(vs, 1);
--       if (vs->minor >= 8) {
--           static const char err[] = "Unsupported authentication type";
--           vnc_write_u32(vs, sizeof(err));
--           vnc_write(vs, err, sizeof(err));
--       }
--       vnc_client_error(vs);
--    }
--
--    return 0;
--}
--
--static void vnc_handshake_io(void *opaque);
--
--static int vnc_continue_handshake(struct VncState *vs) {
--    int ret;
--
--    if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
--       if (!gnutls_error_is_fatal(ret)) {
--           VNC_DEBUG("Handshake interrupted (blocking)\n");
--           if (!gnutls_record_get_direction(vs->tls_session))
--               qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
--           else
--               qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
--           return 0;
--       }
--       VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
--       vnc_client_error(vs);
--       return -1;
--    }
--
--    if (vs->vd->x509verify) {
--	if (vnc_validate_certificate(vs) < 0) {
--	    VNC_DEBUG("Client verification failed\n");
--	    vnc_client_error(vs);
--	    return -1;
--	} else {
--	    VNC_DEBUG("Client verification passed\n");
--	}
--    }
--
--    VNC_DEBUG("Handshake done, switching to TLS data mode\n");
--    vs->wiremode = VNC_WIREMODE_TLS;
--    qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
--
--    return start_auth_vencrypt_subauth(vs);
--}
--
--static void vnc_handshake_io(void *opaque) {
--    struct VncState *vs = (struct VncState *)opaque;
--
--    VNC_DEBUG("Handshake IO continue\n");
--    vnc_continue_handshake(vs);
--}
--
--#define NEED_X509_AUTH(vs)			      \
--    ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
--     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
--     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
--
--
--static int vnc_start_tls(struct VncState *vs) {
--    static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
--    static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
--    static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
--    static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
--
--    VNC_DEBUG("Do TLS setup\n");
--    if (vnc_tls_initialize() < 0) {
--	VNC_DEBUG("Failed to init TLS\n");
--	vnc_client_error(vs);
--	return -1;
--    }
--    if (vs->tls_session == NULL) {
--	if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
--	    vnc_client_error(vs);
--	    return -1;
--	}
--
--	if (gnutls_set_default_priority(vs->tls_session) < 0) {
--	    gnutls_deinit(vs->tls_session);
--	    vs->tls_session = NULL;
--	    vnc_client_error(vs);
--	    return -1;
--	}
--
--	if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
--	    gnutls_deinit(vs->tls_session);
--	    vs->tls_session = NULL;
--	    vnc_client_error(vs);
--	    return -1;
--	}
--
--	if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
--	    gnutls_deinit(vs->tls_session);
--	    vs->tls_session = NULL;
--	    vnc_client_error(vs);
--	    return -1;
--	}
--
--	if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
--	    gnutls_deinit(vs->tls_session);
--	    vs->tls_session = NULL;
--	    vnc_client_error(vs);
--	    return -1;
--	}
--
--	if (NEED_X509_AUTH(vs)) {
--	    gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
--	    if (!x509_cred) {
--		gnutls_deinit(vs->tls_session);
--		vs->tls_session = NULL;
--		vnc_client_error(vs);
--		return -1;
--	    }
--	    if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
--		gnutls_deinit(vs->tls_session);
--		vs->tls_session = NULL;
--		gnutls_certificate_free_credentials(x509_cred);
--		vnc_client_error(vs);
--		return -1;
--	    }
--	    if (vs->vd->x509verify) {
--		VNC_DEBUG("Requesting a client certificate\n");
--		gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
--	    }
--
--	} else {
--	    gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
--	    if (!anon_cred) {
--		gnutls_deinit(vs->tls_session);
--		vs->tls_session = NULL;
--		vnc_client_error(vs);
--		return -1;
--	    }
--	    if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
--		gnutls_deinit(vs->tls_session);
--		vs->tls_session = NULL;
--		gnutls_anon_free_server_credentials(anon_cred);
--		vnc_client_error(vs);
--		return -1;
--	    }
--	}
--
--	gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
--	gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
--	gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
--    }
--
--    VNC_DEBUG("Start TLS handshake process\n");
--    return vnc_continue_handshake(vs);
--}
--
--static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
--{
--    int auth = read_u32(data, 0);
--
--    if (auth != vs->vd->subauth) {
--	VNC_DEBUG("Rejecting auth %d\n", auth);
--	vnc_write_u8(vs, 0); /* Reject auth */
--	vnc_flush(vs);
--	vnc_client_error(vs);
--    } else {
--	VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
--	vnc_write_u8(vs, 1); /* Accept auth */
--	vnc_flush(vs);
--
--	if (vnc_start_tls(vs) < 0) {
--	    VNC_DEBUG("Failed to complete TLS\n");
--	    return 0;
--	}
--    }
--    return 0;
--}
--
--static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
--{
--    if (data[0] != 0 ||
--	data[1] != 2) {
--	VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
--	vnc_write_u8(vs, 1); /* Reject version */
--	vnc_flush(vs);
--	vnc_client_error(vs);
--    } else {
--	VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);
--	vnc_write_u8(vs, 0); /* Accept version */
--	vnc_write_u8(vs, 1); /* Number of sub-auths */
--	vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */
--	vnc_flush(vs);
--	vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
--    }
--    return 0;
--}
--
--static int start_auth_vencrypt(VncState *vs)
--{
--    /* Send VeNCrypt version 0.2 */
--    vnc_write_u8(vs, 0);
--    vnc_write_u8(vs, 2);
--
--    vnc_read_when(vs, protocol_client_vencrypt_init, 2);
--    return 0;
--}
--#endif /* CONFIG_VNC_TLS */
--
- static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
- {
-     /* We only advertise 1 auth scheme at a time, so client
-@@ -2163,17 +1707,19 @@ static int protocol_client_auth(VncState
-                vnc_write_u32(vs, 0); /* Accept auth completion */
-                vnc_flush(vs);
-            }
--           vnc_read_when(vs, protocol_client_init, 1);
-+           start_client_init(vs);
-            break;
- 
-        case VNC_AUTH_VNC:
-            VNC_DEBUG("Start VNC auth\n");
--           return start_auth_vnc(vs);
-+           start_auth_vnc(vs);
-+           break;
- 
- #ifdef CONFIG_VNC_TLS
-        case VNC_AUTH_VENCRYPT:
-            VNC_DEBUG("Accept VeNCrypt auth\n");;
--           return start_auth_vencrypt(vs);
-+           start_auth_vencrypt(vs);
-+           break;
- #endif /* CONFIG_VNC_TLS */
- 
-        default: /* Should not be possible, but just in case */
-@@ -2226,7 +1772,7 @@ static int protocol_version(VncState *vs
-             VNC_DEBUG("Tell client auth none\n");
-             vnc_write_u32(vs, vs->vd->auth);
-             vnc_flush(vs);
--            vnc_read_when(vs, protocol_client_init, 1);
-+	    start_client_init(vs);
-        } else if (vs->vd->auth == VNC_AUTH_VNC) {
-             VNC_DEBUG("Tell client VNC auth\n");
-             vnc_write_u32(vs, vs->vd->auth);
-@@ -2328,61 +1874,6 @@ void vnc_display_init(DisplayState *ds)
-     register_displaychangelistener(ds, dcl);
- }
- 
--#ifdef CONFIG_VNC_TLS
--static int vnc_set_x509_credential(VncDisplay *vs,
--				   const char *certdir,
--				   const char *filename,
--				   char **cred,
--				   int ignoreMissing)
--{
--    struct stat sb;
--
--    if (*cred) {
--	qemu_free(*cred);
--	*cred = NULL;
--    }
--
--    *cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2);
--
--    strcpy(*cred, certdir);
--    strcat(*cred, "/");
--    strcat(*cred, filename);
--
--    VNC_DEBUG("Check %s\n", *cred);
--    if (stat(*cred, &sb) < 0) {
--	qemu_free(*cred);
--	*cred = NULL;
--	if (ignoreMissing && errno == ENOENT)
--	    return 0;
--	return -1;
--    }
--
--    return 0;
--}
--
--static int vnc_set_x509_credential_dir(VncDisplay *vs,
--				       const char *certdir)
--{
--    if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
--	goto cleanup;
--    if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
--	goto cleanup;
--    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
--	goto cleanup;
--    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
--	goto cleanup;
--
--    return 0;
--
-- cleanup:
--    qemu_free(vs->x509cacert);
--    qemu_free(vs->x509cacrl);
--    qemu_free(vs->x509cert);
--    qemu_free(vs->x509key);
--    vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
--    return -1;
--}
--#endif /* CONFIG_VNC_TLS */
- 
- void vnc_display_close(DisplayState *ds)
- {
-@@ -2402,7 +1893,7 @@ void vnc_display_close(DisplayState *ds)
-     vs->auth = VNC_AUTH_INVALID;
- #ifdef CONFIG_VNC_TLS
-     vs->subauth = VNC_AUTH_INVALID;
--    vs->x509verify = 0;
-+    vs->tls.x509verify = 0;
- #endif
- }
- 
-@@ -2458,7 +1949,7 @@ int vnc_display_open(DisplayState *ds, c
- 	    char *start, *end;
- 	    x509 = 1; /* Require x509 certificates */
- 	    if (strncmp(options, "x509verify", 10) == 0)
--	        vs->x509verify = 1; /* ...and verify client certs */
-+	        vs->tls.x509verify = 1; /* ...and verify client certs */
- 
- 	    /* Now check for 'x509=/some/path' postfix
- 	     * and use that to setup x509 certificate/key paths */
-@@ -2469,7 +1960,7 @@ int vnc_display_open(DisplayState *ds, c
- 		char *path = qemu_strndup(start + 1, len);
- 
- 		VNC_DEBUG("Trying certificate path '%s'\n", path);
--		if (vnc_set_x509_credential_dir(vs, path) < 0) {
-+		if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
- 		    fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
- 		    qemu_free(path);
- 		    qemu_free(vs->display);
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.h
-@@ -32,13 +32,16 @@
- #include "audio/audio.h"
- #include <zlib.h>
- 
--#ifdef CONFIG_VNC_TLS
--#include <gnutls/gnutls.h>
--#include <gnutls/x509.h>
--#endif /* CONFIG_VNC_TLS */
--
- #include "keymaps.h"
- 
-+// #define _VNC_DEBUG 1
-+
-+#ifdef _VNC_DEBUG
-+#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-+#else
-+#define VNC_DEBUG(fmt, ...) do { } while (0)
-+#endif
-+
- /*****************************************************************************
-  *
-  * Core data structures
-@@ -72,6 +75,11 @@ typedef void VncSendHextileTile(VncState
- 
- typedef struct VncDisplay VncDisplay;
- 
-+#ifdef CONFIG_VNC_TLS
-+#include "vnc-tls.h"
-+#include "vnc-auth-vencrypt.h"
-+#endif
-+
- struct VncDisplay
- {
-     int lsock;
-@@ -83,13 +91,8 @@ struct VncDisplay
-     char *password;
-     int auth;
- #ifdef CONFIG_VNC_TLS
--    int subauth;
--    int x509verify;
--
--    char *x509cacert;
--    char *x509cacrl;
--    char *x509cert;
--    char *x509key;
-+    int subauth; /* Used by VeNCrypt */
-+    VncDisplayTLS tls;
- #endif
- };
- 
-@@ -117,8 +120,7 @@ struct VncState
-     char challenge[VNC_AUTH_CHALLENGE_SIZE];
- 
- #ifdef CONFIG_VNC_TLS
--    int wiremode;
--    gnutls_session_t tls_session;
-+    VncStateTLS tls;
- #endif
- 
-     Buffer output;
-@@ -162,12 +164,6 @@ enum {
-     VNC_AUTH_VENCRYPT = 19
- };
- 
--#ifdef CONFIG_VNC_TLS
--enum {
--    VNC_WIREMODE_CLEAR,
--    VNC_WIREMODE_TLS,
--};
--
- enum {
-     VNC_AUTH_VENCRYPT_PLAIN = 256,
-     VNC_AUTH_VENCRYPT_TLSNONE = 257,
-@@ -178,12 +174,6 @@ enum {
-     VNC_AUTH_VENCRYPT_X509PLAIN = 262,
- };
- 
--#define X509_CA_CERT_FILE "ca-cert.pem"
--#define X509_CA_CRL_FILE "ca-crl.pem"
--#define X509_SERVER_KEY_FILE "server-key.pem"
--#define X509_SERVER_CERT_FILE "server-cert.pem"
--
--#endif /* CONFIG_VNC_TLS */
- 
- /*****************************************************************************
-  *
-@@ -254,4 +244,38 @@ enum {
- #define VNC_FEATURE_ZLIB_MASK                (1 << VNC_FEATURE_ZLIB)
- #define VNC_FEATURE_COPYRECT_MASK            (1 << VNC_FEATURE_COPYRECT)
- 
-+
-+/*****************************************************************************
-+ *
-+ * Internal APIs
-+ *
-+ *****************************************************************************/
-+
-+/* Event loop functions */
-+void vnc_client_read(void *opaque);
-+void vnc_client_write(void *opaque);
-+
-+
-+/* Protocol I/O functions */
-+void vnc_write(VncState *vs, const void *data, size_t len);
-+void vnc_write_u32(VncState *vs, uint32_t value);
-+void vnc_write_s32(VncState *vs, int32_t value);
-+void vnc_write_u16(VncState *vs, uint16_t value);
-+void vnc_write_u8(VncState *vs, uint8_t value);
-+void vnc_flush(VncState *vs);
-+void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting);
-+
-+
-+/* Buffer I/O functions */
-+uint8_t read_u8(uint8_t *data, size_t offset);
-+uint16_t read_u16(uint8_t *data, size_t offset);
-+int32_t read_s32(uint8_t *data, size_t offset);
-+uint32_t read_u32(uint8_t *data, size_t offset);
-+
-+/* Protocol stage functions */
-+void vnc_client_error(VncState *vs);
-+
-+void start_client_init(VncState *vs);
-+void start_auth_vnc(VncState *vs);
-+
- #endif /* __QEMU_VNC_H */
diff --git a/qemu-sasl-06-vnc-sasl.patch b/qemu-sasl-06-vnc-sasl.patch
deleted file mode 100644
index 388d6c6..0000000
--- a/qemu-sasl-06-vnc-sasl.patch
+++ /dev/null
@@ -1,1603 +0,0 @@
-This patch adds the new SASL authentication protocol to the VNC server.
-
-It is enabled by setting the 'sasl' flag when launching VNC. SASL can
-optionally provide encryption via its SSF layer, if a suitable mechanism
-is configured (eg, GSSAPI/Kerberos, or Digest-MD5).  If an SSF layer is
-not available, then it should be combined with the x509 VNC authentication
-protocol which provides encryption.
-
-eg, if using GSSAPI
-
-   qemu -vnc localhost:1,sasl
-
-eg if using  TLS/x509 for encryption
-
-   qemu -vnc localhost:1,sasl,tls,x509
-
-
-By default the Cyrus SASL library will look for its configuration in
-the file /etc/sasl2/qemu.conf.  For non-root users, this can be overridden
-by setting the SASL_CONF_PATH environment variable, eg to make it look in
-$HOME/.sasl2.  NB unprivileged users may not have access to the full range
-of SASL mechanisms, since some of them require some administrative privileges
-to configure. The patch includes an example SASL configuration file which
-illustrates config for GSSAPI and Digest-MD5, though it should be noted that
-the latter is not really considered secure any more.
-
-Most of the SASL authentication code is located in a separate source file,
-vnc-auth-sasl.c.  The main vnc.c file only contains minimal integration
-glue, specifically parsing of command line flags / setup, and calls to
-start the SASL auth process, to do encoding/decoding for data.
-
-There are several possible stacks for reading & writing of data, depending
-on the combo of VNC authentication methods in use
-
- - Clear.    read/write straight to socket
- - TLS.      read/write via GNUTLS helpers
- - SASL.     encode/decode via SASL SSF layer, then read/write to socket
- - SASL+TLS. encode/decode via SASL SSF layer, then read/write via GNUTLS
-
-Hence, the vnc_client_read & vnc_client_write methods have been refactored
-a little.
-
-   vnc_client_read:  main entry point for reading, calls either
-
-       - vnc_client_read_plain   reading, with no intermediate decoding
-       - vnc_client_read_sasl    reading, with SASL SSF decoding
-
-   These two methods, then call vnc_client_read_buf(). This decides
-   whether to write to the socket directly or write via GNUTLS.
-
-The situation is the same for writing data. More extensive comments
-have been added in the code / patch. The vnc_client_read_sasl and
-vnc_client_write_sasl method implementations live in the separate
-vnc-auth-sasl.c file.
-
-The state required for the SASL auth mechanism is kept in a separate
-VncStateSASL struct, defined in vnc-auth-sasl.h and included in the
-main VncState.
-
-The configure script probes for SASL and automatically enables it
-if found, unless --disable-vnc-sasl was given to override it.
-
-
- Makefile            |    7 
- Makefile.target     |    5 
- b/qemu.sasl         |   34 ++
- b/vnc-auth-sasl.c   |  626 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- b/vnc-auth-sasl.h   |   67 +++++
- configure           |   34 ++
- qemu-doc.texi       |   97 ++++++++
- vnc-auth-vencrypt.c |   12 
- vnc.c               |  249 ++++++++++++++++++--
- vnc.h               |   31 ++
- 10 files changed, 1129 insertions(+), 33 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/Makefile
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/Makefile
-+++ kvm-84.git-snapshot-20090303/qemu/Makefile
-@@ -152,6 +152,9 @@ OBJS+=vnc.o d3des.o
- ifdef CONFIG_VNC_TLS
- OBJS+=vnc-tls.o vnc-auth-vencrypt.o
- endif
-+ifdef CONFIG_VNC_SASL
-+OBJS+=vnc-auth-sasl.o
-+endif
- 
- ifdef CONFIG_COCOA
- OBJS+=cocoa.o
-@@ -175,7 +178,7 @@ sdl.o: sdl.c keymaps.h sdl_keysym.h
- 
- sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
- 
--vnc.h: vnc-tls.h vnc-auth-vencrypt.h keymaps.h
-+vnc.h: vnc-tls.h vnc-auth-vencrypt.h vnc-auth-sasl.h keymaps.h
- 
- vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h
- 
-@@ -185,6 +188,8 @@ vnc-tls.o: vnc-tls.c vnc.h
- 
- vnc-auth-vencrypt.o: vnc-auth-vencrypt.c vnc.h
- 
-+vnc-auth-sasl.o: vnc-auth-sasl.c vnc.h
-+
- curses.o: curses.c keymaps.h curses_keys.h
- 
- bt-host.o: CFLAGS += $(CONFIG_BLUEZ_CFLAGS)
-Index: kvm-84.git-snapshot-20090303/qemu/Makefile.target
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/Makefile.target
-+++ kvm-84.git-snapshot-20090303/qemu/Makefile.target
-@@ -613,6 +613,11 @@ CPPFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
- LIBS += $(CONFIG_VNC_TLS_LIBS)
- endif
- 
-+ifdef CONFIG_VNC_SASL
-+CPPFLAGS += $(CONFIG_VNC_SASL_CFLAGS)
-+LIBS += $(CONFIG_VNC_SASL_LIBS)
-+endif
-+
- ifdef CONFIG_BLUEZ
- LIBS += $(CONFIG_BLUEZ_LIBS)
- endif
-Index: kvm-84.git-snapshot-20090303/qemu/configure
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/configure
-+++ kvm-84.git-snapshot-20090303/qemu/configure
-@@ -164,6 +164,7 @@ fmod_lib=""
- fmod_inc=""
- oss_lib=""
- vnc_tls="yes"
-+vnc_sasl="yes"
- bsd="no"
- linux="no"
- solaris="no"
-@@ -403,6 +404,8 @@ for opt do
-   ;;
-   --disable-vnc-tls) vnc_tls="no"
-   ;;
-+  --disable-vnc-sasl) vnc_sasl="no"
-+  ;;
-   --disable-slirp) slirp="no"
-   ;;
-   --disable-vde) vde="no"
-@@ -562,6 +565,7 @@ echo "                           Availab
- echo "  --enable-mixemu          enable mixer emulation"
- echo "  --disable-brlapi         disable BrlAPI"
- echo "  --disable-vnc-tls        disable TLS encryption for VNC server"
-+echo "  --disable-vnc-sasl       disable SASL encryption for VNC server"
- echo "  --disable-curses         disable curses output"
- echo "  --disable-bluez          disable bluez stack connectivity"
- echo "  --disable-kvm            disable KVM acceleration support"
-@@ -874,6 +878,25 @@ EOF
- fi
- 
- ##########################################
-+# VNC SASL detection
-+if test "$vnc_sasl" = "yes" ; then
-+cat > $TMPC <<EOF
-+#include <sasl/sasl.h>
-+#include <stdio.h>
-+int main(void) { sasl_server_init(NULL, "qemu"); return 0; }
-+EOF
-+    # Assuming Cyrus-SASL installed in /usr prefix
-+    vnc_sasl_cflags=""
-+    vnc_sasl_libs="-lsasl2"
-+    if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $vnc_sasl_cflags $TMPC \
-+           $vnc_sasl_libs 2> /dev/null ; then
-+	:
-+    else
-+	vnc_sasl="no"
-+    fi
-+fi
-+
-+##########################################
- # vde libraries probe
- if test "$vde" = "yes" ; then
-   cat > $TMPC << EOF
-@@ -1208,6 +1231,11 @@ if test "$vnc_tls" = "yes" ; then
-     echo "    TLS CFLAGS    $vnc_tls_cflags"
-     echo "    TLS LIBS      $vnc_tls_libs"
- fi
-+echo "VNC SASL support  $vnc_sasl"
-+if test "$vnc_sasl" = "yes" ; then
-+    echo "    SASL CFLAGS    $vnc_sasl_cflags"
-+    echo "    SASL LIBS      $vnc_sasl_libs"
-+fi
- if test -n "$sparc_cpu"; then
-     echo "Target Sparc Arch $sparc_cpu"
- fi
-@@ -1451,6 +1479,12 @@ if test "$vnc_tls" = "yes" ; then
-   echo "CONFIG_VNC_TLS_LIBS=$vnc_tls_libs" >> $config_mak
-   echo "#define CONFIG_VNC_TLS 1" >> $config_h
- fi
-+if test "$vnc_sasl" = "yes" ; then
-+  echo "CONFIG_VNC_SASL=yes" >> $config_mak
-+  echo "CONFIG_VNC_SASL_CFLAGS=$vnc_sasl_cflags" >> $config_mak
-+  echo "CONFIG_VNC_SASL_LIBS=$vnc_sasl_libs" >> $config_mak
-+  echo "#define CONFIG_VNC_SASL 1" >> $config_h
-+fi
- qemu_version=`head $source_path/VERSION`
- echo "VERSION=$qemu_version" >>$config_mak
- echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h
-Index: kvm-84.git-snapshot-20090303/qemu/qemu-doc.texi
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/qemu-doc.texi
-+++ kvm-84.git-snapshot-20090303/qemu/qemu-doc.texi
-@@ -624,6 +624,21 @@ path following this option specifies whe
- be loaded from. See the @ref{vnc_security} section for details on generating
- certificates.
- 
-+@item sasl
-+
-+Require that the client use SASL to authenticate with the VNC server.
-+The exact choice of authentication method used is controlled from the
-+system / user's SASL configuration file for the 'qemu' service. This
-+is typically found in /etc/sasl2/qemu.conf. If running QEMU as an
-+unprivileged user, an environment variable SASL_CONF_PATH can be used
-+to make it search alternate locations for the service config.
-+While some SASL auth methods can also provide data encryption (eg GSSAPI),
-+it is recommended that SASL always be combined with the 'tls' and
-+'x509' settings to enable use of SSL and server certificates. This
-+ensures a data encryption preventing compromise of authentication
-+credentials. See the @ref{vnc_security} section for details on using
-+SASL authentication.
-+
- @end table
- 
- @end table
-@@ -2058,7 +2073,10 @@ considerations depending on the deployme
- * vnc_sec_certificate::
- * vnc_sec_certificate_verify::
- * vnc_sec_certificate_pw::
-+* vnc_sec_sasl::
-+* vnc_sec_certificate_sasl::
- * vnc_generate_cert::
-+* vnc_setup_sasl::
- @end menu
- @node vnc_sec_none
- @subsection Without passwords
-@@ -2141,6 +2159,41 @@ Password: ********
- (qemu)
- @end example
- 
-+
-+@node vnc_sec_sasl
-+@subsection With SASL authentication
-+
-+The SASL authentication method is a VNC extension, that provides an
-+easily extendable, pluggable authentication method. This allows for
-+integration with a wide range of authentication mechanisms, such as
-+PAM, GSSAPI/Kerberos, LDAP, SQL databases, one-time keys and more.
-+The strength of the authentication depends on the exact mechanism
-+configured. If the chosen mechanism also provides a SSF layer, then
-+it will encrypt the datastream as well.
-+
-+Refer to the later docs on how to choose the exact SASL mechanism
-+used for authentication, but assuming use of one supporting SSF,
-+then QEMU can be launched with:
-+
-+@example
-+qemu [...OPTIONS...] -vnc :1,sasl -monitor stdio
-+@end example
-+
-+@node vnc_sec_certificate_sasl
-+@subsection With x509 certificates and SASL authentication
-+
-+If the desired SASL authentication mechanism does not supported
-+SSF layers, then it is strongly advised to run it in combination
-+with TLS and x509 certificates. This provides securely encrypted
-+data stream, avoiding risk of compromising of the security
-+credentials. This can be enabled, by combining the 'sasl' option
-+with the aforementioned TLS + x509 options:
-+
-+@example
-+qemu [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio
-+@end example
-+
-+
- @node vnc_generate_cert
- @subsection Generating certificates for VNC
- 
-@@ -2252,6 +2305,50 @@ EOF
- The @code{client-key.pem} and @code{client-cert.pem} files should now be securely
- copied to the client for which they were generated.
- 
-+
-+@node vnc_setup_sasl
-+
-+@subsection Configuring SASL mechanisms
-+
-+The following documentation assumes use of the Cyrus SASL implementation on a
-+Linux host, but the principals should apply to any other SASL impl. When SASL
-+is enabled, the mechanism configuration will be loaded from system default
-+SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
-+unprivileged user, an environment variable SASL_CONF_PATH can be used
-+to make it search alternate locations for the service config.
-+
-+The default configuration might contain
-+
-+@example
-+mech_list: digest-md5
-+sasldb_path: /etc/qemu/passwd.db
-+@end example
-+
-+This says to use the 'Digest MD5' mechanism, which is similar to the HTTP
-+Digest-MD5 mechanism. The list of valid usernames & passwords is maintained
-+in the /etc/qemu/passwd.db file, and can be updated using the saslpasswd2
-+command. While this mechanism is easy to configure and use, it is not
-+considered secure by modern standards, so only suitable for developers /
-+ad-hoc testing.
-+
-+A more serious deployment might use Kerberos, which is done with the 'gssapi'
-+mechanism
-+
-+@example
-+mech_list: gssapi
-+keytab: /etc/qemu/krb5.tab
-+@end example
-+
-+For this to work the administrator of your KDC must generate a Kerberos
-+principal for the server, with a name of  'qemu/somehost.example.com@@EXAMPLE.COM'
-+replacing 'somehost.example.com' with the fully qualified host name of the
-+machine running QEMU, and 'EXAMPLE.COM' with the Keberos Realm.
-+
-+Other configurations will be left as an exercise for the reader. It should
-+be noted that only Digest-MD5 and GSSAPI provides a SSF layer for data
-+encryption. For all other mechanisms, VNC should always be configured to
-+use TLS and x509 certificates to protect security credentials from snooping.
-+
- @node gdb_usage
- @section GDB usage
- 
-Index: kvm-84.git-snapshot-20090303/qemu/qemu.sasl
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/qemu.sasl
-@@ -0,0 +1,34 @@
-+# If you want to use the non-TLS socket, then you *must* include
-+# the GSSAPI or DIGEST-MD5 mechanisms, because they are the only
-+# ones that can offer session encryption as well as authentication.
-+#
-+# If you're only using TLS, then you can turn on any mechanisms
-+# you like for authentication, because TLS provides the encryption
-+#
-+# Default to a simple username+password mechanism
-+# NB digest-md5 is no longer considered secure by current standards
-+mech_list: digest-md5
-+
-+# Before you can use GSSAPI, you need a service principle on the
-+# KDC server for libvirt, and that to be exported to the keytab
-+# file listed below
-+#mech_list: gssapi
-+#
-+# You can also list many mechanisms at once, then the user can choose
-+# by adding  '?auth=sasl.gssapi' to their libvirt URI, eg
-+#   qemu+tcp://hostname/system?auth=sasl.gssapi
-+#mech_list: digest-md5 gssapi
-+
-+# Some older builds of MIT kerberos on Linux ignore this option &
-+# instead need KRB5_KTNAME env var.
-+# For modern Linux, and other OS, this should be sufficient
-+keytab: /etc/qemu/krb5.tab
-+
-+# If using digest-md5 for username/passwds, then this is the file
-+# containing the passwds. Use 'saslpasswd2 -a qemu [username]'
-+# to add entries, and 'sasldblistusers2 -a qemu' to browse it
-+sasldb_path: /etc/qemu/passwd.db
-+
-+
-+auxprop_plugin: sasldb
-+
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.c
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.c
-@@ -0,0 +1,626 @@
-+/*
-+ * QEMU VNC display driver: SASL auth protocol
-+ *
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "vnc.h"
-+
-+/* Max amount of data we send/recv for SASL steps to prevent DOS */
-+#define SASL_DATA_MAX_LEN (1024 * 1024)
-+
-+
-+void vnc_sasl_client_cleanup(VncState *vs)
-+{
-+    if (vs->sasl.conn) {
-+	vs->sasl.runSSF = vs->sasl.waitWriteSSF = vs->sasl.wantSSF = 0;
-+	vs->sasl.encodedLength = vs->sasl.encodedOffset = 0;
-+	vs->sasl.encoded = NULL;
-+	free(vs->sasl.username);
-+	free(vs->sasl.mechlist);
-+	vs->sasl.username = vs->sasl.mechlist = NULL;
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+    }
-+}
-+
-+
-+long vnc_client_write_sasl(VncState *vs)
-+{
-+    long ret;
-+
-+    VNC_DEBUG("Write SASL: Pending output %p size %d offset %d Encoded: %p size %d offset %d\n",
-+	      vs->output.buffer, vs->output.capacity, vs->output.offset,
-+	      vs->sasl.encoded, vs->sasl.encodedLength, vs->sasl.encodedOffset);
-+
-+    if (!vs->sasl.encoded) {
-+	int err;
-+	err = sasl_encode(vs->sasl.conn,
-+			  (char *)vs->output.buffer,
-+			  vs->output.offset,
-+			  (const char **)&vs->sasl.encoded,
-+			  &vs->sasl.encodedLength);
-+	if (err != SASL_OK)
-+	    return vnc_client_io_error(vs, -1, EIO);
-+
-+	vs->sasl.encodedOffset = 0;
-+    }
-+
-+    ret = vnc_client_write_buf(vs,
-+			       vs->sasl.encoded + vs->sasl.encodedOffset,
-+			       vs->sasl.encodedLength - vs->sasl.encodedOffset);
-+    if (!ret)
-+	return 0;
-+
-+    vs->sasl.encodedOffset += ret;
-+    if (vs->sasl.encodedOffset == vs->sasl.encodedLength) {
-+	vs->output.offset = 0;
-+	vs->sasl.encoded = NULL;
-+	vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
-+    }
-+
-+    /* Can't merge this block with one above, because
-+     * someone might have written more unencrypted
-+     * data in vs->output while we were processing
-+     * SASL encoded output
-+     */
-+    if (vs->output.offset == 0) {
-+	qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
-+    }
-+
-+    return ret;
-+}
-+
-+
-+long vnc_client_read_sasl(VncState *vs)
-+{
-+    long ret;
-+    uint8_t encoded[4096];
-+    const char *decoded;
-+    unsigned int decodedLen;
-+    int err;
-+
-+    ret = vnc_client_read_buf(vs, encoded, sizeof(encoded));
-+    if (!ret)
-+	return 0;
-+
-+    err = sasl_decode(vs->sasl.conn,
-+		      (char *)encoded, ret,
-+		      &decoded, &decodedLen);
-+
-+    if (err != SASL_OK)
-+	return vnc_client_io_error(vs, -1, -EIO);
-+    VNC_DEBUG("Read SASL Encoded %p size %ld Decoded %p size %d\n",
-+	      encoded, ret, decoded, decodedLen);
-+    buffer_reserve(&vs->input, decodedLen);
-+    buffer_append(&vs->input, decoded, decodedLen);
-+    return decodedLen;
-+}
-+
-+
-+static int vnc_auth_sasl_check_access(VncState *vs)
-+{
-+    const void *val;
-+    int err;
-+
-+    err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val);
-+    if (err != SASL_OK) {
-+	VNC_DEBUG("cannot query SASL username on connection %d (%s)\n",
-+		  err, sasl_errstring(err, NULL, NULL));
-+	return -1;
-+    }
-+    if (val == NULL) {
-+	VNC_DEBUG("no client username was found\n");
-+	return -1;
-+    }
-+    VNC_DEBUG("SASL client username %s\n", (const char *)val);
-+
-+    vs->sasl.username = qemu_strdup((const char*)val);
-+
-+    return 0;
-+}
-+
-+static int vnc_auth_sasl_check_ssf(VncState *vs)
-+{
-+    const void *val;
-+    int err, ssf;
-+
-+    if (!vs->sasl.wantSSF)
-+	return 1;
-+
-+    err = sasl_getprop(vs->sasl.conn, SASL_SSF, &val);
-+    if (err != SASL_OK)
-+	return 0;
-+
-+    ssf = *(const int *)val;
-+    VNC_DEBUG("negotiated an SSF of %d\n", ssf);
-+    if (ssf < 56)
-+	return 0; /* 56 is good for Kerberos */
-+
-+    /* Only setup for read initially, because we're about to send an RPC
-+     * reply which must be in plain text. When the next incoming RPC
-+     * arrives, we'll switch on writes too
-+     *
-+     * cf qemudClientReadSASL  in qemud.c
-+     */
-+    vs->sasl.runSSF = 1;
-+
-+    /* We have a SSF that's good enough */
-+    return 1;
-+}
-+
-+/*
-+ * Step Msg
-+ *
-+ * Input from client:
-+ *
-+ * u32 clientin-length
-+ * u8-array clientin-string
-+ *
-+ * Output to client:
-+ *
-+ * u32 serverout-length
-+ * u8-array serverout-strin
-+ * u8 continue
-+ */
-+
-+static int protocol_client_auth_sasl_step_len(VncState *vs, uint8_t *data, size_t len);
-+
-+static int protocol_client_auth_sasl_step(VncState *vs, uint8_t *data, size_t len)
-+{
-+    uint32_t datalen = len;
-+    const char *serverout;
-+    unsigned int serveroutlen;
-+    int err;
-+    char *clientdata = NULL;
-+
-+    /* NB, distinction of NULL vs "" is *critical* in SASL */
-+    if (datalen) {
-+	clientdata = (char*)data;
-+	clientdata[datalen-1] = '\0'; /* Wire includes '\0', but make sure */
-+	datalen--; /* Don't count NULL byte when passing to _start() */
-+    }
-+
-+    VNC_DEBUG("Step using SASL Data %p (%d bytes)\n",
-+	      clientdata, datalen);
-+    err = sasl_server_step(vs->sasl.conn,
-+			   clientdata,
-+			   datalen,
-+			   &serverout,
-+			   &serveroutlen);
-+    if (err != SASL_OK &&
-+	err != SASL_CONTINUE) {
-+	VNC_DEBUG("sasl step failed %d (%s)\n",
-+		  err, sasl_errdetail(vs->sasl.conn));
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+
-+    if (serveroutlen > SASL_DATA_MAX_LEN) {
-+	VNC_DEBUG("sasl step reply data too long %d\n",
-+		  serveroutlen);
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+
-+    VNC_DEBUG("SASL return data %d bytes, nil; %d\n",
-+	      serveroutlen, serverout ? 0 : 1);
-+
-+    if (serveroutlen) {
-+	vnc_write_u32(vs, serveroutlen + 1);
-+	vnc_write(vs, serverout, serveroutlen + 1);
-+    } else {
-+	vnc_write_u32(vs, 0);
-+    }
-+
-+    /* Whether auth is complete */
-+    vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1);
-+
-+    if (err == SASL_CONTINUE) {
-+	VNC_DEBUG("%s", "Authentication must continue\n");
-+	/* Wait for step length */
-+	vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4);
-+    } else {
-+	if (!vnc_auth_sasl_check_ssf(vs)) {
-+	    VNC_DEBUG("Authentication rejected for weak SSF %d\n", vs->csock);
-+	    goto authreject;
-+	}
-+
-+	/* Check username whitelist ACL */
-+	if (vnc_auth_sasl_check_access(vs) < 0) {
-+	    VNC_DEBUG("Authentication rejected for ACL %d\n", vs->csock);
-+	    goto authreject;
-+	}
-+
-+	VNC_DEBUG("Authentication successful %d\n", vs->csock);
-+	vnc_write_u32(vs, 0); /* Accept auth */
-+	/*
-+	 * Delay writing in SSF encoded mode until pending output
-+	 * buffer is written
-+	 */
-+	if (vs->sasl.runSSF)
-+	    vs->sasl.waitWriteSSF = vs->output.offset;
-+	start_client_init(vs);
-+    }
-+
-+    return 0;
-+
-+ authreject:
-+    vnc_write_u32(vs, 1); /* Reject auth */
-+    vnc_write_u32(vs, sizeof("Authentication failed"));
-+    vnc_write(vs, "Authentication failed", sizeof("Authentication failed"));
-+    vnc_flush(vs);
-+    vnc_client_error(vs);
-+    return -1;
-+
-+ authabort:
-+    vnc_client_error(vs);
-+    return -1;
-+}
-+
-+static int protocol_client_auth_sasl_step_len(VncState *vs, uint8_t *data, size_t len)
-+{
-+    uint32_t steplen = read_u32(data, 0);
-+    VNC_DEBUG("Got client step len %d\n", steplen);
-+    if (steplen > SASL_DATA_MAX_LEN) {
-+	VNC_DEBUG("Too much SASL data %d\n", steplen);
-+	vnc_client_error(vs);
-+	return -1;
-+    }
-+
-+    if (steplen == 0)
-+	return protocol_client_auth_sasl_step(vs, NULL, 0);
-+    else
-+	vnc_read_when(vs, protocol_client_auth_sasl_step, steplen);
-+    return 0;
-+}
-+
-+/*
-+ * Start Msg
-+ *
-+ * Input from client:
-+ *
-+ * u32 clientin-length
-+ * u8-array clientin-string
-+ *
-+ * Output to client:
-+ *
-+ * u32 serverout-length
-+ * u8-array serverout-strin
-+ * u8 continue
-+ */
-+
-+#define SASL_DATA_MAX_LEN (1024 * 1024)
-+
-+static int protocol_client_auth_sasl_start(VncState *vs, uint8_t *data, size_t len)
-+{
-+    uint32_t datalen = len;
-+    const char *serverout;
-+    unsigned int serveroutlen;
-+    int err;
-+    char *clientdata = NULL;
-+
-+    /* NB, distinction of NULL vs "" is *critical* in SASL */
-+    if (datalen) {
-+	clientdata = (char*)data;
-+	clientdata[datalen-1] = '\0'; /* Should be on wire, but make sure */
-+	datalen--; /* Don't count NULL byte when passing to _start() */
-+    }
-+
-+    VNC_DEBUG("Start SASL auth with mechanism %s. Data %p (%d bytes)\n",
-+	      vs->sasl.mechlist, clientdata, datalen);
-+    err = sasl_server_start(vs->sasl.conn,
-+			    vs->sasl.mechlist,
-+			    clientdata,
-+			    datalen,
-+			    &serverout,
-+			    &serveroutlen);
-+    if (err != SASL_OK &&
-+	err != SASL_CONTINUE) {
-+	VNC_DEBUG("sasl start failed %d (%s)\n",
-+		  err, sasl_errdetail(vs->sasl.conn));
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+    if (serveroutlen > SASL_DATA_MAX_LEN) {
-+	VNC_DEBUG("sasl start reply data too long %d\n",
-+		  serveroutlen);
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+
-+    VNC_DEBUG("SASL return data %d bytes, nil; %d\n",
-+	      serveroutlen, serverout ? 0 : 1);
-+
-+    if (serveroutlen) {
-+	vnc_write_u32(vs, serveroutlen + 1);
-+	vnc_write(vs, serverout, serveroutlen + 1);
-+    } else {
-+	vnc_write_u32(vs, 0);
-+    }
-+
-+    /* Whether auth is complete */
-+    vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1);
-+
-+    if (err == SASL_CONTINUE) {
-+	VNC_DEBUG("%s", "Authentication must continue\n");
-+	/* Wait for step length */
-+	vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4);
-+    } else {
-+	if (!vnc_auth_sasl_check_ssf(vs)) {
-+	    VNC_DEBUG("Authentication rejected for weak SSF %d\n", vs->csock);
-+	    goto authreject;
-+	}
-+
-+	/* Check username whitelist ACL */
-+	if (vnc_auth_sasl_check_access(vs) < 0) {
-+	    VNC_DEBUG("Authentication rejected for ACL %d\n", vs->csock);
-+	    goto authreject;
-+	}
-+
-+	VNC_DEBUG("Authentication successful %d\n", vs->csock);
-+	vnc_write_u32(vs, 0); /* Accept auth */
-+	start_client_init(vs);
-+    }
-+
-+    return 0;
-+
-+ authreject:
-+    vnc_write_u32(vs, 1); /* Reject auth */
-+    vnc_write_u32(vs, sizeof("Authentication failed"));
-+    vnc_write(vs, "Authentication failed", sizeof("Authentication failed"));
-+    vnc_flush(vs);
-+    vnc_client_error(vs);
-+    return -1;
-+
-+ authabort:
-+    vnc_client_error(vs);
-+    return -1;
-+}
-+
-+static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size_t len)
-+{
-+    uint32_t startlen = read_u32(data, 0);
-+    VNC_DEBUG("Got client start len %d\n", startlen);
-+    if (startlen > SASL_DATA_MAX_LEN) {
-+	VNC_DEBUG("Too much SASL data %d\n", startlen);
-+	vnc_client_error(vs);
-+	return -1;
-+    }
-+
-+    if (startlen == 0)
-+	return protocol_client_auth_sasl_start(vs, NULL, 0);
-+
-+    vnc_read_when(vs, protocol_client_auth_sasl_start, startlen);
-+    return 0;
-+}
-+
-+static int protocol_client_auth_sasl_mechname(VncState *vs, uint8_t *data, size_t len)
-+{
-+    char *mechname = malloc(len + 1);
-+    if (!mechname) {
-+	VNC_DEBUG("Out of memory reading mechname\n");
-+	vnc_client_error(vs);
-+    }
-+    strncpy(mechname, (char*)data, len);
-+    mechname[len] = '\0';
-+    VNC_DEBUG("Got client mechname '%s' check against '%s'\n",
-+	      mechname, vs->sasl.mechlist);
-+
-+    if (strncmp(vs->sasl.mechlist, mechname, len) == 0) {
-+	if (vs->sasl.mechlist[len] != '\0' &&
-+	    vs->sasl.mechlist[len] != ',') {
-+	    VNC_DEBUG("One %d", vs->sasl.mechlist[len]);
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+    } else {
-+	char *offset = strstr(vs->sasl.mechlist, mechname);
-+	VNC_DEBUG("Two %p\n", offset);
-+	if (!offset) {
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+	VNC_DEBUG("Two '%s'\n", offset);
-+	if (offset[-1] != ',' ||
-+	    (offset[len] != '\0'&&
-+	     offset[len] != ',')) {
-+	    vnc_client_error(vs);
-+	    return -1;
-+	}
-+    }
-+
-+    free(vs->sasl.mechlist);
-+    vs->sasl.mechlist = mechname;
-+
-+    VNC_DEBUG("Validated mechname '%s'\n", mechname);
-+    vnc_read_when(vs, protocol_client_auth_sasl_start_len, 4);
-+    return 0;
-+}
-+
-+static int protocol_client_auth_sasl_mechname_len(VncState *vs, uint8_t *data, size_t len)
-+{
-+    uint32_t mechlen = read_u32(data, 0);
-+    VNC_DEBUG("Got client mechname len %d\n", mechlen);
-+    if (mechlen > 100) {
-+	VNC_DEBUG("Too long SASL mechname data %d\n", mechlen);
-+	vnc_client_error(vs);
-+	return -1;
-+    }
-+    if (mechlen < 1) {
-+	VNC_DEBUG("Too short SASL mechname %d\n", mechlen);
-+	vnc_client_error(vs);
-+	return -1;
-+    }
-+    vnc_read_when(vs, protocol_client_auth_sasl_mechname,mechlen);
-+    return 0;
-+}
-+
-+#define USES_X509_AUTH(vs)			      \
-+    ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
-+     (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
-+     (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN ||  \
-+     (vs)->subauth == VNC_AUTH_VENCRYPT_X509SASL)
-+
-+
-+void start_auth_sasl(VncState *vs)
-+{
-+    const char *mechlist = NULL;
-+    sasl_security_properties_t secprops;
-+    int err;
-+    char *localAddr, *remoteAddr;
-+    int mechlistlen;
-+
-+    VNC_DEBUG("Initialize SASL auth %d\n", vs->csock);
-+
-+    /* Get local & remote client addresses in form  IPADDR;PORT */
-+    if (!(localAddr = vnc_socket_local_addr("%s;%s", vs->csock)))
-+	goto authabort;
-+
-+    if (!(remoteAddr = vnc_socket_remote_addr("%s;%s", vs->csock))) {
-+	free(localAddr);
-+	goto authabort;
-+    }
-+
-+    err = sasl_server_new("vnc",
-+			  NULL, /* FQDN - just delegates to gethostname */
-+			  NULL, /* User realm */
-+			  localAddr,
-+			  remoteAddr,
-+			  NULL, /* Callbacks, not needed */
-+			  SASL_SUCCESS_DATA,
-+			  &vs->sasl.conn);
-+    free(localAddr);
-+    free(remoteAddr);
-+    localAddr = remoteAddr = NULL;
-+
-+    if (err != SASL_OK) {
-+	VNC_DEBUG("sasl context setup failed %d (%s)",
-+		  err, sasl_errstring(err, NULL, NULL));
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+
-+#ifdef CONFIG_VNC_TLS
-+    /* Inform SASL that we've got an external SSF layer from TLS/x509 */
-+    if (vs->vd->auth == VNC_AUTH_VENCRYPT &&
-+	vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) {
-+	gnutls_cipher_algorithm_t cipher;
-+	sasl_ssf_t ssf;
-+
-+	cipher = gnutls_cipher_get(vs->tls.session);
-+	if (!(ssf = (sasl_ssf_t)gnutls_cipher_get_key_size(cipher))) {
-+	    VNC_DEBUG("%s", "cannot TLS get cipher size\n");
-+	    sasl_dispose(&vs->sasl.conn);
-+	    vs->sasl.conn = NULL;
-+	    goto authabort;
-+	}
-+	ssf *= 8; /* tls key size is bytes, sasl wants bits */
-+
-+	err = sasl_setprop(vs->sasl.conn, SASL_SSF_EXTERNAL, &ssf);
-+	if (err != SASL_OK) {
-+	    VNC_DEBUG("cannot set SASL external SSF %d (%s)\n",
-+		      err, sasl_errstring(err, NULL, NULL));
-+	    sasl_dispose(&vs->sasl.conn);
-+	    vs->sasl.conn = NULL;
-+	    goto authabort;
-+	}
-+    } else
-+#endif /* CONFIG_VNC_TLS */
-+	vs->sasl.wantSSF = 1;
-+
-+    memset (&secprops, 0, sizeof secprops);
-+    /* Inform SASL that we've got an external SSF layer from TLS */
-+    if (strncmp(vs->vd->display, "unix:", 5) == 0
-+#ifdef CONFIG_VNC_TLS
-+	/* Disable SSF, if using TLS+x509+SASL only. TLS without x509
-+	   is not sufficiently strong */
-+	|| (vs->vd->auth == VNC_AUTH_VENCRYPT &&
-+	    vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL)
-+#endif /* CONFIG_VNC_TLS */
-+	) {
-+	/* If we've got TLS or UNIX domain sock, we don't care about SSF */
-+	secprops.min_ssf = 0;
-+	secprops.max_ssf = 0;
-+	secprops.maxbufsize = 8192;
-+	secprops.security_flags = 0;
-+    } else {
-+	/* Plain TCP, better get an SSF layer */
-+	secprops.min_ssf = 56; /* Good enough to require kerberos */
-+	secprops.max_ssf = 100000; /* Arbitrary big number */
-+	secprops.maxbufsize = 8192;
-+	/* Forbid any anonymous or trivially crackable auth */
-+	secprops.security_flags =
-+	    SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT;
-+    }
-+
-+    err = sasl_setprop(vs->sasl.conn, SASL_SEC_PROPS, &secprops);
-+    if (err != SASL_OK) {
-+	VNC_DEBUG("cannot set SASL security props %d (%s)\n",
-+		  err, sasl_errstring(err, NULL, NULL));
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+
-+    err = sasl_listmech(vs->sasl.conn,
-+			NULL, /* Don't need to set user */
-+			"", /* Prefix */
-+			",", /* Separator */
-+			"", /* Suffix */
-+			&mechlist,
-+			NULL,
-+			NULL);
-+    if (err != SASL_OK) {
-+	VNC_DEBUG("cannot list SASL mechanisms %d (%s)\n",
-+		  err, sasl_errdetail(vs->sasl.conn));
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+    VNC_DEBUG("Available mechanisms for client: '%s'\n", mechlist);
-+
-+    if (!(vs->sasl.mechlist = strdup(mechlist))) {
-+	VNC_DEBUG("Out of memory");
-+	sasl_dispose(&vs->sasl.conn);
-+	vs->sasl.conn = NULL;
-+	goto authabort;
-+    }
-+    mechlistlen = strlen(mechlist);
-+    vnc_write_u32(vs, mechlistlen);
-+    vnc_write(vs, mechlist, mechlistlen);
-+    vnc_flush(vs);
-+
-+    VNC_DEBUG("Wait for client mechname length\n");
-+    vnc_read_when(vs, protocol_client_auth_sasl_mechname_len, 4);
-+
-+    return;
-+
-+ authabort:
-+    vnc_client_error(vs);
-+    return;
-+}
-+
-+
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.h
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.h
-@@ -0,0 +1,67 @@
-+/*
-+ * QEMU VNC display driver: SASL auth protocol
-+ *
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+
-+#ifndef __QEMU_VNC_AUTH_SASL_H__
-+#define __QEMU_VNC_AUTH_SASL_H__
-+
-+
-+#include <sasl/sasl.h>
-+
-+typedef struct VncStateSASL VncStateSASL;
-+
-+struct VncStateSASL {
-+    sasl_conn_t *conn;
-+    /* If we want to negotiate an SSF layer with client */
-+    int wantSSF :1;
-+    /* If we are now running the SSF layer */
-+    int runSSF :1;
-+    /*
-+     * If this is non-zero, then wait for that many bytes
-+     * to be written plain, before switching to SSF encoding
-+     * This allows the VNC auth result to finish being
-+     * written in plain.
-+     */
-+    unsigned int waitWriteSSF;
-+
-+    /*
-+     * Buffering encoded data to allow more clear data
-+     * to be stuffed onto the output buffer
-+     */
-+    const uint8_t *encoded;
-+    unsigned int encodedLength;
-+    unsigned int encodedOffset;
-+    char *username;
-+    char *mechlist;
-+};
-+
-+void vnc_sasl_client_cleanup(VncState *vs);
-+
-+long vnc_client_read_sasl(VncState *vs);
-+long vnc_client_write_sasl(VncState *vs);
-+
-+void start_auth_sasl(VncState *vs);
-+
-+#endif /* __QEMU_VNC_AUTH_SASL_H__ */
-+
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-vencrypt.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc-auth-vencrypt.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-vencrypt.c
-@@ -43,8 +43,15 @@ static void start_auth_vencrypt_subauth(
-        start_auth_vnc(vs);
-        break;
- 
-+#ifdef CONFIG_VNC_SASL
-+    case VNC_AUTH_VENCRYPT_TLSSASL:
-+    case VNC_AUTH_VENCRYPT_X509SASL:
-+      VNC_DEBUG("Start TLS auth SASL\n");
-+      return start_auth_sasl(vs);
-+#endif /* CONFIG_VNC_SASL */
-+
-     default: /* Should not be possible, but just in case */
--       VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
-+       VNC_DEBUG("Reject subauth %d server bug\n", vs->vd->auth);
-        vnc_write_u8(vs, 1);
-        if (vs->minor >= 8) {
-            static const char err[] = "Unsupported authentication type";
-@@ -105,7 +112,8 @@ static void vnc_tls_handshake_io(void *o
- #define NEED_X509_AUTH(vs)			      \
-     ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
-      (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
--     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
-+     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN ||  \
-+     (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL)
- 
- 
- static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -68,7 +68,8 @@ static char *addr_to_string(const char *
-     return addr;
- }
- 
--static char *vnc_socket_local_addr(const char *format, int fd) {
-+
-+char *vnc_socket_local_addr(const char *format, int fd) {
-     struct sockaddr_storage sa;
-     socklen_t salen;
- 
-@@ -79,7 +80,8 @@ static char *vnc_socket_local_addr(const
-     return addr_to_string(format, &sa, salen);
- }
- 
--static char *vnc_socket_remote_addr(const char *format, int fd) {
-+
-+char *vnc_socket_remote_addr(const char *format, int fd) {
-     struct sockaddr_storage sa;
-     socklen_t salen;
- 
-@@ -125,12 +127,18 @@ static const char *vnc_auth_name(VncDisp
- 	    return "vencrypt+x509+vnc";
- 	case VNC_AUTH_VENCRYPT_X509PLAIN:
- 	    return "vencrypt+x509+plain";
-+	case VNC_AUTH_VENCRYPT_TLSSASL:
-+	    return "vencrypt+tls+sasl";
-+	case VNC_AUTH_VENCRYPT_X509SASL:
-+	    return "vencrypt+x509+sasl";
- 	default:
- 	    return "vencrypt";
- 	}
- #else
- 	return "vencrypt";
- #endif
-+    case VNC_AUTH_SASL:
-+	return "sasl";
-     }
-     return "unknown";
- }
-@@ -278,7 +286,7 @@ static void vnc_framebuffer_update(VncSt
-     vnc_write_s32(vs, encoding);
- }
- 
--static void buffer_reserve(Buffer *buffer, size_t len)
-+void buffer_reserve(Buffer *buffer, size_t len)
- {
-     if ((buffer->capacity - buffer->offset) < len) {
- 	buffer->capacity += (len + 1024);
-@@ -290,22 +298,22 @@ static void buffer_reserve(Buffer *buffe
-     }
- }
- 
--static int buffer_empty(Buffer *buffer)
-+int buffer_empty(Buffer *buffer)
- {
-     return buffer->offset == 0;
- }
- 
--static uint8_t *buffer_end(Buffer *buffer)
-+uint8_t *buffer_end(Buffer *buffer)
- {
-     return buffer->buffer + buffer->offset;
- }
- 
--static void buffer_reset(Buffer *buffer)
-+void buffer_reset(Buffer *buffer)
- {
- 	buffer->offset = 0;
- }
- 
--static void buffer_append(Buffer *buffer, const void *data, size_t len)
-+void buffer_append(Buffer *buffer, const void *data, size_t len)
- {
-     memcpy(buffer->buffer + buffer->offset, data, len);
-     buffer->offset += len;
-@@ -821,7 +829,8 @@ static void audio_del(VncState *vs)
-     }
- }
- 
--static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
-+
-+int vnc_client_io_error(VncState *vs, int ret, int last_errno)
- {
-     if (ret == 0 || ret == -1) {
-         if (ret == -1) {
-@@ -847,6 +856,9 @@ static int vnc_client_io_error(VncState 
- #ifdef CONFIG_VNC_TLS
- 	vnc_tls_client_cleanup(vs);
- #endif /* CONFIG_VNC_TLS */
-+#ifdef CONFIG_VNC_SASL
-+        vnc_sasl_client_cleanup(vs);
-+#endif /* CONFIG_VNC_SASL */
-         audio_del(vs);
- 
-         VncState *p, *parent = NULL;
-@@ -877,14 +889,28 @@ void vnc_client_error(VncState *vs)
-     vnc_client_io_error(vs, -1, EINVAL);
- }
- 
--void vnc_client_write(void *opaque)
-+
-+/*
-+ * Called to write a chunk of data to the client socket. The data may
-+ * be the raw data, or may have already been encoded by SASL.
-+ * The data will be written either straight onto the socket, or
-+ * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
-+ *
-+ * NB, it is theoretically possible to have 2 layers of encryption,
-+ * both SASL, and this TLS layer. It is highly unlikely in practice
-+ * though, since SASL encryption will typically be a no-op if TLS
-+ * is active
-+ *
-+ * Returns the number of bytes written, which may be less than
-+ * the requested 'datalen' if the socket would block. Returns
-+ * -1 on error, and disconnects the client socket.
-+ */
-+long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
- {
-     long ret;
--    VncState *vs = opaque;
--
- #ifdef CONFIG_VNC_TLS
-     if (vs->tls.session) {
--	ret = gnutls_write(vs->tls.session, vs->output.buffer, vs->output.offset);
-+	ret = gnutls_write(vs->tls.session, data, datalen);
- 	if (ret < 0) {
- 	    if (ret == GNUTLS_E_AGAIN)
- 		errno = EAGAIN;
-@@ -894,10 +920,42 @@ void vnc_client_write(void *opaque)
- 	}
-     } else
- #endif /* CONFIG_VNC_TLS */
--	ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
--    ret = vnc_client_io_error(vs, ret, socket_error());
-+	ret = send(vs->csock, data, datalen, 0);
-+    VNC_DEBUG("Wrote wire %p %d -> %ld\n", data, datalen, ret);
-+    return vnc_client_io_error(vs, ret, socket_error());
-+}
-+
-+
-+/*
-+ * Called to write buffered data to the client socket, when not
-+ * using any SASL SSF encryption layers. Will write as much data
-+ * as possible without blocking. If all buffered data is written,
-+ * will switch the FD poll() handler back to read monitoring.
-+ *
-+ * Returns the number of bytes written, which may be less than
-+ * the buffered output data if the socket would block. Returns
-+ * -1 on error, and disconnects the client socket.
-+ */
-+static long vnc_client_write_plain(VncState *vs)
-+{
-+    long ret;
-+
-+#ifdef CONFIG_VNC_SASL
-+    VNC_DEBUG("Write Plain: Pending output %p size %d offset %d. Wait SSF %d\n",
-+              vs->output.buffer, vs->output.capacity, vs->output.offset,
-+              vs->sasl.waitWriteSSF);
-+
-+    if (vs->sasl.conn &&
-+        vs->sasl.runSSF &&
-+        vs->sasl.waitWriteSSF) {
-+        ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
-+        if (ret)
-+            vs->sasl.waitWriteSSF -= ret;
-+    } else
-+#endif /* CONFIG_VNC_SASL */
-+        ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
-     if (!ret)
--	return;
-+        return 0;
- 
-     memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
-     vs->output.offset -= ret;
-@@ -905,6 +963,29 @@ void vnc_client_write(void *opaque)
-     if (vs->output.offset == 0) {
- 	qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
-     }
-+
-+    return ret;
-+}
-+
-+
-+/*
-+ * First function called whenever there is data to be written to
-+ * the client socket. Will delegate actual work according to whether
-+ * SASL SSF layers are enabled (thus requiring encryption calls)
-+ */
-+void vnc_client_write(void *opaque)
-+{
-+    long ret;
-+    VncState *vs = opaque;
-+
-+#ifdef CONFIG_VNC_SASL
-+    if (vs->sasl.conn &&
-+        vs->sasl.runSSF &&
-+        !vs->sasl.waitWriteSSF)
-+        ret = vnc_client_write_sasl(vs);
-+    else
-+#endif /* CONFIG_VNC_SASL */
-+        ret = vnc_client_write_plain(vs);
- }
- 
- void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-@@ -913,16 +994,28 @@ void vnc_read_when(VncState *vs, VncRead
-     vs->read_handler_expect = expecting;
- }
- 
--void vnc_client_read(void *opaque)
-+
-+/*
-+ * Called to read a chunk of data from the client socket. The data may
-+ * be the raw data, or may need to be further decoded by SASL.
-+ * The data will be read either straight from to the socket, or
-+ * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
-+ *
-+ * NB, it is theoretically possible to have 2 layers of encryption,
-+ * both SASL, and this TLS layer. It is highly unlikely in practice
-+ * though, since SASL encryption will typically be a no-op if TLS
-+ * is active
-+ *
-+ * Returns the number of bytes read, which may be less than
-+ * the requested 'datalen' if the socket would block. Returns
-+ * -1 on error, and disconnects the client socket.
-+ */
-+long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
- {
--    VncState *vs = opaque;
-     long ret;
--
--    buffer_reserve(&vs->input, 4096);
--
- #ifdef CONFIG_VNC_TLS
-     if (vs->tls.session) {
--	ret = gnutls_read(vs->tls.session, buffer_end(&vs->input), 4096);
-+	ret = gnutls_read(vs->tls.session, data, datalen);
- 	if (ret < 0) {
- 	    if (ret == GNUTLS_E_AGAIN)
- 		errno = EAGAIN;
-@@ -932,12 +1025,52 @@ void vnc_client_read(void *opaque)
- 	}
-     } else
- #endif /* CONFIG_VNC_TLS */
--	ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
--    ret = vnc_client_io_error(vs, ret, socket_error());
--    if (!ret)
--	return;
-+	ret = recv(vs->csock, data, datalen, 0);
-+    VNC_DEBUG("Read wire %p %d -> %ld\n", data, datalen, ret);
-+    return vnc_client_io_error(vs, ret, socket_error());
-+}
- 
-+
-+/*
-+ * Called to read data from the client socket to the input buffer,
-+ * when not using any SASL SSF encryption layers. Will read as much
-+ * data as possible without blocking.
-+ *
-+ * Returns the number of bytes read. Returns -1 on error, and
-+ * disconnects the client socket.
-+ */
-+static long vnc_client_read_plain(VncState *vs)
-+{
-+    int ret;
-+    VNC_DEBUG("Read plain %p size %d offset %d\n",
-+              vs->input.buffer, vs->input.capacity, vs->input.offset);
-+    buffer_reserve(&vs->input, 4096);
-+    ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
-+    if (!ret)
-+        return 0;
-     vs->input.offset += ret;
-+    return ret;
-+}
-+
-+
-+/*
-+ * First function called whenever there is more data to be read from
-+ * the client socket. Will delegate actual work according to whether
-+ * SASL SSF layers are enabled (thus requiring decryption calls)
-+ */
-+void vnc_client_read(void *opaque)
-+{
-+    VncState *vs = opaque;
-+    long ret;
-+
-+#ifdef CONFIG_VNC_SASL
-+    if (vs->sasl.conn && vs->sasl.runSSF)
-+        ret = vnc_client_read_sasl(vs);
-+    else
-+#endif /* CONFIG_VNC_SASL */
-+        ret = vnc_client_read_plain(vs);
-+    if (!ret)
-+	return;
- 
-     while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
- 	size_t len = vs->read_handler_expect;
-@@ -1722,6 +1855,13 @@ static int protocol_client_auth(VncState
-            break;
- #endif /* CONFIG_VNC_TLS */
- 
-+#ifdef CONFIG_VNC_SASL
-+       case VNC_AUTH_SASL:
-+           VNC_DEBUG("Accept SASL auth\n");
-+           start_auth_sasl(vs);
-+           break;
-+#endif /* CONFIG_VNC_SASL */
-+
-        default: /* Should not be possible, but just in case */
-            VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
-            vnc_write_u8(vs, 1);
-@@ -1923,6 +2063,10 @@ int vnc_display_open(DisplayState *ds, c
- #ifdef CONFIG_VNC_TLS
-     int tls = 0, x509 = 0;
- #endif
-+#ifdef CONFIG_VNC_SASL
-+    int sasl = 0;
-+    int saslErr;
-+#endif
- 
-     if (!vnc_display)
-         return -1;
-@@ -1942,6 +2086,10 @@ int vnc_display_open(DisplayState *ds, c
- 	    reverse = 1;
- 	} else if (strncmp(options, "to=", 3) == 0) {
-             to_port = atoi(options+3) + 5900;
-+#ifdef CONFIG_VNC_SASL
-+	} else if (strncmp(options, "sasl", 4) == 0) {
-+	    sasl = 1; /* Require SASL auth */
-+#endif
- #ifdef CONFIG_VNC_TLS
- 	} else if (strncmp(options, "tls", 3) == 0) {
- 	    tls = 1; /* Require TLS */
-@@ -1978,6 +2126,22 @@ int vnc_display_open(DisplayState *ds, c
- 	}
-     }
- 
-+    /*
-+     * Combinations we support here:
-+     *
-+     *  - no-auth                (clear text, no auth)
-+     *  - password               (clear text, weak auth)
-+     *  - sasl                   (encrypt, good auth *IF* using Kerberos via GSSAPI)
-+     *  - tls                    (encrypt, weak anonymous creds, no auth)
-+     *  - tls + password         (encrypt, weak anonymous creds, weak auth)
-+     *  - tls + sasl             (encrypt, weak anonymous creds, good auth)
-+     *  - tls + x509             (encrypt, good x509 creds, no auth)
-+     *  - tls + x509 + password  (encrypt, good x509 creds, weak auth)
-+     *  - tls + x509 + sasl      (encrypt, good x509 creds, good auth)
-+     *
-+     * NB1. TLS is a stackable auth scheme.
-+     * NB2. the x509 schemes have option to validate a client cert dname
-+     */
-     if (password) {
- #ifdef CONFIG_VNC_TLS
- 	if (tls) {
-@@ -1990,13 +2154,34 @@ int vnc_display_open(DisplayState *ds, c
- 		vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
- 	    }
- 	} else {
--#endif
-+#endif /* CONFIG_VNC_TLS */
- 	    VNC_DEBUG("Initializing VNC server with password auth\n");
- 	    vs->auth = VNC_AUTH_VNC;
- #ifdef CONFIG_VNC_TLS
- 	    vs->subauth = VNC_AUTH_INVALID;
- 	}
--#endif
-+#endif /* CONFIG_VNC_TLS */
-+#ifdef CONFIG_VNC_SASL
-+    } else if (sasl) {
-+#ifdef CONFIG_VNC_TLS
-+        if (tls) {
-+            vs->auth = VNC_AUTH_VENCRYPT;
-+            if (x509) {
-+		VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
-+                vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
-+            } else {
-+		VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
-+                vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
-+            }
-+        } else {
-+#endif /* CONFIG_VNC_TLS */
-+	    VNC_DEBUG("Initializing VNC server with SASL auth\n");
-+            vs->auth = VNC_AUTH_SASL;
-+#ifdef CONFIG_VNC_TLS
-+            vs->subauth = VNC_AUTH_INVALID;
-+        }
-+#endif /* CONFIG_VNC_TLS */
-+#endif /* CONFIG_VNC_SASL */
-     } else {
- #ifdef CONFIG_VNC_TLS
- 	if (tls) {
-@@ -2018,6 +2203,16 @@ int vnc_display_open(DisplayState *ds, c
- #endif
-     }
- 
-+#ifdef CONFIG_VNC_SASL
-+    if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
-+        fprintf(stderr, "Failed to initialize SASL auth %s",
-+                sasl_errstring(saslErr, NULL, NULL));
-+        free(vs->display);
-+        vs->display = NULL;
-+        return -1;
-+    }
-+#endif
-+
-     if (reverse) {
-         /* connect to viewer */
-         if (strncmp(display, "unix:", 5) == 0)
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.h
-@@ -79,6 +79,10 @@ typedef struct VncDisplay VncDisplay;
- #include "vnc-tls.h"
- #include "vnc-auth-vencrypt.h"
- #endif
-+#ifdef CONFIG_VNC_SASL
-+#include "vnc-auth-sasl.h"
-+#endif
-+
- 
- struct VncDisplay
- {
-@@ -118,10 +122,12 @@ struct VncState
-     int minor;
- 
-     char challenge[VNC_AUTH_CHALLENGE_SIZE];
--
- #ifdef CONFIG_VNC_TLS
-     VncStateTLS tls;
- #endif
-+#ifdef CONFIG_VNC_SASL
-+    VncStateSASL sasl;
-+#endif
- 
-     Buffer output;
-     Buffer input;
-@@ -160,8 +166,9 @@ enum {
-     VNC_AUTH_RA2NE = 6,
-     VNC_AUTH_TIGHT = 16,
-     VNC_AUTH_ULTRA = 17,
--    VNC_AUTH_TLS = 18,
--    VNC_AUTH_VENCRYPT = 19
-+    VNC_AUTH_TLS = 18,      /* Supported in GTK-VNC & VINO */
-+    VNC_AUTH_VENCRYPT = 19, /* Supported in GTK-VNC & VeNCrypt */
-+    VNC_AUTH_SASL = 20,     /* Supported in GTK-VNC & VINO */
- };
- 
- enum {
-@@ -172,6 +179,8 @@ enum {
-     VNC_AUTH_VENCRYPT_X509NONE = 260,
-     VNC_AUTH_VENCRYPT_X509VNC = 261,
-     VNC_AUTH_VENCRYPT_X509PLAIN = 262,
-+    VNC_AUTH_VENCRYPT_X509SASL = 263,
-+    VNC_AUTH_VENCRYPT_TLSSASL = 264,
- };
- 
- 
-@@ -255,6 +264,8 @@ enum {
- void vnc_client_read(void *opaque);
- void vnc_client_write(void *opaque);
- 
-+long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
-+long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
- 
- /* Protocol I/O functions */
- void vnc_write(VncState *vs, const void *data, size_t len);
-@@ -274,8 +285,22 @@ uint32_t read_u32(uint8_t *data, size_t 
- 
- /* Protocol stage functions */
- void vnc_client_error(VncState *vs);
-+int vnc_client_io_error(VncState *vs, int ret, int last_errno);
- 
- void start_client_init(VncState *vs);
- void start_auth_vnc(VncState *vs);
- 
-+/* Buffer management */
-+void buffer_reserve(Buffer *buffer, size_t len);
-+int buffer_empty(Buffer *buffer);
-+uint8_t *buffer_end(Buffer *buffer);
-+void buffer_reset(Buffer *buffer);
-+void buffer_append(Buffer *buffer, const void *data, size_t len);
-+
-+
-+/* Misc helpers */
-+
-+char *vnc_socket_local_addr(const char *format, int fd);
-+char *vnc_socket_remote_addr(const char *format, int fd);
-+
- #endif /* __QEMU_VNC_H */
diff --git a/qemu-sasl-07-vnc-monitor-authinfo.patch b/qemu-sasl-07-vnc-monitor-authinfo.patch
deleted file mode 100644
index 2c80faa..0000000
--- a/qemu-sasl-07-vnc-monitor-authinfo.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-This patch extends the 'info vnc' monitor output to include information
-about the VNC client authentication credentials.
-
-For clients authenticated using SASL, this will output the username.
-
-For clients authenticated using x509 certificates, this will output
-the x509 distinguished name.
-
-Auth can be stacked, so both username & x509 dname may be shown.
-
-    Server:
-         address: 0.0.0.0:5902
-            auth: vencrypt+x509+sasl
-    Client:
-         address: 10.33.6.67:38621
-      x509 dname: C=GB,O=ACME,L=London,ST=London,CN=localhost
-        username: admin
-    Client:
-         address: 10.33.6.63:38620
-      x509 dname: C=GB,O=ACME,L=London,ST=London,CN=localhost
-        username: admin
-
-
-
- vnc-tls.c |   17 +++++++++++++++++
- vnc-tls.h |    3 +++
- vnc.c     |   19 +++++++++++++++++--
- 3 files changed, 37 insertions(+), 2 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
-@@ -241,6 +241,22 @@ int vnc_tls_validate_certificate(struct 
- 	    return -1;
- 	}
- 
-+	if (i == 0) {
-+	    size_t dnameSize = 1024;
-+	    vs->tls.dname = qemu_malloc(dnameSize);
-+	requery:
-+	    if ((ret = gnutls_x509_crt_get_dn (cert, vs->tls.dname, &dnameSize)) != 0) {
-+		if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
-+		    vs->tls.dname = qemu_realloc(vs->tls.dname, dnameSize);
-+		    goto requery;
-+		}
-+		gnutls_x509_crt_deinit (cert);
-+		VNC_DEBUG("Cannot get client distinguished name: %s",
-+			  gnutls_strerror (ret));
-+		return -1;
-+	    }
-+	}
-+
- 	gnutls_x509_crt_deinit (cert);
-     }
- 
-@@ -347,6 +363,7 @@ void vnc_tls_client_cleanup(struct VncSt
- 	vs->tls.session = NULL;
-     }
-     vs->tls.wiremode = VNC_WIREMODE_CLEAR;
-+    free(vs->tls.dname);
- }
- 
- 
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
-@@ -55,6 +55,9 @@ struct VncStateTLS {
-     /* Whether data is being TLS encrypted yet */
-     int wiremode;
-     gnutls_session_t session;
-+
-+    /* Client's Distinguished Name from the x509 cert */
-+    char *dname;
- };
- 
- int vnc_tls_client_setup(VncState *vs, int x509Creds);
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -156,6 +156,21 @@ static void do_info_vnc_client(VncState 
-     term_puts("Client:\n");
-     term_puts(clientAddr);
-     free(clientAddr);
-+
-+#ifdef CONFIG_VNC_TLS
-+    if (client->tls.session &&
-+	client->tls.dname)
-+	term_printf("  x509 dname: %s\n", client->tls.dname);
-+    else
-+	term_puts("  x509 dname: none\n");
-+#endif
-+#ifdef CONFIG_VNC_SASL
-+    if (client->sasl.conn &&
-+	client->sasl.username)
-+	term_printf("    username: %s\n", client->sasl.username);
-+    else
-+	term_puts("    username: none\n");
-+#endif
- }
- 
- void do_info_vnc(void)
-@@ -1823,7 +1838,7 @@ static int protocol_client_auth(VncState
-     /* We only advertise 1 auth scheme at a time, so client
-      * must pick the one we sent. Verify this */
-     if (data[0] != vs->vd->auth) { /* Reject auth */
--       VNC_DEBUG("Reject auth %d\n", (int)data[0]);
-+       VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
-        vnc_write_u32(vs, 1);
-        if (vs->minor >= 8) {
-            static const char err[] = "Authentication failed";
-@@ -1863,7 +1878,7 @@ static int protocol_client_auth(VncState
- #endif /* CONFIG_VNC_SASL */
- 
-        default: /* Should not be possible, but just in case */
--           VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
-+           VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
-            vnc_write_u8(vs, 1);
-            if (vs->minor >= 8) {
-                static const char err[] = "Authentication failed";
diff --git a/qemu-sasl-08-vnc-acl-mgmt.patch b/qemu-sasl-08-vnc-acl-mgmt.patch
deleted file mode 100644
index 271925f..0000000
--- a/qemu-sasl-08-vnc-acl-mgmt.patch
+++ /dev/null
@@ -1,781 +0,0 @@
-This patch introduces a generic internal API for access control lists
-to be used by network servers in QEMU. It adds support for checking
-these ACL in the VNC server, in two places. The first ACL is for the
-SASL authentication mechanism, checking the SASL username. This ACL
-is called 'vnc.username'. The second is for the TLS authentication
-mechanism, when x509 client certificates are turned on, checking against
-the Distinguished Name of the client. This ACL is called 'vnc.x509dname'
-
-The internal API provides for an ACL with the following characteristics
-
- - A unique name, eg  vnc.username, and vnc.x509dname.
- - A default policy, allow or deny
- - An ordered series of match rules, with allow or deny policy
-
-If none of the match rules apply, then the default policy is
-used.
-
-There is a monitor API to manipulate the ACLs, which I'll describe via
-examples
-
-  (qemu) acl show vnc.username
-  policy: allow
-  (qemu) acl policy vnc.username denya
-  acl: policy set to 'deny'
-  (qemu) acl allow vnc.username fred
-  acl: added rule at position 1
-  (qemu) acl allow vnc.username bob
-  acl: added rule at position 2
-  (qemu) acl allow vnc.username joe 1
-  acl: added rule at position 1
-  (qemu) acl show vnc.username
-  policy: deny
-  0: allow fred
-  1: allow joe
-  2: allow bob
-
-
-  (qemu) acl show vnc.x509dname
-  policy: allow
-  (qemu) acl policy vnc.x509dname deny
-  acl: policy set to 'deny'
-  (qemu) acl allow vnc.x509dname C=GB,O=ACME,L=London,CN=*
-  acl: added rule at position 1
-  (qemu) acl allow vnc.x509dname C=GB,O=ACME,L=Boston,CN=bob
-  acl: added rule at position 2
-  (qemu) acl show vnc.x509dname
-  policy: deny
-  0: allow C=GB,O=ACME,L=London,CN=*
-  1: allow C=GB,O=ACME,L=Boston,CN=bob
-
-By default the VNC server will not use any ACLs, allowing access to
-the server if the user successfully authenticates. To enable use of
-ACLs to restrict user access, the ',acl' flag should be given when
-starting QEMU. The initial ACL activated will be a 'deny all' policy
-and should be customized using monitor commands.
-
-eg enable SASL auth and ACLs
-
-    qemu ....  -vnc localhost:1,sasl,acl
-
-The next patch will provide a way to load a pre-defined ACL when
-starting up
-
-
- Makefile        |    6 +
- b/acl.c         |  185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- b/acl.h         |   74 ++++++++++++++++++++++
- configure       |   18 +++++
- monitor.c       |   95 ++++++++++++++++++++++++++++
- qemu-doc.texi   |   49 ++++++++++++++
- vnc-auth-sasl.c |   16 +++-
- vnc-auth-sasl.h |    7 ++
- vnc-tls.c       |   19 +++++
- vnc-tls.h       |    3 
- vnc.c           |   21 ++++++
- vnc.h           |    3 
- 12 files changed, 491 insertions(+), 5 deletions(-)
-
-   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: kvm-84.git-snapshot-20090303/qemu/Makefile
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/Makefile
-+++ kvm-84.git-snapshot-20090303/qemu/Makefile
-@@ -148,7 +148,7 @@ endif
- ifdef CONFIG_CURSES
- OBJS+=curses.o
- endif
--OBJS+=vnc.o d3des.o
-+OBJS+=vnc.o acl.o d3des.o
- ifdef CONFIG_VNC_TLS
- OBJS+=vnc-tls.o vnc-auth-vencrypt.o
- endif
-@@ -178,9 +178,11 @@ sdl.o: sdl.c keymaps.h sdl_keysym.h
- 
- sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
- 
-+acl.o: acl.h acl.c
-+
- vnc.h: vnc-tls.h vnc-auth-vencrypt.h vnc-auth-sasl.h keymaps.h
- 
--vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h
-+vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h acl.h
- 
- vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
- 
-Index: kvm-84.git-snapshot-20090303/qemu/acl.c
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/acl.c
-@@ -0,0 +1,185 @@
-+/*
-+ * QEMU access control list management
-+ *
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+
-+#include "qemu-common.h"
-+#include "sysemu.h"
-+#include "acl.h"
-+
-+#ifdef HAVE_FNMATCH_H
-+#include <fnmatch.h>
-+#endif
-+
-+
-+static unsigned int nacls = 0;
-+static qemu_acl **acls = NULL;
-+
-+
-+
-+qemu_acl *qemu_acl_find(const char *aclname)
-+{
-+    int i;
-+    for (i = 0 ; i < nacls ; i++) {
-+	if (strcmp(acls[i]->aclname, aclname) == 0)
-+	    return acls[i];
-+    }
-+
-+    return NULL;
-+}
-+
-+qemu_acl *qemu_acl_init(const char *aclname)
-+{
-+    qemu_acl *acl;
-+
-+    acl = qemu_acl_find(aclname);
-+    if (acl)
-+	return acl;
-+
-+    acl = qemu_malloc(sizeof(*acl));
-+    acl->aclname = qemu_strdup(aclname);
-+    /* Deny by default, so there is no window of "open
-+     * access" between QEMU starting, and the user setting
-+     * up ACLs in the monitor */
-+    acl->defaultDeny = 1;
-+
-+    acl->nentries = 0;
-+    TAILQ_INIT(&acl->entries);
-+
-+    acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1));
-+    acls[nacls] = acl;
-+    nacls++;
-+
-+    return acl;
-+}
-+
-+int qemu_acl_party_is_allowed(qemu_acl *acl,
-+			      const char *party)
-+{
-+    qemu_acl_entry *entry;
-+
-+    TAILQ_FOREACH(entry, &acl->entries, next) {
-+#ifdef HAVE_FNMATCH_H
-+	if (fnmatch(entry->match, party, 0) == 0)
-+	    return entry->deny ? 0 : 1;
-+#else
-+	/* No fnmatch, so fallback to exact string matching
-+	 * instead of allowing wildcards */
-+	if (strcmp(entry->match, party) == 0)
-+	    return entry->deny ? 0 : 1;
-+#endif
-+    }
-+
-+    return acl->defaultDeny ? 0 : 1;
-+}
-+
-+
-+void qemu_acl_reset(qemu_acl *acl)
-+{
-+    qemu_acl_entry *entry;
-+
-+    /* Put back to deny by default, so there is no window
-+     * of "open access" while the user re-initializes the
-+     * access control list */
-+    acl->defaultDeny = 1;
-+    TAILQ_FOREACH(entry, &acl->entries, next) {
-+	TAILQ_REMOVE(&acl->entries, entry, next);
-+	free(entry->match);
-+	free(entry);
-+    }
-+    acl->nentries = 0;
-+}
-+
-+
-+int qemu_acl_append(qemu_acl *acl,
-+		    int deny,
-+		    const char *match)
-+{
-+    qemu_acl_entry *entry;
-+
-+    entry = qemu_malloc(sizeof(*entry));
-+    entry->match = qemu_strdup(match);
-+    entry->deny = deny;
-+
-+    TAILQ_INSERT_TAIL(&acl->entries, entry, next);
-+    acl->nentries++;
-+
-+    return acl->nentries;
-+}
-+
-+
-+int qemu_acl_insert(qemu_acl *acl,
-+		    int deny,
-+		    const char *match,
-+		    int index)
-+{
-+    qemu_acl_entry *entry;
-+    qemu_acl_entry *tmp;
-+    int i = 0;
-+
-+    if (index <= 0)
-+	return -1;
-+    if (index >= acl->nentries)
-+	return qemu_acl_append(acl, deny, match);
-+
-+
-+    entry = qemu_malloc(sizeof(*entry));
-+    entry->match = qemu_strdup(match);
-+    entry->deny = deny;
-+
-+    TAILQ_FOREACH(tmp, &acl->entries, next) {
-+	i++;
-+	if (i == index) {
-+	    TAILQ_INSERT_BEFORE(tmp, entry, next);
-+	    acl->nentries++;
-+	    break;
-+	}
-+    }
-+
-+    return i;
-+}
-+
-+int qemu_acl_remove(qemu_acl *acl,
-+		    const char *match)
-+{
-+    qemu_acl_entry *entry;
-+    int i = 0;
-+
-+    TAILQ_FOREACH(entry, &acl->entries, next) {
-+	i++;
-+	if (strcmp(entry->match, match) == 0) {
-+	    TAILQ_REMOVE(&acl->entries, entry, next);
-+	    return i;
-+	}
-+    }
-+    return -1;
-+}
-+
-+
-+/*
-+ * Local variables:
-+ *  c-indent-level: 4
-+ *  c-basic-offset: 4
-+ *  tab-width: 8
-+ * End:
-+ */
-Index: kvm-84.git-snapshot-20090303/qemu/acl.h
-===================================================================
---- /dev/null
-+++ kvm-84.git-snapshot-20090303/qemu/acl.h
-@@ -0,0 +1,74 @@
-+/*
-+ * QEMU access control list management
-+ *
-+ * Copyright (C) 2009 Red Hat, Inc
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#ifndef __QEMU_ACL_H__
-+#define __QEMU_ACL_H__
-+
-+#include "sys-queue.h"
-+
-+typedef struct qemu_acl_entry qemu_acl_entry;
-+typedef struct qemu_acl qemu_acl;
-+
-+struct qemu_acl_entry {
-+    char *match;
-+    int deny;
-+
-+    TAILQ_ENTRY(qemu_acl_entry) next;
-+};
-+
-+struct qemu_acl {
-+    char *aclname;
-+    unsigned int nentries;
-+    TAILQ_HEAD(,qemu_acl_entry) entries;
-+    int defaultDeny;
-+};
-+
-+qemu_acl *qemu_acl_init(const char *aclname);
-+
-+qemu_acl *qemu_acl_find(const char *aclname);
-+
-+int qemu_acl_party_is_allowed(qemu_acl *acl,
-+			      const char *party);
-+
-+void qemu_acl_reset(qemu_acl *acl);
-+
-+int qemu_acl_append(qemu_acl *acl,
-+		    int deny,
-+		    const char *match);
-+int qemu_acl_insert(qemu_acl *acl,
-+		    int deny,
-+		    const char *match,
-+		    int index);
-+int qemu_acl_remove(qemu_acl *acl,
-+		    const char *match);
-+
-+#endif /* __QEMU_ACL_H__ */
-+
-+/*
-+ * Local variables:
-+ *  c-indent-level: 4
-+ *  c-basic-offset: 4
-+ *  tab-width: 8
-+ * End:
-+ */
-Index: kvm-84.git-snapshot-20090303/qemu/configure
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/configure
-+++ kvm-84.git-snapshot-20090303/qemu/configure
-@@ -897,6 +897,21 @@ EOF
- fi
- 
- ##########################################
-+# fnmatch() probe, used for ACL routines
-+fnmatch="no"
-+cat > $TMPC << EOF
-+#include <fnmatch.h>
-+int main(void)
-+{
-+    fnmatch("foo", "foo", 0);
-+    return 0;
-+}
-+EOF
-+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
-+   fnmatch="yes"
-+fi
-+
-+##########################################
- # vde libraries probe
- if test "$vde" = "yes" ; then
-   cat > $TMPC << EOF
-@@ -1485,6 +1500,9 @@ if test "$vnc_sasl" = "yes" ; then
-   echo "CONFIG_VNC_SASL_LIBS=$vnc_sasl_libs" >> $config_mak
-   echo "#define CONFIG_VNC_SASL 1" >> $config_h
- fi
-+if test "$fnmatch" = "yes" ; then
-+  echo "#define HAVE_FNMATCH_H 1" >> $config_h
-+fi
- qemu_version=`head $source_path/VERSION`
- echo "VERSION=$qemu_version" >>$config_mak
- echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h
-Index: kvm-84.git-snapshot-20090303/qemu/monitor.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/monitor.c
-+++ kvm-84.git-snapshot-20090303/qemu/monitor.c
-@@ -39,6 +39,7 @@
- #include "qemu-timer.h"
- #include "migration.h"
- #include "kvm.h"
-+#include "acl.h"
- 
- #include "qemu-kvm.h"
- 
-@@ -1452,6 +1453,85 @@ static void do_info_balloon(void)
-         term_printf("balloon: actual=%d\n", (int)(actual >> 20));
- }
- 
-+static void do_acl(const char *command,
-+		   const char *aclname,
-+		   const char *match,
-+		   int has_index,
-+		   int index)
-+{
-+    qemu_acl *acl;
-+
-+    acl = qemu_acl_find(aclname);
-+    if (!acl) {
-+	term_printf("acl: unknown list '%s'\n", aclname);
-+	return;
-+    }
-+
-+    if (strcmp(command, "show") == 0) {
-+	int i = 0;
-+	qemu_acl_entry *entry;
-+	term_printf("policy: %s\n",
-+		    acl->defaultDeny ? "deny" : "allow");
-+	TAILQ_FOREACH(entry, &acl->entries, next) {
-+	    i++;
-+	    term_printf("%d: %s %s\n", i,
-+			entry->deny ? "deny" : "allow",
-+			entry->match);
-+	}
-+    } else if (strcmp(command, "reset") == 0) {
-+	qemu_acl_reset(acl);
-+	term_printf("acl: removed all rules\n");
-+    } else if (strcmp(command, "policy") == 0) {
-+	if (!match) {
-+	    term_printf("acl: missing policy parameter\n");
-+	    return;
-+	}
-+
-+	if (strcmp(match, "allow") == 0) {
-+	    acl->defaultDeny = 0;
-+	    term_printf("acl: policy set to 'allow'\n");
-+	} else if (strcmp(match, "deny") == 0) {
-+	    acl->defaultDeny = 1;
-+	    term_printf("acl: policy set to 'deny'\n");
-+	} else {
-+	    term_printf("acl: unknown policy '%s', expected 'deny' or 'allow'\n", match);
-+	}
-+    } else if ((strcmp(command, "allow") == 0) ||
-+	       (strcmp(command, "deny") == 0)) {
-+	int deny = strcmp(command, "deny") == 0 ? 1 : 0;
-+	int ret;
-+
-+	if (!match) {
-+	    term_printf("acl: missing match parameter\n");
-+	    return;
-+	}
-+
-+	if (has_index)
-+	    ret = qemu_acl_insert(acl, deny, match, index);
-+	else
-+	    ret = qemu_acl_append(acl, deny, match);
-+	if (ret < 0)
-+	    term_printf("acl: unable to add acl entry\n");
-+	else
-+	    term_printf("acl: added rule at position %d\n", ret);
-+    } else if (strcmp(command, "remove") == 0) {
-+	int ret;
-+
-+	if (!match) {
-+	    term_printf("acl: missing match parameter\n");
-+	    return;
-+	}
-+
-+	ret = qemu_acl_remove(acl, match);
-+	if (ret < 0)
-+	    term_printf("acl: no matching acl entry\n");
-+	else
-+	    term_printf("acl: removed rule at position %d\n", ret);
-+    } else {
-+	term_printf("acl: unknown command '%s'\n", command);
-+    }
-+}
-+
- /* Please update qemu-doc.texi when adding or changing commands */
- static const term_cmd_t term_cmds[] = {
-     { "help|?", "s?", do_help,
-@@ -1557,6 +1637,12 @@ static const term_cmd_t term_cmds[] = {
-     { "set_link", "ss", do_set_link,
-       "name [up|down]", "change the link status of a network adapter" },
-     { "set_link", "ss", do_set_link, "name [up|down]" },
-+    { "acl", "sss?i?", do_acl, "<command> <aclname> [<match>] [<index>]\n",
-+                               "acl show vnc.username\n"
-+                               "acl policy vnc.username deny\n"
-+                               "acl allow vnc.username fred\n"
-+                               "acl deny vnc.username bob\n"
-+                               "acl reset vnc.username\n" },
-     { "cpu_set", "is", do_cpu_set_nr, "cpu [online|offline]", "change cpu state" },
- #if defined(TARGET_I386) || defined(TARGET_X86_64)
-     { "drive_add", "iss", drive_hot_add, "pcibus pcidevfn [file=file][,if=type][,bus=n]\n"
-@@ -2927,3 +3013,12 @@ void monitor_readline(const char *prompt
-                 monitor_hd[i]->focus = old_focus[i];
-     }
- }
-+
-+
-+/*
-+ * Local variables:
-+ *  c-indent-level: 4
-+ *  c-basic-offset: 4
-+ *  tab-width: 8
-+ * End:
-+ */
-Index: kvm-84.git-snapshot-20090303/qemu/qemu-doc.texi
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/qemu-doc.texi
-+++ kvm-84.git-snapshot-20090303/qemu/qemu-doc.texi
-@@ -639,6 +639,19 @@ ensures a data encryption preventing com
- credentials. See the @ref{vnc_security} section for details on using
- SASL authentication.
- 
-+@item acl
-+
-+Turn on access control lists for checking of the x509 client certificate
-+and SASL party. For x509 certs, the ACL check is made against the
-+certificate's distinguished name. This is something that looks like
-+@code{C=GB,O=ACME,L=Boston,CN=bob}. For SASL party, the ACL check is
-+made against the username, which depending on the SASL plugin, may
-+include a realm component, eg @code{bob} or @code{bob\@EXAMPLE.COM}.
-+When the @option{acl} flag is set, the initial access list will be
-+empty, with a @code{deny} policy. Thus no one will be allowed to
-+use the VNC server until the ACLs have been loaded. This can be
-+achieved using the @code{acl} monitor command.
-+
- @end table
- 
- @end table
-@@ -1389,6 +1402,42 @@ Password: ********
- 
- @end table
- 
-+@item acl @var{subcommand} @var{aclname} @var{match} @var{index}
-+
-+Manage access control lists for network services. There are currently
-+two named access control lists, @var{vnc.x509dname} and @var{vnc.username}
-+matching on the x509 client certificate distinguished name, and SASL
-+username respectively.
-+
-+@table @option
-+@item acl show <aclname>
-+list all the match rules in the access control list, and the default
-+policy
-+@item acl policy <aclname> @code{allow|deny}
-+set the default access control list policy, used in the event that
-+none of the explicit rules match. The default policy at startup is
-+always @code{deny}
-+@item acl allow <aclname> <match> [<index>]
-+add a match to the access control list, allowing access. The match will
-+normally be an exact username or x509 distinguished name, but can
-+optionally include wildcard globs. eg @code{*\@EXAMPLE.COM} to allow
-+all users in the @code{EXAMPLE.COM} kerberos realm. The match will
-+normally be appended to the end of the ACL, but can be inserted
-+earlier in the list if the optional @code{index} parameter is supplied.
-+@item acl deny <aclname> <match> [<index>]
-+add a match to the access control list, denying access. The match will
-+normally be an exact username or x509 distinguished name, but can
-+optionally include wildcard globs. eg @code{*\@EXAMPLE.COM} to allow
-+all users in the @code{EXAMPLE.COM} kerberos realm. The match will
-+normally be appended to the end of the ACL, but can be inserted
-+earlier in the list if the optional @code{index} parameter is supplied.
-+@item acl remove <aclname> <match>
-+remove the specified match rule from the access control list.
-+@item acl reset <aclname>
-+remove all matches from the access control list, and set the default
-+policy back to @code{deny}.
-+@end table
-+
- @item screendump @var{filename}
- Save screen into PPM image @var{filename}.
- 
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc-auth-sasl.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.c
-@@ -120,22 +120,32 @@ static int vnc_auth_sasl_check_access(Vn
- {
-     const void *val;
-     int err;
-+    int allow;
- 
-     err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val);
-     if (err != SASL_OK) {
--	VNC_DEBUG("cannot query SASL username on connection %d (%s)\n",
-+	VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n",
- 		  err, sasl_errstring(err, NULL, NULL));
- 	return -1;
-     }
-     if (val == NULL) {
--	VNC_DEBUG("no client username was found\n");
-+	VNC_DEBUG("no client username was found, denying access\n");
- 	return -1;
-     }
-     VNC_DEBUG("SASL client username %s\n", (const char *)val);
- 
-     vs->sasl.username = qemu_strdup((const char*)val);
- 
--    return 0;
-+    if (vs->vd->sasl.acl == NULL) {
-+	VNC_DEBUG("no ACL activated, allowing access\n");
-+	return 0;
-+    }
-+
-+    allow = qemu_acl_party_is_allowed(vs->vd->sasl.acl, vs->sasl.username);
-+
-+    VNC_DEBUG("SASL client %s %s by ACL\n", vs->sasl.username,
-+	      allow ? "allowed" : "denied");
-+    return allow ? 0 : -1;
- }
- 
- static int vnc_auth_sasl_check_ssf(VncState *vs)
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc-auth-sasl.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.h
-@@ -30,6 +30,9 @@
- #include <sasl/sasl.h>
- 
- typedef struct VncStateSASL VncStateSASL;
-+typedef struct VncDisplaySASL VncDisplaySASL;
-+
-+#include "acl.h"
- 
- struct VncStateSASL {
-     sasl_conn_t *conn;
-@@ -56,6 +59,10 @@ struct VncStateSASL {
-     char *mechlist;
- };
- 
-+struct VncDisplaySASL {
-+    qemu_acl *acl;
-+};
-+
- void vnc_sasl_client_cleanup(VncState *vs);
- 
- long vnc_client_read_sasl(VncState *vs);
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
-@@ -255,6 +255,25 @@ int vnc_tls_validate_certificate(struct 
- 			  gnutls_strerror (ret));
- 		return -1;
- 	    }
-+
-+	    if (vs->vd->tls.x509verify) {
-+		int allow;
-+		if (!vs->vd->tls.acl) {
-+		    VNC_DEBUG("no ACL activated, allowing access");
-+		    gnutls_x509_crt_deinit (cert);
-+		    continue;
-+		}
-+
-+		allow = qemu_acl_party_is_allowed(vs->vd->tls.acl,
-+						  vs->tls.dname);
-+
-+		VNC_DEBUG("TLS x509 ACL check for %s is %s\n",
-+			  vs->tls.dname, allow ? "allowed" : "denied");
-+		if (!allow) {
-+		    gnutls_x509_crt_deinit (cert);
-+		    return -1;
-+		}
-+	    }
- 	}
- 
- 	gnutls_x509_crt_deinit (cert);
-Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
-@@ -31,6 +31,8 @@
- #include <gnutls/gnutls.h>
- #include <gnutls/x509.h>
- 
-+#include "acl.h"
-+
- enum {
-     VNC_WIREMODE_CLEAR,
-     VNC_WIREMODE_TLS,
-@@ -42,6 +44,7 @@ typedef struct VncStateTLS VncStateTLS;
- /* Server state */
- struct VncDisplayTLS {
-     int x509verify; /* Non-zero if server requests & validates client cert */
-+    qemu_acl *acl;
- 
-     /* Paths to x509 certs/keys */
-     char *x509cacert;
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
-@@ -28,6 +28,7 @@
- #include "sysemu.h"
- #include "qemu_socket.h"
- #include "qemu-timer.h"
-+#include "acl.h"
- 
- #define VNC_REFRESH_INTERVAL (1000 / 30)
- 
-@@ -2082,6 +2083,7 @@ int vnc_display_open(DisplayState *ds, c
-     int sasl = 0;
-     int saslErr;
- #endif
-+    int acl = 0;
- 
-     if (!vnc_display)
-         return -1;
-@@ -2138,9 +2140,28 @@ int vnc_display_open(DisplayState *ds, c
- 		return -1;
- 	    }
- #endif
-+	} else if (strncmp(options, "acl", 3) == 0) {
-+	    acl = 1;
- 	}
-     }
- 
-+#ifdef CONFIG_VNC_TLS
-+    if (acl && x509 && vs->tls.x509verify) {
-+	if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
-+	    fprintf(stderr, "Failed to create x509 dname ACL\n");
-+	    exit(1);
-+	}
-+    }
-+#endif
-+#ifdef CONFIG_VNC_SASL
-+    if (acl && sasl) {
-+	if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
-+	    fprintf(stderr, "Failed to create username ACL\n");
-+	    exit(1);
-+	}
-+    }
-+#endif
-+
-     /*
-      * Combinations we support here:
-      *
-Index: kvm-84.git-snapshot-20090303/qemu/vnc.h
-===================================================================
---- kvm-84.git-snapshot-20090303.orig/qemu/vnc.h
-+++ kvm-84.git-snapshot-20090303/qemu/vnc.h
-@@ -98,6 +98,9 @@ struct VncDisplay
-     int subauth; /* Used by VeNCrypt */
-     VncDisplayTLS tls;
- #endif
-+#ifdef CONFIG_VNC_SASL
-+    VncDisplaySASL sasl;
-+#endif
- };
- 
- struct VncState
diff --git a/qemu.spec b/qemu.spec
index df8906c..9d0203f 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -1,7 +1,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 0.10
-Release: 0.5.kvm20090303git%{?dist}
+Release: 0.6.kvm20090310git%{?dist}
 # I have mistakenly thought the revision name would be 1.0.
 # So 0.10 series get Epoch = 1
 Epoch: 2
@@ -10,25 +10,12 @@ Group: Development/Tools
 URL: http://www.qemu.org/
 #Source0: http://www.qemu.org/%{name}-%{version}.tar.gz
 # FIXME: Say how to get the sources
-Source0: kvm-84.git-snapshot-20090303.tar.gz
+Source0: kvm-84.git-snapshot-20090310.tar.gz
 Source1: qemu.init
 Source2: kvm.modules
 
-# VNC SASL authentication support
-# Not upstream yet, but approved for commit immediately
-# after this release
-Patch1: qemu-sasl-01-tls-handshake-fix.patch
-Patch2: qemu-sasl-02-vnc-monitor-info.patch
-Patch3: qemu-sasl-03-display-keymaps.patch
-Patch4: qemu-sasl-04-vnc-struct.patch
-Patch5: qemu-sasl-05-vnc-tls-vencrypt.patch
-Patch6: qemu-sasl-06-vnc-sasl.patch
-Patch7: qemu-sasl-07-vnc-monitor-authinfo.patch
-Patch8: qemu-sasl-08-vnc-acl-mgmt.patch
-Patch9: kvm-upstream-ppc.patch
-Patch10: kvm-fix-strayR.patch
-# NB, delibrately not including patch 09 which is not
-# intended for commit
+Patch1: kvm-upstream-ppc.patch
+Patch2: kvm-fix-strayR.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
@@ -190,25 +177,9 @@ such as kvmtrace and kvm_stat.
 %endif
 
 %prep
-%setup -q -n kvm-84.git-snapshot-20090303
-# 01-tls-handshake-fix
+%setup -q -n kvm-84.git-snapshot-20090310
 %patch1 -p1
-# 02-vnc-monitor-info
 %patch2 -p1
-# 03-display-keymaps
-%patch3 -p1
-# 04-vnc-struct
-%patch4 -p1
-# 05-vnc-tls-vencrypt
-%patch5 -p1
-# 06-vnc-sasl
-%patch6 -p1
-# 07-vnc-monitor-authinfo
-%patch7 -p1
-# 08-vnc-acl-mgmt
-%patch8 -p1
-%patch9 -p1
-%patch10 -p1
 
 %build
 # systems like rhel build system does not have a recent enough linker so
@@ -258,7 +229,7 @@ cd qemu
                 sparc32plus-linux-user" \
     --prefix=%{_prefix} \
     --interp-prefix=%{_prefix}/qemu-%%M \
-            --kerneldir=$(pwd)/../kernel --prefix=%{_prefix} \
+    --kerneldir=$(pwd)/../kernel --prefix=%{_prefix} \
     --disable-kvm \
     --extra-ldflags=$extraldflags
 
@@ -438,6 +409,10 @@ fi
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Tue Mar 10 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.6.kvm20090310git
+- updated to kvm20090310git
+- removed sasl patches (already in this release)
+
 * Tue Mar 10 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.5.kvm20090303git
 - kvm.modules were being wrongly mentioned at %%install.
 - update description for the x86 system package to include kvm support
diff --git a/sources b/sources
index 0877184..f4afd25 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-b81c0982015b21e01fe93a1d9405def8  kvm-84.git-snapshot-20090303.tar.gz
+a43cc777acc08855e0364d249bff3da6  kvm-84.git-snapshot-20090310.tar.gz