From f4391268397bcb41cc7045130130cb4e1e716c92 Mon Sep 17 00:00:00 2001 From: Daniel P. Berrange Date: Oct 11 2007 00:47:59 +0000 Subject: Fix QEMU locating x509 certs. Add VNC tls/x509 config to XenD --- diff --git a/xen-qemu-vnc-authentication.patch b/xen-qemu-vnc-authentication.patch index 084895d..fc5c599 100644 --- a/xen-qemu-vnc-authentication.patch +++ b/xen-qemu-vnc-authentication.patch @@ -1,6 +1,6 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/configure xen-3.1.0-src.new/tools/ioemu/configure ---- xen-3.1.0-src.orig/tools/ioemu/configure 2007-05-18 10:45:21.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/configure 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/configure 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/configure 2007-10-10 17:31:52.000000000 -0400 @@ -85,6 +85,7 @@ alsa="no" fmod="no" fmod_lib="" @@ -71,7 +71,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/configure xen-3.1.0-src.new/tools/ioem rm -f $TMPO $TMPC $TMPE $TMPS diff -rupN xen-3.1.0-src.orig/tools/ioemu/d3des.c xen-3.1.0-src.new/tools/ioemu/d3des.c --- xen-3.1.0-src.orig/tools/ioemu/d3des.c 1969-12-31 19:00:00.000000000 -0500 -+++ xen-3.1.0-src.new/tools/ioemu/d3des.c 2007-08-28 17:10:41.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/d3des.c 2007-10-10 17:31:52.000000000 -0400 @@ -0,0 +1,434 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and @@ -509,7 +509,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/d3des.c xen-3.1.0-src.new/tools/ioemu/ + **********************************************************************/ diff -rupN xen-3.1.0-src.orig/tools/ioemu/d3des.h xen-3.1.0-src.new/tools/ioemu/d3des.h --- xen-3.1.0-src.orig/tools/ioemu/d3des.h 1969-12-31 19:00:00.000000000 -0500 -+++ xen-3.1.0-src.new/tools/ioemu/d3des.h 2007-08-28 17:10:41.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/d3des.h 2007-10-10 17:31:52.000000000 -0400 @@ -0,0 +1,51 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and @@ -563,8 +563,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/d3des.h xen-3.1.0-src.new/tools/ioemu/ +/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery + ********************************************************************/ diff -rupN xen-3.1.0-src.orig/tools/ioemu/Makefile.target xen-3.1.0-src.new/tools/ioemu/Makefile.target ---- xen-3.1.0-src.orig/tools/ioemu/Makefile.target 2007-08-28 17:02:25.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/Makefile.target 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/Makefile.target 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/Makefile.target 2007-10-10 17:31:52.000000000 -0400 @@ -347,6 +347,11 @@ SOUND_HW += fmopl.o adlib.o endif AUDIODRV+= wavcapture.o @@ -596,8 +596,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/Makefile.target xen-3.1.0-src.new/tool sdlaudio.o: sdlaudio.c diff -rupN xen-3.1.0-src.orig/tools/ioemu/monitor.c xen-3.1.0-src.new/tools/ioemu/monitor.c ---- xen-3.1.0-src.orig/tools/ioemu/monitor.c 2007-05-18 10:45:21.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/monitor.c 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/monitor.c 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/monitor.c 2007-10-10 17:31:52.000000000 -0400 @@ -343,7 +343,7 @@ void do_eject(int force, const char *fil eject_device(bs, force); } @@ -639,8 +639,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/monitor.c xen-3.1.0-src.new/tools/ioem { vga_hw_screen_dump(filename); diff -rupN xen-3.1.0-src.orig/tools/ioemu/qemu_socket.h xen-3.1.0-src.new/tools/ioemu/qemu_socket.h ---- xen-3.1.0-src.orig/tools/ioemu/qemu_socket.h 2007-05-18 10:45:21.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/qemu_socket.h 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/qemu_socket.h 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/qemu_socket.h 2007-10-10 17:31:52.000000000 -0400 @@ -19,6 +19,7 @@ #include #include @@ -650,8 +650,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/qemu_socket.h xen-3.1.0-src.new/tools/ #define socket_error() errno #define closesocket(s) close(s) diff -rupN xen-3.1.0-src.orig/tools/ioemu/vl.c xen-3.1.0-src.new/tools/ioemu/vl.c ---- xen-3.1.0-src.orig/tools/ioemu/vl.c 2007-08-28 17:02:25.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/vl.c 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/vl.c 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/vl.c 2007-10-10 17:31:52.000000000 -0400 @@ -122,7 +122,6 @@ static DisplayState display_state; int nographic; int vncviewer; @@ -754,8 +754,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vl.c xen-3.1.0-src.new/tools/ioemu/vl. qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock)); } diff -rupN xen-3.1.0-src.orig/tools/ioemu/vl.h xen-3.1.0-src.new/tools/ioemu/vl.h ---- xen-3.1.0-src.orig/tools/ioemu/vl.h 2007-08-28 17:02:25.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/vl.h 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/vl.h 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/vl.h 2007-10-10 17:31:52.000000000 -0400 @@ -813,7 +813,10 @@ void sdl_display_init(DisplayState *ds, void cocoa_display_init(DisplayState *ds, int full_screen); @@ -769,8 +769,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vl.h xen-3.1.0-src.new/tools/ioemu/vl. /* ide.c */ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vnc.c ---- xen-3.1.0-src.orig/tools/ioemu/vnc.c 2007-08-28 17:02:25.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/vnc.c 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/vnc.c 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/vnc.c 2007-10-10 20:24:32.000000000 -0400 @@ -44,6 +44,28 @@ #include "vnc_keysym.h" @@ -846,7 +846,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn struct VncState { QEMUTimer *timer; -@@ -93,6 +154,24 @@ struct VncState +@@ -93,6 +154,29 @@ struct VncState int depth; /* internal VNC frame buffer byte per pixel */ int has_resize; int has_hextile; @@ -860,6 +860,11 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn +#if CONFIG_VNC_TLS + int subauth; + int x509verify; ++ ++ char *x509cacert; ++ char *x509cacrl; ++ char *x509cert; ++ char *x509key; +#endif + char challenge[VNC_AUTH_CHALLENGE_SIZE]; + @@ -871,7 +876,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn Buffer output; Buffer input; kbd_layout_t *kbd_layout; -@@ -117,6 +196,8 @@ struct VncState +@@ -117,6 +201,8 @@ struct VncState int numlock; }; @@ -880,7 +885,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn #define DIRTY_PIXEL_BITS 64 #define X2DP_DOWN(vs, x) ((x) >> (vs)->dirty_pixel_shift) #define X2DP_UP(vs, x) \ -@@ -672,11 +753,19 @@ static int vnc_client_io_error(VncState +@@ -672,11 +758,19 @@ static int vnc_client_io_error(VncState if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN)) return 0; @@ -900,7 +905,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn return 0; } return ret; -@@ -692,7 +781,19 @@ static void vnc_client_write(void *opaqu +@@ -692,7 +786,19 @@ static void vnc_client_write(void *opaqu long ret; VncState *vs = opaque; @@ -921,7 +926,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn ret = vnc_client_io_error(vs, ret, socket_error()); if (!ret) return; -@@ -718,7 +819,19 @@ static void vnc_client_read(void *opaque +@@ -718,7 +824,19 @@ static void vnc_client_read(void *opaque buffer_reserve(&vs->input, 4096); @@ -942,7 +947,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn ret = vnc_client_io_error(vs, ret, socket_error()); if (!ret) return; -@@ -815,6 +928,41 @@ static uint32_t read_u32(uint8_t *data, +@@ -815,6 +933,41 @@ static uint32_t read_u32(uint8_t *data, (data[offset + 2] << 8) | data[offset + 3]); } @@ -984,7 +989,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn static void client_cut_text(VncState *vs, size_t len, char *text) { } -@@ -1257,23 +1405,575 @@ static int protocol_client_init(VncState +@@ -1257,23 +1410,587 @@ static int protocol_client_init(VncState } @@ -1107,37 +1112,49 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn +} + + -+static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(void) ++static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs) +{ + gnutls_certificate_credentials_t x509_cred; + int ret; -+ struct stat st; ++ ++ if (!vs->x509cacert) { ++ VNC_DEBUG("No CA x509 certificate specified\n"); ++ return NULL; ++ } ++ if (!vs->x509cert) { ++ VNC_DEBUG("No server x509 certificate specified\n"); ++ return NULL; ++ } ++ if (!vs->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, X509_CA_CERT_FILE, GNUTLS_X509_FMT_PEM)) < 0) { ++ if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred, ++ vs->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, X509_SERVER_CERT_FILE, -+ X509_SERVER_KEY_FILE, ++ if ((ret = gnutls_certificate_set_x509_key_file (x509_cred, ++ vs->x509cert, ++ vs->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 (stat(X509_CA_CRL_FILE, &st) < 0) { -+ if (errno != ENOENT) { -+ gnutls_certificate_free_credentials(x509_cred); -+ return NULL; -+ } -+ } else { -+ if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred, X509_CA_CRL_FILE, GNUTLS_X509_FMT_PEM)) < 0) { ++ if (vs->x509cacrl) { ++ if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred, ++ vs->x509cacrl, ++ GNUTLS_X509_FMT_PEM)) < 0) { + VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret)); + gnutls_certificate_free_credentials(x509_cred); + return NULL; @@ -1353,7 +1370,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn + } + + if (NEED_X509_AUTH(vs)) { -+ gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(); ++ gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs); + if (!x509_cred) { + gnutls_deinit(vs->tls_session); + vs->tls_session = NULL; @@ -1568,7 +1585,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn return 0; } -@@ -1286,9 +1986,10 @@ static void vnc_listen_read(void *opaque +@@ -1286,9 +2003,10 @@ static void vnc_listen_read(void *opaque vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen); if (vs->csock != -1) { @@ -1580,7 +1597,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn vnc_flush(vs); vnc_read_when(vs, protocol_version, 12); framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height); -@@ -1299,9 +2000,8 @@ static void vnc_listen_read(void *opaque +@@ -1299,9 +2017,8 @@ static void vnc_listen_read(void *opaque } } @@ -1591,7 +1608,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn VncState *vs; vs = qemu_mallocz(sizeof(VncState)); -@@ -1309,11 +2009,13 @@ int vnc_display_init(DisplayState *ds, i +@@ -1309,11 +2026,13 @@ int vnc_display_init(DisplayState *ds, i exit(1); ds->opaque = vs; @@ -1606,7 +1623,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn vs->ds = ds; -@@ -1324,51 +2026,230 @@ int vnc_display_init(DisplayState *ds, i +@@ -1324,51 +2043,312 @@ int vnc_display_init(DisplayState *ds, i if (!vs->kbd_layout) exit(1); @@ -1624,6 +1641,76 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn + memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); +} + ++#if CONFIG_VNC_TLS ++static int vnc_set_x509_credential(VncState *vs, ++ const char *certdir, ++ const char *filename, ++ char **cred, ++ int ignoreMissing) ++{ ++ struct stat sb; ++ ++ if (*cred) { ++ qemu_free(*cred); ++ *cred = NULL; + } + +- reuse_addr = 1; +- ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, +- (const char *)&reuse_addr, sizeof(reuse_addr)); +- if (ret == -1) { +- fprintf(stderr, "setsockopt() failed\n"); +- exit(1); ++ if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2))) ++ return -1; ++ ++ 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; + } + +- retry: +- addr->sin_family = AF_INET; +- addr->sin_port = htons(5900 + display); ++ return 0; ++} + +- if (bind(vs->lsock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) == -1) { +- if (find_unused && errno == EADDRINUSE) { +- display++; +- goto retry; ++static int vnc_set_x509_credential_dir(VncState *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) +{ + VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; @@ -1647,7 +1734,9 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn + if (vs->tls_session) { + gnutls_deinit(vs->tls_session); + vs->tls_session = NULL; -+ } + } +- fprintf(stderr, "bind() failed\n"); +- exit(1); + vs->wiremode = VNC_WIREMODE_CLEAR; +#endif /* CONFIG_VNC_TLS */ } @@ -1658,11 +1747,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn +#endif +} -- reuse_addr = 1; -- ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, -- (const char *)&reuse_addr, sizeof(reuse_addr)); -- if (ret == -1) { -- fprintf(stderr, "setsockopt() failed\n"); +- if (listen(vs->lsock, 1) == -1) { +- fprintf(stderr, "listen() failed\n"); - exit(1); +int parse_host_port(struct sockaddr_in *saddr, const char *str); + @@ -1681,16 +1767,17 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn + return -1; } -- retry: -- addr->sin_family = AF_INET; -- addr->sin_port = htons(5900 + display); +- ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, +- NULL, vs); +- if (ret == -1) +- exit(1); + return 0; +} -- if (bind(vs->lsock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) == -1) { -- if (find_unused && errno == EADDRINUSE) { -- display++; -- goto retry; +- vs->ds->data = NULL; +- vs->ds->dpy_update = vnc_dpy_update; +- vs->ds->dpy_resize = vnc_dpy_resize; +- vs->ds->dpy_refresh = vnc_dpy_refresh; +int vnc_display_open(DisplayState *ds, const char *display, int find_unused) +{ + struct sockaddr *addr; @@ -1707,7 +1794,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn +#if CONFIG_VNC_TLS + int tls = 0, x509 = 0; +#endif -+ + +- vnc_dpy_resize(vs->ds, 640, 400); + vnc_display_close(ds); + if (strcmp(display, "none") == 0) + return 0; @@ -1723,20 +1811,40 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn +#if CONFIG_VNC_TLS + } else if (strncmp(options, "tls", 3) == 0) { + tls = 1; /* Require TLS */ -+ } else if (strncmp(options, "x509verify", 10) == 0) { -+ x509 = 1; /* Require x509 certificates... */ -+ vs->x509verify = 1;/* ...and verify client certs */ + } else if (strncmp(options, "x509", 4) == 0) { ++ char *start, *end; + x509 = 1; /* Require x509 certificates */ ++ if (strncmp(options, "x509verify", 10) == 0) ++ vs->x509verify = 1; /* ...and verify client certs */ ++ ++ /* Now check for 'x509=/some/path' postfix ++ * and use that to setup x509 certificate/key paths */ ++ start = strchr(options, '='); ++ end = strchr(options, ','); ++ if (start && (!end || (start < end))) { ++ int len = end ? end-(start+1) : strlen(start+1); ++ char *path = qemu_malloc(len+1); ++ strncpy(path, start+1, len); ++ path[len] = '\0'; ++ VNC_DEBUG("Trying certificate path '%s'\n", path); ++ if (vnc_set_x509_credential_dir(vs, path) < 0) { ++ fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path); ++ qemu_free(path); ++ qemu_free(vs->display); ++ vs->display = NULL; ++ return -1; ++ } ++ qemu_free(path); ++ } else { ++ fprintf(stderr, "No certificate path provided\n"); ++ qemu_free(vs->display); ++ vs->display = NULL; ++ return -1; ++ } +#endif - } -- fprintf(stderr, "bind() failed\n"); -- exit(1); - } - -- if (listen(vs->lsock, 1) == -1) { -- fprintf(stderr, "listen() failed\n"); -- exit(1); ++ } ++ } ++ + if (password) { +#if CONFIG_VNC_TLS + if (tls) { @@ -1775,7 +1883,7 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn + vs->subauth = VNC_AUTH_INVALID; + } +#endif - } ++ } +#ifndef _WIN32 + if (strstart(display, "unix:", &p)) { + addr = (struct sockaddr *)&uaddr; @@ -1788,27 +1896,18 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn + vs->display = NULL; + return -1; + } - -- ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, -- NULL, vs); -- if (ret == -1) -- exit(1); ++ + uaddr.sun_family = AF_UNIX; + memset(uaddr.sun_path, 0, 108); + snprintf(uaddr.sun_path, 108, "%s", p); - -- vs->ds->data = NULL; -- vs->ds->dpy_update = vnc_dpy_update; -- vs->ds->dpy_resize = vnc_dpy_resize; -- vs->ds->dpy_refresh = vnc_dpy_refresh; ++ + unlink(uaddr.sun_path); + } else +#endif + { + addr = (struct sockaddr *)&iaddr; + addrlen = sizeof(iaddr); - -- vnc_dpy_resize(vs->ds, 640, 400); ++ + if (parse_host_port(&iaddr, display) < 0) { + fprintf(stderr, "Could not parse VNC address\n"); + free(vs->display); @@ -1870,8 +1969,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/vnc.c xen-3.1.0-src.new/tools/ioemu/vn int vnc_start_viewer(int port) diff -rupN xen-3.1.0-src.orig/tools/ioemu/xenstore.c xen-3.1.0-src.new/tools/ioemu/xenstore.c ---- xen-3.1.0-src.orig/tools/ioemu/xenstore.c 2007-08-28 17:02:25.000000000 -0400 -+++ xen-3.1.0-src.new/tools/ioemu/xenstore.c 2007-08-28 17:10:41.000000000 -0400 +--- xen-3.1.0-src.orig/tools/ioemu/xenstore.c 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/ioemu/xenstore.c 2007-10-10 17:31:52.000000000 -0400 @@ -367,7 +367,7 @@ void xenstore_write_vncport(int display) if (pasprintf(&buf, "%s/console/vnc-port", path) == -1) goto out; @@ -1890,8 +1989,8 @@ diff -rupN xen-3.1.0-src.orig/tools/ioemu/xenstore.c xen-3.1.0-src.new/tools/ioe free(path); return rc; diff -rupN xen-3.1.0-src.orig/tools/python/xen/xend/image.py xen-3.1.0-src.new/tools/python/xen/xend/image.py ---- xen-3.1.0-src.orig/tools/python/xen/xend/image.py 2007-08-28 17:02:25.000000000 -0400 -+++ xen-3.1.0-src.new/tools/python/xen/xend/image.py 2007-08-28 17:22:59.000000000 -0400 +--- xen-3.1.0-src.orig/tools/python/xen/xend/image.py 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/python/xen/xend/image.py 2007-10-10 20:19:46.000000000 -0400 @@ -30,6 +30,7 @@ from xen.xend.XendOptions import instanc from xen.xend.server.netif import randomMAC from xen.xend.xenstore.xswatch import xswatch @@ -1948,9 +2047,9 @@ diff -rupN xen-3.1.0-src.orig/tools/python/xen/xend/image.py xen-3.1.0-src.new/t # SDL is default in QEMU. pass diff -rupN xen-3.1.0-src.orig/tools/python/xen/xend/server/vfbif.py xen-3.1.0-src.new/tools/python/xen/xend/server/vfbif.py ---- xen-3.1.0-src.orig/tools/python/xen/xend/server/vfbif.py 2007-08-28 17:02:25.000000000 -0400 -+++ xen-3.1.0-src.new/tools/python/xen/xend/server/vfbif.py 2007-08-28 17:09:06.000000000 -0400 -@@ -61,8 +61,10 @@ class VfbifController(DevController): +--- xen-3.1.0-src.orig/tools/python/xen/xend/server/vfbif.py 2007-10-10 20:20:09.000000000 -0400 ++++ xen-3.1.0-src.new/tools/python/xen/xend/server/vfbif.py 2007-10-10 17:31:52.000000000 -0400 +@@ -69,8 +69,10 @@ class VfbifController(DevController): passwd = config["vncpasswd"] else: passwd = xen.xend.XendOptions.instance().get_vncpasswd_default() @@ -1961,7 +2060,7 @@ diff -rupN xen-3.1.0-src.orig/tools/python/xen/xend/server/vfbif.py xen-3.1.0-sr log.debug("Stored a VNC password for vfb access") else: log.debug("No VNC passwd configured for vfb access") -@@ -70,7 +72,7 @@ class VfbifController(DevController): +@@ -78,7 +80,7 @@ class VfbifController(DevController): vnclisten = config.get('vnclisten', xen.xend.XendOptions.instance().get_vnclisten_address()) vncdisplay = config.get('vncdisplay', 0) diff --git a/xen-qemu-vnc-x509-certs.patch b/xen-qemu-vnc-x509-certs.patch new file mode 100644 index 0000000..ae8bd2b --- /dev/null +++ b/xen-qemu-vnc-x509-certs.patch @@ -0,0 +1,105 @@ +diff -rup xen-3.1.0-src.orig/tools/examples/xend-config.sxp xen-3.1.0-src.new/tools/examples/xend-config.sxp +--- xen-3.1.0-src.orig/tools/examples/xend-config.sxp 2007-10-10 17:31:42.000000000 -0400 ++++ xen-3.1.0-src.new/tools/examples/xend-config.sxp 2007-10-10 17:55:25.000000000 -0400 +@@ -202,3 +202,33 @@ + # The default password for VNC console on HVM domain. + # Empty string is no authentication. + (vncpasswd '') ++ ++# The VNC server can be told to negotiate a TLS session ++# to encryption all traffic, and provide x509 cert to ++# clients enalbing them to verify server identity. The ++# GTK-VNC widget, virt-viewer, virt-manager and VeNCrypt ++# all support the VNC extension for TLS used in QEMU. The ++# TightVNC/RealVNC/UltraVNC clients do not. ++# ++# To enable this create x509 certificates / keys in the ++# directory /etc/xen/vnc ++# ++# ca-cert.pem - The CA certificate ++# server-cert.pem - The Server certificate signed by the CA ++# server-key.pem - The server private key ++# ++# and then uncomment this next line ++# (vnc-tls 1) ++# ++# The certificate dir can be pointed elsewhere.. ++# ++# (vnc-x509-cert-dir /etc/xen/vnc) ++# ++# The server can be told to request & validate an x509 ++# certificate from the client. Only clients with a cert ++# signed by the trusted CA will be able to connect. This ++# is more secure the password auth alone. Passwd auth can ++# used at the same time if desired. To enable client cert ++# checking uncomment this: ++# ++# (vnc-x509-verify 1) +diff -rup xen-3.1.0-src.orig/tools/python/xen/xend/image.py xen-3.1.0-src.new/tools/python/xen/xend/image.py +--- xen-3.1.0-src.orig/tools/python/xen/xend/image.py 2007-10-10 17:31:42.000000000 -0400 ++++ xen-3.1.0-src.new/tools/python/xen/xend/image.py 2007-10-10 19:54:22.000000000 -0400 +@@ -17,7 +17,7 @@ + #============================================================================ + + +-import os, string ++import os, os.path, string + import re + import math + import signal +@@ -400,6 +400,19 @@ class HVMImageHandler(ImageHandler): + else: + log.debug("No VNC passwd configured for vfb access") + ++ if XendOptions.instance().get_vnc_tls(): ++ vncx509certdir = XendOptions.instance().get_vnc_x509_cert_dir() ++ vncx509verify = XendOptions.instance().get_vnc_x509_verify() ++ ++ if not os.path.exists(vncx509certdir): ++ raise "VNC x509 certificate dir does not exist" ++ ++ if vncx509verify: ++ vncopts = vncopts + ",tls,x509verify=%s" % vncx509certdir ++ else: ++ vncopts = vncopts + ",tls,x509=%s" % vncx509certdir ++ ++ + vnclisten = vnc_config.get('vnclisten', + XendOptions.instance().get_vnclisten_address()) + vncdisplay = vnc_config.get('vncdisplay', 0) +diff -rup xen-3.1.0-src.orig/tools/python/xen/xend/XendOptions.py xen-3.1.0-src.new/tools/python/xen/xend/XendOptions.py +--- xen-3.1.0-src.orig/tools/python/xen/xend/XendOptions.py 2007-05-18 10:45:21.000000000 -0400 ++++ xen-3.1.0-src.new/tools/python/xen/xend/XendOptions.py 2007-10-10 17:55:49.000000000 -0400 +@@ -102,6 +102,15 @@ class XendOptions: + """Default interface to listen for VNC connections on""" + xend_vnc_listen_default = '127.0.0.1' + ++ """Use of TLS mode in QEMU VNC server""" ++ xend_vnc_tls = 0 ++ ++ """x509 certificate directory for QEMU VNC server""" ++ xend_vnc_x509_cert_dir = "/etc/xen/vnc" ++ ++ """Verify incoming client x509 certs""" ++ xend_vnc_x509_verify = 0 ++ + """Default session storage path.""" + xend_domains_path_default = '/var/lib/xend/domains' + +@@ -278,6 +287,16 @@ class XendOptions: + return self.get_config_string('vncpasswd', + self.vncpasswd_default) + ++ def get_vnc_tls(self): ++ return self.get_config_string('vnc-tls', self.xend_vnc_tls) ++ ++ def get_vnc_x509_cert_dir(self): ++ return self.get_config_string('vnc-x509-cert-dir', self.xend_vnc_x509_cert_dir) ++ ++ def get_vnc_x509_verify(self): ++ return self.get_config_string('vnc-x509-verify', self.xend_vnc_x509_verify) ++ ++ + class XendOptionsFile(XendOptions): + + """Default path to the config file.""" diff --git a/xen.spec b/xen.spec index e2249b7..4fb6735 100644 --- a/xen.spec +++ b/xen.spec @@ -47,6 +47,7 @@ Patch164: xen-qemu-vnc-revert-password.patch Patch165: xen-qemu-iohandler-delete.patch Patch166: xen-qemu-vnc-authentication.patch +Patch167: xen-qemu-vnc-x509-certs.patch Patch251: pygrub-manykernels.patch @@ -160,6 +161,7 @@ virtual machines. # Add new TLS code %patch165 -p1 %patch166 -p1 +%patch167 -p1 # upstream patches %patch251 -p1 @@ -293,6 +295,8 @@ rm -rf $RPM_BUILD_ROOT %changelog * Wed Oct 10 2007 Daniel P. Berrange - 3.1.0-12.fc8 - Pull in QEMU BIOS boot menu patch from KVM package +- Fix QEMU patch for locating x509 certificates based on command line args +- Add XenD config options for TLS x509 certificate setup * Wed Sep 26 2007 Daniel P. Berrange - 3.1.0-11.fc8 - Fixed rtl8139 checksum calculation for Vista (rhbz #308201)