diff --git a/.cvsignore b/.cvsignore
index 53c87a3..97f3c02 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1 +1 @@
-qemu-kvm-0.10.tar.gz
+qemu-kvm-*.tar.gz
diff --git a/01-tls-handshake-fix.patch b/01-tls-handshake-fix.patch
deleted file mode 100644
index 112c4fe..0000000
--- a/01-tls-handshake-fix.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-Index: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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/02-vnc-monitor-info.patch b/02-vnc-monitor-info.patch
deleted file mode 100644
index 04a3988..0000000
--- a/02-vnc-monitor-info.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-Index: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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/03-display-keymaps.patch b/03-display-keymaps.patch
deleted file mode 100644
index 6819d74..0000000
--- a/03-display-keymaps.patch
+++ /dev/null
@@ -1,330 +0,0 @@
-Index: qemu-kvm-0.10/qemu/Makefile
-===================================================================
---- qemu-kvm-0.10.orig/qemu/Makefile
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/curses.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/curses.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/curses_keys.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/curses_keys.h
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/keymaps.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/keymaps.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/keymaps.h
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/sdl.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/sdl.c
-+++ qemu-kvm-0.10/qemu/sdl.c
-@@ -109,7 +109,6 @@ static void sdl_resize(DisplayState *ds)
- /* generic keyboard conversion */
- 
- #include "sdl_keysym.h"
--#include "keymaps.c"
- 
- static kbd_layout_t *kbd_layout = NULL;
- 
-@@ -677,7 +676,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: qemu-kvm-0.10/qemu/sdl_keysym.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/sdl_keysym.h
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc_keysym.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc_keysym.h
-+++ qemu-kvm-0.10/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/04-vnc-struct.patch b/04-vnc-struct.patch
deleted file mode 100644
index eb7a346..0000000
--- a/04-vnc-struct.patch
+++ /dev/null
@@ -1,304 +0,0 @@
-Index: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.h
-+++ qemu-kvm-0.10/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/05-vnc-tls-vencrypt.patch b/05-vnc-tls-vencrypt.patch
deleted file mode 100644
index 625a5b6..0000000
--- a/05-vnc-tls-vencrypt.patch
+++ /dev/null
@@ -1,1644 +0,0 @@
-Index: qemu-kvm-0.10/qemu/Makefile
-===================================================================
---- qemu-kvm-0.10.orig/qemu/Makefile
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-auth-vencrypt.c
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-auth-vencrypt.h
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-tls.c
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-tls.h
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.h
-+++ qemu-kvm-0.10/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/06-vnc-sasl.patch b/06-vnc-sasl.patch
deleted file mode 100644
index f7eafd0..0000000
--- a/06-vnc-sasl.patch
+++ /dev/null
@@ -1,1526 +0,0 @@
-Index: qemu-kvm-0.10/qemu/Makefile
-===================================================================
---- qemu-kvm-0.10.orig/qemu/Makefile
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/Makefile.target
-===================================================================
---- qemu-kvm-0.10.orig/qemu/Makefile.target
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/configure
-===================================================================
---- qemu-kvm-0.10.orig/qemu/configure
-+++ qemu-kvm-0.10/qemu/configure
-@@ -164,6 +164,7 @@ fmod_lib=""
- fmod_inc=""
- oss_lib=""
- vnc_tls="yes"
-+vnc_sasl="yes"
- bsd="no"
- linux="no"
- solaris="no"
-@@ -404,6 +405,8 @@ for opt do
-   ;;
-   --disable-vnc-tls) vnc_tls="no"
-   ;;
-+  --disable-vnc-sasl) vnc_sasl="no"
-+  ;;
-   --disable-slirp) slirp="no"
-   ;;
-   --disable-vde) vde="no"
-@@ -563,6 +566,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"
-@@ -890,6 +894,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
-@@ -1224,6 +1247,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
-@@ -1467,6 +1495,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: qemu-kvm-0.10/qemu/qemu-doc.texi
-===================================================================
---- qemu-kvm-0.10.orig/qemu/qemu-doc.texi
-+++ qemu-kvm-0.10/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
-@@ -2069,7 +2084,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
-@@ -2152,6 +2170,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
- 
-@@ -2263,6 +2316,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: qemu-kvm-0.10/qemu/qemu.sasl
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-auth-sasl.c
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-auth-sasl.h
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-auth-vencrypt.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc-auth-vencrypt.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.h
-+++ qemu-kvm-0.10/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/07-vnc-monitor-authinfo.patch b/07-vnc-monitor-authinfo.patch
deleted file mode 100644
index f691c7e..0000000
--- a/07-vnc-monitor-authinfo.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-Index: qemu-kvm-0.10/qemu/vnc-tls.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc-tls.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-tls.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc-tls.h
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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/08-vnc-acl-mgmt.patch b/08-vnc-acl-mgmt.patch
deleted file mode 100644
index a4ae11d..0000000
--- a/08-vnc-acl-mgmt.patch
+++ /dev/null
@@ -1,709 +0,0 @@
-Index: qemu-kvm-0.10/qemu/Makefile
-===================================================================
---- qemu-kvm-0.10.orig/qemu/Makefile
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/acl.c
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/acl.h
-===================================================================
---- /dev/null
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/configure
-===================================================================
---- qemu-kvm-0.10.orig/qemu/configure
-+++ qemu-kvm-0.10/qemu/configure
-@@ -913,6 +913,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
-@@ -1501,6 +1516,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: qemu-kvm-0.10/qemu/monitor.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/monitor.c
-+++ qemu-kvm-0.10/qemu/monitor.c
-@@ -39,6 +39,7 @@
- #include "qemu-timer.h"
- #include "migration.h"
- #include "kvm.h"
-+#include "acl.h"
- 
- #include "qemu-kvm.h"
- 
-@@ -1498,6 +1499,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,
-@@ -1603,6 +1683,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"
-@@ -1611,6 +1697,7 @@ static const term_cmd_t term_cmds[] = {
-                                         "[snapshot=on|off][,cache=on|off]",
-                                         "add drive to PCI storage controller" },
- #endif
-+
-     { NULL, NULL, },
- };
- 
-@@ -2995,3 +3082,12 @@ int monitor_read_bdrv_key(BlockDriverSta
-     }
-     return -EPERM;
- }
-+
-+
-+/*
-+ * Local variables:
-+ *  c-indent-level: 4
-+ *  c-basic-offset: 4
-+ *  tab-width: 8
-+ * End:
-+ */
-Index: qemu-kvm-0.10/qemu/qemu-doc.texi
-===================================================================
---- qemu-kvm-0.10.orig/qemu/qemu-doc.texi
-+++ qemu-kvm-0.10/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
-@@ -1400,6 +1413,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: qemu-kvm-0.10/qemu/vnc-auth-sasl.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc-auth-sasl.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-auth-sasl.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc-auth-sasl.h
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-tls.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc-tls.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc-tls.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc-tls.h
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.c
-+++ qemu-kvm-0.10/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: qemu-kvm-0.10/qemu/vnc.h
-===================================================================
---- qemu-kvm-0.10.orig/qemu/vnc.h
-+++ qemu-kvm-0.10/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/make-release b/make-release
deleted file mode 100755
index ec4bb42..0000000
--- a/make-release
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash -e
-
-# Based on avi's scripts/make-release from kvm-userspace.git
-
-usage()
-{
-    echo "usage: make-release name kernel-dir kernel-commit user-dir user-commit"
-    exit 1
-}
-
-[ $# -eq 5 ] || usage
-
-name="$1"
-kdir="$2"
-kcommit="$3"
-udir="$4"
-ucommit="$5"
-archs=(x86 ia64)
-
-release_dir=$(mktemp -d)
-
-tarball="$(pwd)/$name.tar.gz"
-
-cd "${release_dir}"
-(cd "$udir";  git archive --format=tar --prefix="$name"/ "$ucommit") | tar x
-cd "$name"
-cat <<EOF > SOURCES
-kernel:    $(cd "$kdir"; git rev-parse "$kcommit")
-userspace: $(cd "$udir"; git rev-parse "$ucommit")
-EOF
-
-paths=(drivers/kvm virt/kvm)
-files=(kvm.h kvm_host.h kvm_para.h kvm_types.h kvm_x86_emulate.h virtext.h svm.h vmx.h)
-for file in "${files[@]}"; do
-    for arch in "${archs[@]}"; do
-	for variant in include/asm-"$arch" arch/"$arch"/include/asm; do
-	    paths+=("$variant"/"$file")
-	done
-    done
-    paths+=(include/linux/"$file")
-done
-for arch in "${archs[@]}"; do
-    paths+=(arch/"$arch"/kvm)
-done
-
-(cd "$kdir"; git archive --format=tar --prefix=linux/ "$kcommit" "${paths[@]}") | tar x
-
-touch kernel/config.kbuild
-echo ARCH=ia64 > config.mak
-make -C kernel sync LINUX=../linux version="$name" >/dev/null
-echo ARCH=x86_64 > config.mak
-make -C kernel sync LINUX=../linux version="$name" >/dev/null
-rm -rf config.mak linux kernel/config.kbuild
-#rm -rf kernel/include/asm kernel/include-compat/asm
-sed -i "s/kvm-devel/$name/" qemu/configure
-
-cd ..
-
-tar czf "$tarball" "$name"
-
-cd $(dirname "$tarball")
-md5sum $(basename "$tarball")
-
-rm -rf "${release_dir}"
diff --git a/qemu-disable-preadv.patch b/qemu-disable-preadv.patch
new file mode 100644
index 0000000..dae289d
--- /dev/null
+++ b/qemu-disable-preadv.patch
@@ -0,0 +1,16 @@
+diff -up qemu-kvm-devel-85/qemu/configure.disable-preadv qemu-kvm-devel-85/qemu/configure
+--- qemu-kvm-devel-85/qemu/configure.disable-preadv	2009-04-27 16:09:05.000000000 +0100
++++ qemu-kvm-devel-85/qemu/configure	2009-04-27 16:09:36.000000000 +0100
+@@ -1189,9 +1189,9 @@ cat > $TMPC <<EOF
+ int main(void) { preadv; }
+ EOF
+ preadv=no
+-if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
+-  preadv=yes
+-fi
++#if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
++#  preadv=yes
++#fi
+ 
+ ##########################################
+ # fdt probe
diff --git a/qemu-fix-arm-framebuffer-build.patch b/qemu-fix-arm-framebuffer-build.patch
new file mode 100644
index 0000000..8a45bd8
--- /dev/null
+++ b/qemu-fix-arm-framebuffer-build.patch
@@ -0,0 +1,45 @@
+From: Mark McLoughlin <markmc@redhat.com>
+Date: Mon, 27 Apr 2009 10:18:14 +0100
+Subject: [PATCH] kvm: qemu: framebuffer: build fix for target-arm
+
+Include qemu-kvm.h for non-KVM_UPSTREAM building and surround the
+kvm code with USE_KVM guards.
+
+Fixes target-arm:
+
+ qemu/hw/framebuffer.c: In function 'framebuffer_update_display':
+ qemu/hw/framebuffer.c:53: warning: implicit declaration of function 'kvm_enabled'
+ qemu/hw/framebuffer.c:54: warning: implicit declaration of function 'kvm_physical_sync_dirty_bitmap'
+
+Signed-off-by: Mark McLoughlin <markmc@redhat.com>
+---
+ qemu/hw/framebuffer.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/qemu/hw/framebuffer.c b/qemu/hw/framebuffer.c
+index 1086ba9..e2d7604 100644
+--- a/qemu/hw/framebuffer.c
++++ b/qemu/hw/framebuffer.c
+@@ -18,6 +18,7 @@
+ #include "console.h"
+ #include "framebuffer.h"
+ #include "kvm.h"
++#include "qemu-kvm.h"
+ 
+ /* Render an image from a shared memory framebuffer.  */
+    
+@@ -50,9 +51,11 @@ void framebuffer_update_display(
+     *first_row = -1;
+     src_len = src_width * rows;
+ 
++#ifdef USE_KVM
+     if (kvm_enabled()) {
+         kvm_physical_sync_dirty_bitmap(base, src_len);
+     }
++#endif
+     pd = cpu_get_physical_page_desc(base);
+     pd2 = cpu_get_physical_page_desc(base + src_len - 1);
+     /* We should reall check that this is a continuous ram region.
+-- 
+1.6.0.6
+
diff --git a/qemu-fix-debuginfo.patch b/qemu-fix-debuginfo.patch
deleted file mode 100644
index f6f1d71..0000000
--- a/qemu-fix-debuginfo.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From: Riku Voipio <riku.voipio@iki.fi>
-Subject: [Qemu-devel] [PATCH] Make binary stripping conditional
-
-Currently qemu unconditionally strips binaries on install. This
-is a problem for packagers who may want to store/ship debug symbols
-of compiled packages for debugging purposes.
-
-Keep stripping as default for the oldtimers and add a
---disable-strip flag to override.
-
-Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
----
- Makefile        |    2 +-
- Makefile.target |    2 +-
- configure       |    9 ++++++++-
- 3 files changed, 10 insertions(+), 3 deletions(-)
-
-Index: qemu-kvm-0.10/qemu/Makefile
-===================================================================
---- qemu-kvm-0.10.orig/qemu/Makefile
-+++ qemu-kvm-0.10/qemu/Makefile
-@@ -256,7 +256,7 @@ endif
- install: all $(if $(BUILD_DOCS),install-doc)
- 	mkdir -p "$(DESTDIR)$(bindir)"
- ifneq ($(TOOLS),)
--	$(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
-+	$(INSTALL) -m 755 $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
- endif
- ifneq ($(BLOBS),)
- 	mkdir -p "$(DESTDIR)$(datadir)"
-Index: qemu-kvm-0.10/qemu/configure
-===================================================================
---- qemu-kvm-0.10.orig/qemu/configure
-+++ qemu-kvm-0.10/qemu/configure
-@@ -154,6 +154,7 @@ case "$cpu" in
- esac
- gprof="no"
- sparse="no"
-+strip_opt="yes"
- bigendian="no"
- mingw32="no"
- EXESUF=""
-@@ -403,6 +404,8 @@ for opt do
-   ;;
-   --disable-sparse) sparse="no"
-   ;;
-+  --disable-strip) strip_opt="no"
-+  ;;
-   --disable-vnc-tls) vnc_tls="no"
-   ;;
-   --disable-vnc-sasl) vnc_sasl="no"
-@@ -556,6 +559,7 @@ echo "  --install=INSTALL        use spe
- echo "  --static                 enable static build [$static]"
- echo "  --enable-sparse          enable sparse checker"
- echo "  --disable-sparse         disable sparse checker (default)"
-+echo "  --disable-strip          disable stripping binaries"
- echo "  --disable-werror         disable compilation abort on warning"
- echo "  --disable-sdl            disable SDL"
- echo "  --enable-cocoa           enable COCOA (Mac OS X only)"
-@@ -1242,6 +1246,7 @@ echo "host big endian   $bigendian"
- echo "target list       $target_list"
- echo "gprof enabled     $gprof"
- echo "sparse enabled    $sparse"
-+echo "strip binaries    $strip_opt"
- echo "profiler          $profiler"
- echo "static build      $static"
- echo "-Werror enabled   $werror"
-@@ -1318,7 +1323,6 @@ echo "INSTALL=$install" >> $config_mak
- echo "CC=$cc" >> $config_mak
- echo "HOST_CC=$host_cc" >> $config_mak
- echo "AR=$ar" >> $config_mak
--echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
- # XXX: only use CFLAGS and LDFLAGS ?  
- # XXX: should export HOST_CFLAGS and HOST_LDFLAGS for cross
- # compilation of dyngen tool (useful for win32 build on Linux host)
-@@ -1405,6 +1409,9 @@ if test "$sparse" = "yes" ; then
-   echo "HOST_CC := REAL_CC=\"\$(HOST_CC)\" cgcc"  >> $config_mak
-   echo "CFLAGS  += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_mak
- fi
-+if test "$strip_opt" = "yes" ; then
-+  echo "STRIP_OPT=-s" >> $config_mak
-+fi
- if test "$bigendian" = "yes" ; then
-   echo "WORDS_BIGENDIAN=yes" >> $config_mak
-   echo "#define WORDS_BIGENDIAN 1" >> $config_h
diff --git a/qemu-fix-display-breakage.patch b/qemu-fix-display-breakage.patch
deleted file mode 100644
index 8645bc2..0000000
--- a/qemu-fix-display-breakage.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 9d1b494a2d5dd2c129994edcf4eb7630bb554964 Mon Sep 17 00:00:00 2001
-From: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
-Date: Tue, 7 Apr 2009 20:55:58 +0000
-Subject: [PATCH 1/1] Fix crash on resolution change -> screen dump -> vga redraw (Avi Kivity)
-
-The vga screen dump function updates last_width and last_height,
-but does not change the DisplaySurface that these variables describe.
-A consequent vga_draw_graphic() will therefore fail to resize the
-surface and crash.
-
-Fix by invalidating the display state after a screen dump, forcing
-vga_draw_graphic() to reallocate the DisplaySurface.
-
-Signed-off-by: Avi Kivity <avi@redhat.com>
-Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-
-
-git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7026 c046a42c-6fe2-441c-8c8c-71466251a162
----
- qemu/hw/vga.c |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
-
-diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c
-index b1e4373..4d1049b 100644
---- a/qemu/hw/vga.c
-+++ b/qemu/hw/vga.c
-@@ -2678,4 +2678,5 @@ static void vga_screen_dump(void *opaque, const char *filename)
-         vga_screen_dump_graphic(s, filename);
-     else
-         vga_screen_dump_text(s, filename);
-+    vga_invalidate_display(s);
- }
--- 
-1.6.0.6
-
diff --git a/qemu-fix-gcc.patch b/qemu-fix-gcc.patch
deleted file mode 100644
index e21a877..0000000
--- a/qemu-fix-gcc.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 2ced1d80f01645885ac2e28107f724886eb1cd5a Mon Sep 17 00:00:00 2001
-From: Jochen Roth <jroth@linux.vnet.ibm.com>
-Date: Thu, 12 Mar 2009 14:19:19 +0100
-Subject: [PATCH] kvm: testsuite: compile fix - avoid raw string literal
-
-This patch fixes compilation problems of kvm-userspace on current gcc
-4.4 compilers which implement the following standard:
-http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
-
-Signed-off-by: Jochen Roth <jroth@linux.vnet.ibm.com>
-Signed-off-by: Avi Kivity <avi@redhat.com>
----
- user/test/x86/apic.c   |   32 ++++++++++++++++----------------
- user/test/x86/vmexit.c |    2 +-
- 2 files changed, 17 insertions(+), 17 deletions(-)
-
-Index: qemu-kvm-0.10/user/test/x86/apic.c
-===================================================================
---- qemu-kvm-0.10.orig/user/test/x86/apic.c
-+++ qemu-kvm-0.10/user/test/x86/apic.c
-@@ -54,14 +54,14 @@ asm (
-     "push %r9  \n\t"
-     "push %r8  \n\t"
- #endif
--    "push %"R"di \n\t"
--    "push %"R"si \n\t"
--    "push %"R"bp \n\t"
--    "push %"R"sp \n\t"
--    "push %"R"bx \n\t"
--    "push %"R"dx \n\t"
--    "push %"R"cx \n\t"
--    "push %"R"ax \n\t"
-+    "push %"R "di \n\t"
-+    "push %"R "si \n\t"
-+    "push %"R "bp \n\t"
-+    "push %"R "sp \n\t"
-+    "push %"R "bx \n\t"
-+    "push %"R "dx \n\t"
-+    "push %"R "cx \n\t"
-+    "push %"R "ax \n\t"
- #ifdef __x86_64__
-     "mov %rsp, %rdi \n\t"
-     "callq *8*16(%rsp) \n\t"
-@@ -70,14 +70,14 @@ asm (
-     "calll *4+4*8(%esp) \n\t"
-     "add $4, %esp \n\t"
- #endif
--    "pop %"R"ax \n\t"
--    "pop %"R"cx \n\t"
--    "pop %"R"dx \n\t"
--    "pop %"R"bx \n\t"
--    "pop %"R"bp \n\t"
--    "pop %"R"bp \n\t"
--    "pop %"R"si \n\t"
--    "pop %"R"di \n\t"
-+    "pop %"R "ax \n\t"
-+    "pop %"R "cx \n\t"
-+    "pop %"R "dx \n\t"
-+    "pop %"R "bx \n\t"
-+    "pop %"R "bp \n\t"
-+    "pop %"R "bp \n\t"
-+    "pop %"R "si \n\t"
-+    "pop %"R "di \n\t"
- #ifdef __x86_64__
-     "pop %r8  \n\t"
-     "pop %r9  \n\t"
-Index: qemu-kvm-0.10/user/test/x86/vmexit.c
-===================================================================
---- qemu-kvm-0.10.orig/user/test/x86/vmexit.c
-+++ qemu-kvm-0.10/user/test/x86/vmexit.c
-@@ -31,7 +31,7 @@ int main()
- 
- 	t1 = rdtsc();
- 	for (i = 0; i < N; ++i)
--		asm volatile ("push %%"R"bx; cpuid; pop %%"R"bx"
-+		asm volatile ("push %%"R "bx; cpuid; pop %%"R "bx"
- 			      : : : "eax", "ecx", "edx");
- 	t2 = rdtsc();
- 	printf("vmexit latency: %d\n", (int)((t2 - t1) / N));
diff --git a/qemu-fix-qcow2-2TB.patch b/qemu-fix-qcow2-2TB.patch
deleted file mode 100644
index 4fee796..0000000
--- a/qemu-fix-qcow2-2TB.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 2d2431f03fc78b532f3a1c5f858cf78859d50fc3 Mon Sep 17 00:00:00 2001
-From: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
-Date: Sun, 5 Apr 2009 17:40:58 +0000
-Subject: [PATCH] qcow2: fix image creation for large, > ~2TB, images (Chris Wright)
-
-When creating large disk images w/ qcow2 format, qcow2_create is hard
-coded to creating a single refcount block.  This is insufficient for
-large images, and will cause qemu-img to segfault as it walks off the
-end of the refcount block.  Keep track of the space needed during image
-create and create proper number of refcount blocks accordingly.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=491943
-
-Signed-off-by: Chris Wright <chrisw@redhat.com>
-Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-
-
-git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6982 c046a42c-6fe2-441c-8c8c-71466251a162
----
- block-qcow2.c |   20 +++++++++++++-------
- 1 files changed, 13 insertions(+), 7 deletions(-)
-
-Index: qemu-kvm-0.10/qemu/block-qcow2.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/block-qcow2.c
-+++ qemu-kvm-0.10/qemu/block-qcow2.c
-@@ -1458,6 +1458,7 @@ static int qcow_create(const char *filen
-                       const char *backing_file, int flags)
- {
-     int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
-+    int ref_clusters = 0;
-     QCowHeader header;
-     uint64_t tmp, offset;
-     QCowCreateState s1, *s = &s1;
-@@ -1498,22 +1499,28 @@ static int qcow_create(const char *filen
-     offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
- 
-     s->refcount_table = qemu_mallocz(s->cluster_size);
--    s->refcount_block = qemu_mallocz(s->cluster_size);
- 
-     s->refcount_table_offset = offset;
-     header.refcount_table_offset = cpu_to_be64(offset);
-     header.refcount_table_clusters = cpu_to_be32(1);
-     offset += s->cluster_size;
--
--    s->refcount_table[0] = cpu_to_be64(offset);
-     s->refcount_block_offset = offset;
--    offset += s->cluster_size;
-+
-+    /* count how many refcount blocks needed */
-+    tmp = offset >> s->cluster_bits;
-+    ref_clusters = (tmp >> (s->cluster_bits - REFCOUNT_SHIFT)) + 1;
-+    for (i=0; i < ref_clusters; i++) {
-+        s->refcount_table[i] = cpu_to_be64(offset);
-+        offset += s->cluster_size;
-+    }
-+
-+    s->refcount_block = qemu_mallocz(ref_clusters * s->cluster_size);
- 
-     /* update refcounts */
-     create_refcount_update(s, 0, header_size);
-     create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));
-     create_refcount_update(s, s->refcount_table_offset, s->cluster_size);
--    create_refcount_update(s, s->refcount_block_offset, s->cluster_size);
-+    create_refcount_update(s, s->refcount_block_offset, ref_clusters * s->cluster_size);
- 
-     /* write all the data */
-     write(fd, &header, sizeof(header));
-@@ -1529,7 +1536,7 @@ static int qcow_create(const char *filen
-     write(fd, s->refcount_table, s->cluster_size);
- 
-     lseek(fd, s->refcount_block_offset, SEEK_SET);
--    write(fd, s->refcount_block, s->cluster_size);
-+    write(fd, s->refcount_block, ref_clusters * s->cluster_size);
- 
-     qemu_free(s->refcount_table);
-     qemu_free(s->refcount_block);
diff --git a/qemu-fix-qcow2-corruption.patch b/qemu-fix-qcow2-corruption.patch
index dfed7be..53ac9ec 100644
--- a/qemu-fix-qcow2-corruption.patch
+++ b/qemu-fix-qcow2-corruption.patch
@@ -1,26 +1,3 @@
-From: Nolan Leake <nolan <at> sigbus.net>
-Subject: [PATCH] Fix (at least one cause of) qcow2 corruption.
-
-qcow2's get_cluster_offset() scans forward in the l2 table to find other
-clusters that have the same allocation status as the first cluster.
-This is used by (among others) qcow_is_allocated().
-
-Unfortunately, it was not checking to be sure that it didn't fall off
-the end of the l2 table.  This patch adds that check.
-
-The symptom that motivated me to look into this was that
-bdrv_is_allocated() was returning false when there was in fact data
-there.  This is one of many ways this bug could lead to data corruption.
-
-I checked the other place that scans for consecutive unallocated blocks
-(alloc_cluster_offset()) and it appears to be OK:
-    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
-appears to prevent the same problem from occurring.
-
-Signed-off-by: Nolan Leake <nolan <at> sigbus.net>
-
----
-
 From: Kevin Wolf <kwolf@redhat.com>
 Subject: [PATCH] qcow2 corruption: Fix alloc_cluster_link_l2
 
@@ -41,22 +18,10 @@ qcow2 image (the header is gone after three loop iterations):
 
 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
 
-diff -up qemu-kvm-0.10/qemu/block-qcow2.c.qcow2-corruption qemu-kvm-0.10/qemu/block-qcow2.c
-diff -up qemu-kvm-0.10/qemu/block-qcow2.c.qcow2-corruption qemu-kvm-0.10/qemu/block-qcow2.c
---- qemu-kvm-0.10/qemu/block-qcow2.c.qcow2-corruption	2009-04-21 09:57:21.000000000 +0100
-+++ qemu-kvm-0.10/qemu/block-qcow2.c	2009-04-21 09:58:27.000000000 +0100
-@@ -670,6 +670,10 @@ static uint64_t get_cluster_offset(Block
- 
-     nb_available = (nb_available >> 9) + index_in_cluster;
- 
-+    if (nb_needed > nb_available) {
-+        nb_needed = nb_available;
-+    }
-+
-     cluster_offset = 0;
- 
-     /* seek the the l2 offset in the l1 table */
-@@ -912,7 +916,7 @@ static int alloc_cluster_link_l2(BlockDr
+diff -up qemu-kvm-devel-85/qemu/block-qcow2.c.qcow2-corruption qemu-kvm-devel-85/qemu/block-qcow2.c
+--- qemu-kvm-devel-85/qemu/block-qcow2.c.qcow2-corruption	2009-04-21 10:57:31.000000000 +0100
++++ qemu-kvm-devel-85/qemu/block-qcow2.c	2009-04-24 19:29:44.000000000 +0100
+@@ -1007,7 +1007,7 @@ static int alloc_cluster_link_l2(BlockDr
          goto err;
  
      for (i = 0; i < j; i++)
diff --git a/qemu-roms-more-room.patch b/qemu-roms-more-room.patch
deleted file mode 100644
index 9437e8d..0000000
--- a/qemu-roms-more-room.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From 34b39c2ba6cc08239a707b52bfb2886df2aa8dec Mon Sep 17 00:00:00 2001
-From: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
-Date: Sat, 28 Mar 2009 17:28:45 +0000
-Subject: [PATCH] get roms more room. (Glauber Costa)
-
-This patch increases by 50 % the size available for option roms.
-The main motivator is that some roms grew bigger than the 64k we
-currently allocate for them (Hey, it's 2009!)
-
-One example is the gpxe project, that produces some roms with 69k,
-70k, etc. The space proposed by this patch actually makes it as
-big as 84k. Probably still a fit for some time.
-
-But there is no free lunch. This space must come from somewhere,
-and we take it from vga rom space. Currently, our vga roms are
-around 35k in size. With this patch, option rom space will begin
-just after vga ends, aligned to the next 2k boundary.
-
-Technicaly, we could do the same with the uper space (the bios itself),
-but since bochs bios is already 128 k in size, I don't see an
-urgent need to do it.
-
-[ fix case for vgabioses smaller than 30k, by Carl-Daniel Hailfinger ]
-
-Signed-off-by: Glauber Costa <glommer@redhat.com>
-Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-
-
-git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6896 c046a42c-6fe2-441c-8c8c-71466251a162
----
- hw/pc.c |   29 +++++++++++++++++++----------
- 1 files changed, 19 insertions(+), 10 deletions(-)
-
-Index: qemu-kvm-0.10/qemu/hw/pc.c
-===================================================================
---- qemu-kvm-0.10.orig/qemu/hw/pc.c
-+++ qemu-kvm-0.10/qemu/hw/pc.c
-@@ -813,7 +813,7 @@ static void pc_init1(ram_addr_t ram_size
- {
-     char buf[1024];
-     int ret, linux_boot, i;
--    ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset;
-+    ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset, option_rom_start = 0;
-     ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
-     int bios_size, isa_bios_size, vga_bios_size;
-     int pci_option_rom_offset;
-@@ -825,6 +825,7 @@ static void pc_init1(ram_addr_t ram_size
-     int index;
-     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-     BlockDriverState *fd[MAX_FD];
-+    int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
- 
-     if (ram_size >= 0xe0000000 ) {
-         above_4g_mem_size = ram_size - 0xe0000000;
-@@ -900,7 +901,7 @@ static void pc_init1(ram_addr_t ram_size
-         exit(1);
-     }
- 
--    if (cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled) {
-+    if (using_vga) {
-         /* VGA BIOS load */
-         if (cirrus_vga_enabled) {
-             snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
-@@ -918,12 +919,21 @@ vga_bios_error:
-             fprintf(stderr, "qemu: could not load VGA BIOS '%s'\n", buf);
-             exit(1);
-         }
-+	/* Round up vga bios size to the next 2k boundary */
-+	vga_bios_size = (vga_bios_size + 2047) & ~2047;
-+	option_rom_start = 0xc0000 + vga_bios_size;
- 
-         /* setup basic memory access */
--        cpu_register_physical_memory(0xc0000, 0x10000,
-+        cpu_register_physical_memory(0xc0000, vga_bios_size,
-                                      vga_bios_offset | IO_MEM_ROM);
-     }
- 
-+    /* No point in placing option roms before this address, since bochs bios
-+     * will only start looking for it at 0xc8000 */
-+    if (option_rom_start < 0xc8000)
-+	    option_rom_start = 0xc8000;
-+
-+
-     /* map the last 128KB of the BIOS in ISA space */
-     isa_bios_size = bios_size;
-     if (isa_bios_size > (128 * 1024))
-@@ -944,14 +954,14 @@ vga_bios_error:
-         ram_addr_t option_rom_offset;
-         int size, offset;
- 
--        offset = 0;
-+        offset = option_rom_start;
-         if (linux_boot) {
-             option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE);
-             load_linux(phys_ram_base + option_rom_offset,
-                        kernel_filename, initrd_filename, kernel_cmdline);
--            cpu_register_physical_memory(0xd0000, TARGET_PAGE_SIZE,
-+            cpu_register_physical_memory(option_rom_start, TARGET_PAGE_SIZE,
-                                          option_rom_offset | IO_MEM_ROM);
--            offset = TARGET_PAGE_SIZE;
-+            offset += TARGET_PAGE_SIZE;
-         }
- 
-         for (i = 0; i < nb_option_roms; i++) {
-@@ -961,13 +971,13 @@ vga_bios_error:
-                         option_rom[i]);
-                 exit(1);
-             }
--            if (size > (0x10000 - offset))
-+            if (size > (0xe0000 - offset))
-                 goto option_rom_error;
-             option_rom_offset = qemu_ram_alloc(size);
-             ret = load_image(option_rom[i], phys_ram_base + option_rom_offset);
-             if (ret != size) {
-             option_rom_error:
--                fprintf(stderr, "Too many option ROMS\n");
-+                fprintf(stderr, "Could not fit %soption roms in available space\n", using_vga ? "VGA bios and " : "");
-                 exit(1);
-             }
-             size = (size + 4095) & ~4095;
-@@ -975,9 +985,8 @@ vga_bios_error:
-        initialization, and (optionally) marked readonly by the BIOS
-        before INT 19h.  See the PNPBIOS specification, appendix B.
-        DDIM support is mandatory for proper PCI expansion ROM support. */
--            cpu_register_physical_memory(0xd0000 + offset,
--                                         size, option_rom_offset /* | IO_MEM_ROM */);
--            option_rom_setup_reset(0xd0000 + offset, size);
-+            cpu_register_physical_memory(offset, size, option_rom_offset /* | IO_MEM_ROM */);
-+            option_rom_setup_reset(offset, size);
-             offset += size;
-         }
-         pci_option_rom_offset = offset;
diff --git a/qemu-virtio-blk-boot-on.patch b/qemu-virtio-blk-boot-on.patch
new file mode 100644
index 0000000..4d2ba6a
--- /dev/null
+++ b/qemu-virtio-blk-boot-on.patch
@@ -0,0 +1,32 @@
+From: Pauline Middelink <middelink@polyware.nl>
+To: kvm@vger.kernel.org
+Subject: kvm-85 won't boot guests with virtio block device
+
+Hi,
+
+To follow up on the issues with kvm-85 and libvirt I discovered the following
+issue: libvirt detects from the help of qemu which options it can give to
+qemu. (in this case obviously /usr/kvm/bin/qemu-system-x86_64 -help)
+
+If you look carefully to the output of the -help of qemu from kvm-84 and
+kvm-85, you will notice the boot flag to the -drive option has disappeared!
+Hence letting libvirt believe it isnt allowed to use it, hence the unable
+to boot error.
+
+A small patch which fixes the problem for me, is attached.
+
+    Met vriendelijke groet,
+        Pauline Middelink
+
+diff -ur kvm-85/qemu/qemu-options.hx kvm-85a/qemu/qemu-options.hx
+--- kvm-85/qemu/qemu-options.hx 2009-04-21 11:57:31.000000000 +0200
++++ kvm-85a/qemu/qemu-options.hx        2009-04-24 19:04:50.000000000 +0200
+@@ -77,6 +77,7 @@
+     "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
+     "       [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
+     "       [,cache=writethrough|writeback|none][,format=f][,serial=s]\n"
++    "       [,boot=on|off]\n"
+     "                use 'file' as a drive image\n")
+ STEXI
+ @item -drive @var{option}[,@var{option}[,@var{option}[,...]]]
+
diff --git a/qemu.spec b/qemu.spec
index 254143c..4790d19 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -1,42 +1,41 @@
+%define kvmvernum  85
+%define kvmvertag  kvm%{kvmvernum}
+%define kvmverfull kvm-devel-%{kvmvernum}
+
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
-Version: 0.10
-Release: 15%{?dist}
-# I have mistakenly thought the revision name would be 1.0.
-# So 0.10 series get Epoch = 1
+Version: 0.10.50
+Release: 1.%{kvmvertag}%{?dist}
+# Epoch because we pushed a qemu-1.0 package
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
 Group: Development/Tools
 URL: http://www.qemu.org/
 
-# To re-create the tarball below:
-#   $> git clone git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm.git
-#   $> git clone git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm-userspace.git
-#   $> make-release qemu-kvm-%{version}.tar.gz $(pwd)/kvm v2.6.29-6998-g1d0cdf1 \
-#                                              $(pwd)/kvm-userspace kvm-84-196-ga01bd3f
-Source0: qemu-kvm-%{version}.tar.gz
-Source1: make-release
-Source2: qemu.init
-Source3: kvm.modules
-
-Patch1: 01-tls-handshake-fix.patch
-Patch2: 02-vnc-monitor-info.patch
-Patch3: 03-display-keymaps.patch
-Patch4: 04-vnc-struct.patch
-Patch5: 05-vnc-tls-vencrypt.patch
-Patch6: 06-vnc-sasl.patch
-Patch7: 07-vnc-monitor-authinfo.patch
-Patch8: 08-vnc-acl-mgmt.patch
-
-Patch9: kvm-upstream-ppc.patch
-Patch10: qemu-fix-debuginfo.patch
-Patch11: qemu-fix-gcc.patch
-Patch12: qemu-roms-more-room.patch
-Patch13: qemu-roms-more-room-fix-vga-align.patch
-Patch14: qemu-bios-bigger-roms.patch
-Patch15: qemu-fix-display-breakage.patch
-Patch16: qemu-fix-qcow2-2TB.patch
-Patch17: qemu-fix-qcow2-corruption.patch
+Source0: http://download.sourceforge.net/sourceforge/kvm/qemu-%{kvmverfull}.tar.gz
+Source1: qemu.init
+Source2: kvm.modules
+
+# Hack until merge happens upstream
+Patch01: kvm-upstream-ppc.patch
+
+# Not upstream, why?
+Patch02: qemu-bios-bigger-roms.patch
+
+# Fixed upstream by f753ff1638
+Patch03: qemu-roms-more-room-fix-vga-align.patch
+
+# Fixed upstream by 641636d19e
+Patch04: qemu-fix-qcow2-corruption.patch
+
+# Seen on kvm list
+Patch05: qemu-virtio-blk-boot-on.patch
+
+# kvm-85 build fix, submitted upstream
+Patch06: qemu-fix-arm-framebuffer-build.patch
+
+# Disable preadv()/pwritev() until bug #497429 is fixed
+Patch07: qemu-disable-preadv.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
@@ -206,25 +205,20 @@ such as kvmtrace and kvm_stat.
 %endif
 
 %prep
-%setup -q -n qemu-kvm-%{version}
-
-%patch1 -p1
-%patch2 -p1
-%patch3 -p1
-%patch4 -p1
-%patch5 -p1
-%patch6 -p1
-%patch7 -p1
-%patch8 -p1
-%patch9 -p1
-%patch10 -p1
-%patch11 -p1
-%patch12 -p1
-%patch13 -p1
-%patch14 -p1
-%patch15 -p1
-%patch16 -p1
-%patch17 -p1
+%setup -q -n qemu-%{kvmverfull}
+
+#
+# Hack - kvm-85 missing kernel/include/asm symlink
+#
+(cd kernel/include && ln -s asm-x86 asm)
+
+%patch01 -p1 -b .kvm-upstream-ppc
+%patch02 -p1 -b .bios-bigger-roms
+%patch03 -p1 -b .roms-more-room-fix-vga-align
+%patch04 -p1 -b .fix-qcow2-corruption
+%patch05 -p1 -b .virtio-blk-boot-on
+%patch06 -p1 -b .framebuffer-build-fix
+%patch07 -p1 -b .disable-preadv
 
 %build
 # systems like rhel build system does not have a recent enough linker so
@@ -262,7 +256,6 @@ cp user/kvmtrace_format  .
 make clean
 %endif
 
-echo "%{name}-%{version}" > $(pwd)/kernel/.kernelrelease
 cd qemu
 ./configure \
     --target-list="i386-softmmu x86_64-softmmu arm-softmmu cris-softmmu m68k-softmmu \
@@ -282,8 +275,7 @@ cd qemu
     --audio-drv-list=pa,sdl,alsa,oss \
     --extra-cflags="$RPM_OPT_FLAGS"
 
-
-make %{?_smp_mflags} $buildldflags
+make V=1 %{?_smp_mflags} $buildldflags
 
 %install
 rm -rf $RPM_BUILD_ROOT
@@ -292,7 +284,7 @@ rm -rf $RPM_BUILD_ROOT
 mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/modules
 mkdir -p $RPM_BUILD_ROOT%{_bindir}/
 
-install -m 0755 %{SOURCE3} $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/modules/kvm.modules
+install -m 0755 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/modules/kvm.modules
 install -m 0755 kvmtrace $RPM_BUILD_ROOT%{_bindir}/
 install -m 0755 kvmtrace_format $RPM_BUILD_ROOT%{_bindir}/
 install -m 0755 kvm_stat $RPM_BUILD_ROOT%{_bindir}/
@@ -308,7 +300,7 @@ make prefix="${RPM_BUILD_ROOT}%{_prefix}" \
      docdir="${RPM_BUILD_ROOT}%{_docdir}/%{name}-%{version}" \
      datadir="${RPM_BUILD_ROOT}%{_prefix}/share/qemu" install
 chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/*
-install -D -p -m 0755 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/qemu
+install -D -p -m 0755 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/qemu
 install -D -p -m 0644 -t ${RPM_BUILD_ROOT}/%{qemudocdir} Changelog README TODO COPYING COPYING.LIB LICENSE
 
 install -D -p -m 0644 qemu.sasl $RPM_BUILD_ROOT%{_sysconfdir}/sasl2/qemu.conf
@@ -339,8 +331,6 @@ ln -s ../openbios/openbios-ppc %{buildroot}/%{_prefix}/share/qemu/openbios-ppc
 ln -s ../openbios/openbios-sparc32 %{buildroot}/%{_prefix}/share/qemu/openbios-sparc32
 ln -s ../openbios/openbios-sparc64 %{buildroot}/%{_prefix}/share/qemu/openbios-sparc64
 
-
-
 %clean
 rm -rf $RPM_BUILD_ROOT
 
@@ -463,9 +453,22 @@ fi
 %files img
 %defattr(-,root,root)
 %{_bindir}/qemu-img
+%{_bindir}/qemu-io
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Mon Apr 27 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-1.kvm85
+- Update to qemu-kvm-devel-85
+- kvm-85 is based on qemu development branch, currently version 0.10.50
+- Include new qemu-io utility in qemu-img package
+- Re-instate -help string for boot=on to fix virtio booting with libvirt
+- Drop upstreamed patches
+- Fix missing kernel/include/asm symlink in upstream tarball
+- Fix target-arm build
+- Disable preadv()/pwritev() until bug #497429 is fixed
+- Kill more .kernelrelease uselessness
+- Make non-kvm qemu build verbose
+
 * Fri Apr 24 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-15
 - Fix source numbering typos caused by make-release addition
 
diff --git a/sources b/sources
index 004ec2d..14a7621 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-04c32fb43c722f180654f53e04ad17dd  qemu-kvm-0.10.tar.gz
+3b671f64b66e7e6e571516193c184653  qemu-kvm-devel-85.tar.gz