qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PATCH v1 RFC 30/34] ui: convert VNC server to use QIOChannelTLS
Date: Fri, 17 Apr 2015 15:22:33 +0100	[thread overview]
Message-ID: <1429280557-8887-31-git-send-email-berrange@redhat.com> (raw)
In-Reply-To: <1429280557-8887-1-git-send-email-berrange@redhat.com>

Switch VNC server over to using the QIOChannelTLS object for
the TLS session. This removes all the VNC specific code for
dealing with TLS. This has the nice effect that all the
CONFIG_VNC_TLS conditionals go away and the user gets an
actual error message when requesting TLS instead of it being
silently ignored.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 configure              |  31 ------
 qemu-options.hx        |  28 ++++-
 ui/Makefile.objs       |   2 +-
 ui/vnc-auth-sasl.c     |  46 +++-----
 ui/vnc-auth-vencrypt.c | 107 ++++++------------
 ui/vnc-tls.h           |  69 ------------
 ui/vnc-ws.c            |  89 +++++++--------
 ui/vnc-ws.h            |   2 -
 ui/vnc.c               | 296 ++++++++++++++++++++++++++-----------------------
 ui/vnc.h               |  13 +--
 10 files changed, 279 insertions(+), 404 deletions(-)
 delete mode 100644 ui/vnc-tls.h

diff --git a/configure b/configure
index fa07f2c..24133c0 100755
--- a/configure
+++ b/configure
@@ -241,7 +241,6 @@ vnc="yes"
 sparse="no"
 uuid=""
 vde=""
-vnc_tls=""
 vnc_sasl=""
 vnc_jpeg=""
 vnc_png=""
@@ -872,10 +871,6 @@ for opt do
   ;;
   --disable-strip) strip_opt="no"
   ;;
-  --disable-vnc-tls) vnc_tls="no"
-  ;;
-  --enable-vnc-tls) vnc_tls="yes"
-  ;;
   --disable-vnc-sasl) vnc_sasl="no"
   ;;
   --enable-vnc-sasl) vnc_sasl="yes"
@@ -2369,28 +2364,6 @@ EOF
   fi
 fi
 
-##########################################
-# VNC TLS/WS detection
-if test "$vnc" = "yes" -a "$vnc_tls" != "no" ; then
-  cat > $TMPC <<EOF
-#include <gnutls/gnutls.h>
-int main(void) { gnutls_session_t s; gnutls_init(&s, GNUTLS_SERVER); return 0; }
-EOF
-  vnc_tls_cflags=`$pkg_config --cflags gnutls 2> /dev/null`
-  vnc_tls_libs=`$pkg_config --libs gnutls 2> /dev/null`
-  if compile_prog "$vnc_tls_cflags" "$vnc_tls_libs" ; then
-    if test "$vnc_tls" != "no" ; then
-      vnc_tls=yes
-    fi
-    libs_softmmu="$vnc_tls_libs $libs_softmmu"
-    QEMU_CFLAGS="$QEMU_CFLAGS $vnc_tls_cflags"
-  else
-    if test "$vnc_tls" = "yes" ; then
-      feature_not_found "vnc-tls" "Install gnutls devel"
-    fi
-    vnc_tls=no
-  fi
-fi
 
 ##########################################
 # VNC SASL detection
@@ -4432,7 +4405,6 @@ echo "Block whitelist (ro) $block_drv_ro_whitelist"
 echo "VirtFS support    $virtfs"
 echo "VNC support       $vnc"
 if test "$vnc" = "yes" ; then
-    echo "VNC TLS support   $vnc_tls"
     echo "VNC SASL support  $vnc_sasl"
     echo "VNC JPEG support  $vnc_jpeg"
     echo "VNC PNG support   $vnc_png"
@@ -4628,9 +4600,6 @@ echo "CONFIG_BDRV_RO_WHITELIST=$block_drv_ro_whitelist" >> $config_host_mak
 if test "$vnc" = "yes" ; then
   echo "CONFIG_VNC=y" >> $config_host_mak
 fi
-if test "$vnc_tls" = "yes" ; then
-  echo "CONFIG_VNC_TLS=y" >> $config_host_mak
-fi
 if test "$vnc_sasl" = "yes" ; then
   echo "CONFIG_VNC_SASL=y" >> $config_host_mak
 fi
diff --git a/qemu-options.hx b/qemu-options.hx
index 1c88253..44d9be2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1206,8 +1206,9 @@ By definition the Websocket port is 5700+@var{display}. If @var{host} is
 specified connections will only be allowed from this host.
 As an alternative the Websocket port could be specified by using
 @code{websocket}=@var{port}.
-TLS encryption for the Websocket connection is supported if the required
-certificates are specified with the VNC option @option{x509}.
+If no TLS credentials are provided, the websocket connection runs in
+uncrypted mode. If TLS credentials are provided, the websocket connection
+requires encrypted client connections.
 
 @item password
 
@@ -1228,6 +1229,20 @@ date and time).
 You can also use keywords "now" or "never" for the expiration time to
 allow <protocol> password to expire immediately or never expire.
 
+@item tls-cred=@var{ID}
+
+Provides the ID of a set of TLS credentials to use to secure the
+VNC server. They will apply to both the normal VNC server socket
+and the websocket socket (if enabled). Setting TLS credentials
+will cause the VNC server socket to enable the VeNCrypt auth
+mechanism.  The credentials should have been previously created
+using the @option{-object qcrypto-tls-cred} argument.
+
+The @option{tls-cred} parameter obsoletes the @option{tls},
+@option{x509}, and @option{x509verify} options, and as such
+it is not permitted to set both new and old type options at
+the same time.
+
 @item tls
 
 Require that client use TLS when communicating with the VNC server. This
@@ -1235,6 +1250,9 @@ uses anonymous TLS credentials so is susceptible to a man-in-the-middle
 attack. It is recommended that this option be combined with either the
 @option{x509} or @option{x509verify} options.
 
+This option is now deprecated in favour of using the @option{tls-cred}
+argument.
+
 @item x509=@var{/path/to/certificate/dir}
 
 Valid if @option{tls} is specified. Require that x509 credentials are used
@@ -1244,6 +1262,9 @@ to provide authentication of the client when this is used. The path following
 this option specifies where the x509 certificates are to be loaded from.
 See the @ref{vnc_security} section for details on generating certificates.
 
+This option is now deprecated in favour of using the @option{tls-cred}
+argument.
+
 @item x509verify=@var{/path/to/certificate/dir}
 
 Valid if @option{tls} is specified. Require that x509 credentials are used
@@ -1257,6 +1278,9 @@ path following this option specifies where the x509 certificates are to
 be loaded from. See the @ref{vnc_security} section for details on generating
 certificates.
 
+This option is now deprecated in favour of using the @option{tls-cred}
+argument.
+
 @item sasl
 
 Require that the client use SASL to authenticate with the VNC server.
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index 6458d3c..b8314f5 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -2,7 +2,7 @@ vnc-obj-y += vnc.o
 vnc-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o
 vnc-obj-y += vnc-enc-tight.o vnc-palette.o
 vnc-obj-y += vnc-enc-zrle.o
-vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
+vnc-obj-y += vnc-auth-vencrypt.o
 vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
 vnc-obj-y += vnc-ws.o
 vnc-obj-y += vnc-jobs.o
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
index 7851037..4d05a65 100644
--- a/ui/vnc-auth-sasl.c
+++ b/ui/vnc-auth-sasl.c
@@ -495,7 +495,7 @@ void start_auth_sasl(VncState *vs)
 {
     const char *mechlist = NULL;
     sasl_security_properties_t secprops;
-    int err;
+    int ret;
     char *localAddr, *remoteAddr;
     int mechlistlen;
 
@@ -513,7 +513,7 @@ void start_auth_sasl(VncState *vs)
         goto authabort;
     }
 
-    err = sasl_server_new("vnc",
+    ret = sasl_server_new("vnc",
                           NULL, /* FQDN - just delegates to gethostname */
                           NULL, /* User realm */
                           localAddr,
@@ -525,54 +525,44 @@ void start_auth_sasl(VncState *vs)
     g_free(remoteAddr);
     localAddr = remoteAddr = NULL;
 
-    if (err != SASL_OK) {
+    if (ret != SASL_OK) {
         VNC_DEBUG("sasl context setup failed %d (%s)",
-                  err, sasl_errstring(err, NULL, NULL));
+                  ret, sasl_errstring(ret, 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->auth == VNC_AUTH_VENCRYPT &&
         vs->subauth == VNC_AUTH_VENCRYPT_X509SASL) {
-        gnutls_cipher_algorithm_t cipher;
-        sasl_ssf_t ssf;
-
-        cipher = gnutls_cipher_get(vs->tls.session);
-        ssf = (sasl_ssf_t)gnutls_cipher_get_key_size(cipher);
-        if (!ssf) {
-            VNC_DEBUG("%s", "cannot TLS get cipher size\n");
-            sasl_dispose(&vs->sasl.conn);
-            vs->sasl.conn = NULL;
+        Error *err = NULL;
+        int ssf = qcrypto_tls_session_get_key_size(vs->tls, &err);
+        if (ssf < 0) {
+            VNC_DEBUG("Cannot get key size %s\n", error_get_pretty(err));
+            error_free(err);
             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) {
+        ret = sasl_setprop(vs->sasl.conn, SASL_SSF_EXTERNAL, &ssf);
+        if (ret != SASL_OK) {
             VNC_DEBUG("cannot set SASL external SSF %d (%s)\n",
-                      err, sasl_errstring(err, NULL, NULL));
+                      ret, sasl_errstring(ret, NULL, NULL));
             sasl_dispose(&vs->sasl.conn);
             vs->sasl.conn = NULL;
             goto authabort;
         }
     } else {
-#endif /* CONFIG_VNC_TLS */
         vs->sasl.wantSSF = 1;
-#ifdef CONFIG_VNC_TLS
     }
-#endif
 
     memset (&secprops, 0, sizeof secprops);
     /* Inform SASL that we've got an external SSF layer from TLS */
     if (vs->vd->is_unix
-#ifdef CONFIG_VNC_TLS
         /* Disable SSF, if using TLS+x509+SASL only. TLS without x509
            is not sufficiently strong */
         || (vs->auth == VNC_AUTH_VENCRYPT &&
             vs->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;
@@ -589,16 +579,16 @@ void start_auth_sasl(VncState *vs)
             SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT;
     }
 
-    err = sasl_setprop(vs->sasl.conn, SASL_SEC_PROPS, &secprops);
-    if (err != SASL_OK) {
+    ret = sasl_setprop(vs->sasl.conn, SASL_SEC_PROPS, &secprops);
+    if (ret != SASL_OK) {
         VNC_DEBUG("cannot set SASL security props %d (%s)\n",
-                  err, sasl_errstring(err, NULL, NULL));
+                  ret, sasl_errstring(ret, NULL, NULL));
         sasl_dispose(&vs->sasl.conn);
         vs->sasl.conn = NULL;
         goto authabort;
     }
 
-    err = sasl_listmech(vs->sasl.conn,
+    ret = sasl_listmech(vs->sasl.conn,
                         NULL, /* Don't need to set user */
                         "", /* Prefix */
                         ",", /* Separator */
@@ -606,9 +596,9 @@ void start_auth_sasl(VncState *vs)
                         &mechlist,
                         NULL,
                         NULL);
-    if (err != SASL_OK) {
+    if (ret != SASL_OK) {
         VNC_DEBUG("cannot list SASL mechanisms %d (%s)\n",
-                  err, sasl_errdetail(vs->sasl.conn));
+                  ret, sasl_errdetail(vs->sasl.conn));
         sasl_dispose(&vs->sasl.conn);
         vs->sasl.conn = NULL;
         goto authabort;
diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
index 55f24e4..99846fa 100644
--- a/ui/vnc-auth-vencrypt.c
+++ b/ui/vnc-auth-vencrypt.c
@@ -63,76 +63,22 @@ static void start_auth_vencrypt_subauth(VncState *vs)
     }
 }
 
-static gboolean vnc_tls_handshake_io(QIOChannel *ioc,
-                                     GIOCondition condition,
-                                     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)) {
-            GIOCondition condition;
-            VNC_DEBUG("Handshake interrupted (blocking)\n");
-            if (!gnutls_record_get_direction(vs->tls.session)) {
-                condition = G_IO_IN;
-            } else {
-                condition = G_IO_OUT;
-            }
-            if (vs->ioc_tag) {
-                g_source_remove(vs->ioc_tag);
-            }
-            vs->ioc_tag = qio_channel_add_watch(
-                vs->ioc, condition, 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");
-    if (vs->ioc_tag) {
-        g_source_remove(vs->ioc_tag);
-    }
-    vs->ioc_tag = qio_channel_add_watch(
-        vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs);
-
-    start_auth_vencrypt_subauth(vs);
-
-    return 0;
-}
-
-static gboolean vnc_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
-                                     GIOCondition condition G_GNUC_UNUSED,
-                                     void *opaque)
+static void vnc_tls_handshake_done(QIOTask *task,
+                                   gpointer user_data)
 {
-    struct VncState *vs = (struct VncState *)opaque;
+    struct VncState *vs = user_data;
 
-    VNC_DEBUG("Handshake IO continue\n");
-    vnc_start_vencrypt_handshake(vs);
-    return TRUE;
+    if (task->err) {
+        VNC_DEBUG("Handshake failed %s\n",
+                  error_get_pretty(task->err));
+        vnc_client_error(vs);
+    } else {
+        vs->ioc_tag = qio_channel_add_watch(
+            vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs);
+        start_auth_vencrypt_subauth(vs);
+    }
 }
 
-
-
-#define NEED_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)
-
-
 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
 {
     int auth = read_u32(data, 0);
@@ -143,20 +89,37 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
         vnc_flush(vs);
         vnc_client_error(vs);
     } else {
+        Error *err = NULL;
+        QIOChannelTLS *tls;
         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;
+        if (vs->ioc_tag) {
+            g_source_remove(vs->ioc_tag);
+            vs->ioc_tag = 0;
         }
 
-        VNC_DEBUG("Start TLS VeNCrypt handshake process\n");
-        if (vnc_start_vencrypt_handshake(vs) < 0) {
-            VNC_DEBUG("Failed to start TLS handshake\n");
+        tls = qio_channel_tls_new_server(
+            vs->ioc,
+            vs->vd->creds,
+            vs->vd->tlsaclname,
+            &err);
+        if (!tls) {
+            VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err));
+            error_free(err);
+            vnc_client_error(vs);
             return 0;
         }
+
+        object_unref(OBJECT(vs->ioc));
+        vs->ioc = QIO_CHANNEL(tls);
+        vs->tls = qio_channel_tls_get_session(tls);
+
+        qio_channel_tls_handshake(tls,
+                                  vnc_tls_handshake_done,
+                                  vs,
+                                  NULL);
     }
     return 0;
 }
diff --git a/ui/vnc-tls.h b/ui/vnc-tls.h
deleted file mode 100644
index f9829c7..0000000
--- a/ui/vnc-tls.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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>
-
-#include "qemu/acl.h"
-
-typedef struct VncDisplayTLS VncDisplayTLS;
-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;
-    char *x509cacrl;
-    char *x509cert;
-    char *x509key;
-};
-
-/* Per client state */
-struct VncStateTLS {
-    gnutls_session_t session;
-
-    /* Client's Distinguished Name from the x509 cert */
-    char *dname;
-};
-
-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__ */
-
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
index ad22694..714e513 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -22,73 +22,62 @@
 #include "qemu/main-loop.h"
 #include "crypto/hash.h"
 
-#ifdef CONFIG_VNC_TLS
 #include "qemu/sockets.h"
 
 static void vncws_handshake_read(VncState *vs);
 
-static int vncws_start_tls_handshake(struct VncState *vs)
+static void vncws_tls_handshake_done(QIOTask *task,
+                                     gpointer user_data)
 {
-    int ret = gnutls_handshake(vs->tls.session);
-
-    if (ret < 0) {
-        if (!gnutls_error_is_fatal(ret)) {
-            GIOCondition condition;
-            VNC_DEBUG("Handshake interrupted (blocking)\n");
-            if (!gnutls_record_get_direction(vs->tls.session)) {
-                condition = G_IO_IN;
-            } else {
-                condition = G_IO_OUT;
-            }
-            if (vs->ioc_tag) {
-                g_source_remove(vs->ioc_tag);
-            }
-            vs->ioc_tag = qio_channel_add_watch(
-                vs->ioc, condition, vncws_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");
-        }
-    }
+    struct VncState *vs = user_data;
 
-    VNC_DEBUG("Handshake done, switching to TLS data mode\n");
-    if (vs->ioc_tag) {
-        g_source_remove(vs->ioc_tag);
+    if (task->err) {
+        VNC_DEBUG("Handshake failed %s\n", error_get_pretty(task->err));
+        vnc_client_error(vs);
+    } else {
+        vs->ioc_tag = qio_channel_add_watch(
+            QIO_CHANNEL(vs->ioc), G_IO_IN, vncws_handshake_io, vs);
     }
-    vs->ioc_tag = qio_channel_add_watch(
-        vs->ioc, G_IO_IN, vncws_handshake_io, vs);
-
-    return 0;
 }
 
+
 gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
                                 GIOCondition condition G_GNUC_UNUSED,
                                 void *opaque)
 {
-    struct VncState *vs = (struct VncState *)opaque;
+    VncState *vs = opaque;
+    QIOChannelTLS *tls;
+    Error *err = NULL;
 
-    if (!vs->tls.session) {
-        VNC_DEBUG("TLS Websocket setup\n");
-        if (vnc_tls_client_setup(vs, vs->vd->tls.x509cert != NULL) < 0) {
-            return TRUE;
-        }
+    VNC_DEBUG("TLS Websocket connection required\n");
+    if (vs->ioc_tag) {
+        g_source_remove(vs->ioc_tag);
+        vs->ioc_tag = 0;
     }
-    VNC_DEBUG("Handshake IO continue\n");
-    vncws_start_tls_handshake(vs);
+
+    tls = qio_channel_tls_new_server(
+        vs->ioc,
+        vs->vd->creds,
+        vs->vd->tlsaclname,
+        &err);
+    if (!tls) {
+        VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err));
+        error_free(err);
+        vnc_client_error(vs);
+        return TRUE;
+    }
+
+    object_unref(OBJECT(vs->ioc));
+    vs->ioc = QIO_CHANNEL(tls);
+    vs->tls = qio_channel_tls_get_session(tls);
+
+    qio_channel_tls_handshake(tls,
+                              vncws_tls_handshake_done,
+                              vs,
+                              NULL);
+
     return TRUE;
 }
-#endif /* CONFIG_VNC_TLS */
 
 static void vncws_handshake_read(VncState *vs)
 {
diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h
index 2e79324..21caaf3 100644
--- a/ui/vnc-ws.h
+++ b/ui/vnc-ws.h
@@ -72,11 +72,9 @@ enum {
     WS_OPCODE_PONG = 0xA
 };
 
-#ifdef CONFIG_VNC_TLS
 gboolean vncws_tls_handshake_io(QIOChannel *ioc,
                                 GIOCondition condition,
                                 void *opaque);
-#endif /* CONFIG_VNC_TLS */
 gboolean vncws_handshake_io(QIOChannel *ioc,
                             GIOCondition condition,
                             void *opaque);
diff --git a/ui/vnc.c b/ui/vnc.c
index 6c08711..65d7493 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -39,6 +39,7 @@
 #include "ui/input.h"
 #include "qapi-event.h"
 #include "crypto/hash.h"
+#include "qom/object_interfaces.h"
 
 #include <glib/gi18n.h>
 
@@ -191,7 +192,6 @@ static const char *vnc_auth_name(VncDisplay *vd) {
     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";
@@ -214,9 +214,6 @@ static const char *vnc_auth_name(VncDisplay *vd) {
         default:
             return "vencrypt";
         }
-#else
-        return "vencrypt";
-#endif
     case VNC_AUTH_SASL:
         return "sasl";
     }
@@ -247,13 +244,12 @@ static void vnc_client_cache_auth(VncState *client)
         return;
     }
 
-#ifdef CONFIG_VNC_TLS
-    if (client->tls.session &&
-        client->tls.dname) {
-        client->info->has_x509_dname = true;
-        client->info->x509_dname = g_strdup(client->tls.dname);
+    if (client->tls) {
+        client->info->x509_dname =
+            qcrypto_tls_session_get_peer_name(client->tls);
+        client->info->has_x509_dname =
+            client->info->x509_dname != NULL;
     }
-#endif
 #ifdef CONFIG_VNC_SASL
     if (client->sasl.conn &&
         client->sasl.username) {
@@ -325,12 +321,10 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
     info->base = binfo;
     info->base->websocket = client->websocket;
 
-#ifdef CONFIG_VNC_TLS
-    if (client->tls.session && client->tls.dname) {
-        info->has_x509_dname = true;
-        info->x509_dname = g_strdup(client->tls.dname);
+    if (client->tls) {
+        info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
+        info->has_x509_dname = info->x509_dname != NULL;
     }
-#endif
 #ifdef CONFIG_VNC_SASL
     if (client->sasl.conn && client->sasl.username) {
         info->has_sasl_username = true;
@@ -456,7 +450,6 @@ static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
         break;
     case VNC_AUTH_VENCRYPT:
         info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
-#ifdef CONFIG_VNC_TLS
         info->has_vencrypt = true;
         switch (vd->subauth) {
         case VNC_AUTH_VENCRYPT_PLAIN:
@@ -490,7 +483,6 @@ static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
             info->has_vencrypt = false;
             break;
         }
-#endif
         break;
     case VNC_AUTH_SASL:
         info->auth = VNC_PRIMARY_AUTH_SASL;
@@ -1140,9 +1132,6 @@ void vnc_disconnect_finish(VncState *vs)
     vnc_tight_clear(vs);
     vnc_zrle_clear(vs);
 
-#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 */
@@ -1202,26 +1191,6 @@ void vnc_client_error(VncState *vs)
     vnc_disconnect_start(vs);
 }
 
-#ifdef CONFIG_VNC_TLS
-static ssize_t vnc_client_write_tls(gnutls_session_t *session,
-                                    const uint8_t *data,
-                                    size_t datalen,
-                                    Error **errp)
-{
-    ssize_t ret = gnutls_write(*session, data, datalen);
-    if (ret < 0) {
-        if (ret == GNUTLS_E_AGAIN) {
-            ret = -2;
-        } else {
-            ret = -1;
-            error_setg_errno(errp, -EIO, "%s",
-                             _("Cannot write to TLS socket"));
-        }
-    }
-    return ret;
-}
-#endif /* CONFIG_VNC_TLS */
-
 /*
  * 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.
@@ -1241,16 +1210,8 @@ ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
 {
     ssize_t ret;
     Error *err = NULL;
-#ifdef CONFIG_VNC_TLS
-    if (vs->tls.session) {
-        ret = vnc_client_write_tls(&vs->tls.session, data, datalen, &err);
-    } else {
-#endif /* CONFIG_VNC_TLS */
-        ret = qio_channel_write(
-            vs->ioc, (const char *)data, datalen, &err);
-#ifdef CONFIG_VNC_TLS
-    }
-#endif /* CONFIG_VNC_TLS */
+    ret = qio_channel_write(
+        vs->ioc, (const char *)data, datalen, &err);
     VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
     return vnc_client_io_error(vs, ret, &err);
 }
@@ -1346,24 +1307,6 @@ void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
     vs->read_handler_expect = expecting;
 }
 
-#ifdef CONFIG_VNC_TLS
-static ssize_t vnc_client_read_tls(gnutls_session_t *session, uint8_t *data,
-                                   size_t datalen, Error **errp)
-{
-    ssize_t ret = gnutls_read(*session, data, datalen);
-    if (ret < 0) {
-        if (ret == GNUTLS_E_AGAIN) {
-            ret = QIO_CHANNEL_ERR_BLOCK;
-        } else {
-            ret = -1;
-            error_setg_errno(errp, -EIO, "%s",
-                             _("Cannot read from TLS socket"));
-        }
-    }
-    return ret;
-}
-#endif /* CONFIG_VNC_TLS */
-
 /*
  * 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.
@@ -1383,16 +1326,8 @@ ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
 {
     ssize_t ret;
     Error *err = NULL;
-#ifdef CONFIG_VNC_TLS
-    if (vs->tls.session) {
-        ret = vnc_client_read_tls(&vs->tls.session, data, datalen, &err);
-    } else {
-#endif /* CONFIG_VNC_TLS */
-        ret = qio_channel_read(
-            vs->ioc, (char *)data, datalen, &err);
-#ifdef CONFIG_VNC_TLS
-    }
-#endif /* CONFIG_VNC_TLS */
+    ret = qio_channel_read(
+        vs->ioc, (char *)data, datalen, &err);
     VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
     return vnc_client_io_error(vs, ret, &err);
 }
@@ -2559,12 +2494,10 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
            start_auth_vnc(vs);
            break;
 
-#ifdef CONFIG_VNC_TLS
        case VNC_AUTH_VENCRYPT:
            VNC_DEBUG("Accept VeNCrypt auth\n");
            start_auth_vencrypt(vs);
            break;
-#endif /* CONFIG_VNC_TLS */
 
 #ifdef CONFIG_VNC_SASL
        case VNC_AUTH_SASL:
@@ -2946,8 +2879,8 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
             vs->subauth = vd->subauth;
         }
     }
-    VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
-              csock, websocket, vs->auth, vs->subauth);
+    VNC_DEBUG("Client sock=%p ws=%d auth=%d subauth=%d\n",
+              sioc, websocket, vs->auth, vs->subauth);
 
     vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
     for (i = 0; i < VNC_STAT_ROWS; ++i) {
@@ -2959,13 +2892,10 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
     qio_channel_set_blocking(vs->ioc, false);
     if (websocket) {
         vs->websocket = 1;
-#ifdef CONFIG_VNC_TLS
         if (vd->ws_tls) {
             vs->ioc_tag = qio_channel_add_watch(
                 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs);
-        } else
-#endif /* CONFIG_VNC_TLS */
-        {
+        } else {
             vs->ioc_tag = qio_channel_add_watch(
                 vs->ioc, G_IO_IN, vncws_handshake_io, vs);
         }
@@ -3116,9 +3046,11 @@ static void vnc_display_close(VncDisplay *vs)
     }
     vs->auth = VNC_AUTH_INVALID;
     vs->subauth = VNC_AUTH_INVALID;
-#ifdef CONFIG_VNC_TLS
-    vs->tls.x509verify = 0;
-#endif
+    /** XXX unregister transient creds from global namespace?,
+     * or does it go away automatically on last unref ?*/
+    object_unref(OBJECT(vs->creds));
+    g_free(vs->tlsaclname);
+    vs->tlsaclname = NULL;
 }
 
 int vnc_display_password(const char *id, const char *password)
@@ -3172,6 +3104,9 @@ static QemuOptsList qemu_vnc_opts = {
             .name = "websocket",
             .type = QEMU_OPT_STRING,
         },{
+            .name = "tls-cred",
+            .type = QEMU_OPT_STRING,
+        },{
             .name = "x509",
             .type = QEMU_OPT_STRING,
         },{
@@ -3228,13 +3163,12 @@ static QemuOptsList qemu_vnc_opts = {
 };
 
 
-static void
+static int
 vnc_display_setup_auth(VncDisplay *vs,
                        bool password,
                        bool sasl,
-                       bool tls,
-                       bool x509,
-                       bool websocket)
+                       bool websocket,
+                       Error **errp)
 {
     /*
      * We have a choice of 3 authentication options
@@ -3284,17 +3218,27 @@ vnc_display_setup_auth(VncDisplay *vs,
      * result has the same security characteristics.
      */
     if (password) {
-        if (tls) {
+        if (vs->creds) {
             vs->auth = VNC_AUTH_VENCRYPT;
             if (websocket) {
                 vs->ws_tls = true;
             }
-            if (x509) {
+            switch (vs->creds->type) {
+            case QCRYPTO_TLS_CREDS_TYPE_X509:
                 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
                 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
-            } else {
+                break;
+
+            case QCRYPTO_TLS_CREDS_TYPE_ANON:
                 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
                 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
+                break;
+
+            default:
+                error_setg(errp,
+                           _("Unsupported TLS cred type %d"),
+                           vs->creds->type);
+                return -1;
             }
         } else {
             VNC_DEBUG("Initializing VNC server with password auth\n");
@@ -3307,17 +3251,27 @@ vnc_display_setup_auth(VncDisplay *vs,
             vs->ws_auth = VNC_AUTH_INVALID;
         }
     } else if (sasl) {
-        if (tls) {
+        if (vs->creds) {
             vs->auth = VNC_AUTH_VENCRYPT;
             if (websocket) {
                 vs->ws_tls = true;
             }
-            if (x509) {
+            switch (vs->creds->type) {
+            case QCRYPTO_TLS_CREDS_TYPE_X509:
                 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
                 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
-            } else {
+                break;
+
+            case QCRYPTO_TLS_CREDS_TYPE_ANON:
                 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
                 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
+                break;
+
+            default:
+                error_setg(errp,
+                           _("Unsupported TLS cred type %d"),
+                           vs->creds->type);
+                return -1;
             }
         } else {
             VNC_DEBUG("Initializing VNC server with SASL auth\n");
@@ -3330,17 +3284,27 @@ vnc_display_setup_auth(VncDisplay *vs,
             vs->ws_auth = VNC_AUTH_INVALID;
         }
     } else {
-        if (tls) {
+        if (vs->creds) {
             vs->auth = VNC_AUTH_VENCRYPT;
             if (websocket) {
                 vs->ws_tls = true;
             }
-            if (x509) {
+            switch (vs->creds->type) {
+            case QCRYPTO_TLS_CREDS_TYPE_X509:
                 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
                 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
-            } else {
+                break;
+
+            case QCRYPTO_TLS_CREDS_TYPE_ANON:
                 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
                 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
+                break;
+
+            default:
+                error_setg(errp,
+                           _("Unsupported TLS cred type %d"),
+                           vs->creds->type);
+                return -1;
             }
         } else {
             VNC_DEBUG("Initializing VNC server with no auth\n");
@@ -3353,6 +3317,43 @@ vnc_display_setup_auth(VncDisplay *vs,
             vs->ws_auth = VNC_AUTH_INVALID;
         }
     }
+    return 0;
+}
+
+static QCryptoTLSCreds *vnc_display_create_creds(bool x509,
+                                                 bool x509verify,
+                                                 const char *dir,
+                                                 const char *id,
+                                                 Error **errp)
+{
+    gchar *credsid = g_strdup_printf("tlsvnc%s", id);
+    Object *creds;
+
+    if (x509) {
+        creds = object_new_propv(TYPE_QCRYPTO_TLS_CREDS,
+                                 credsid,
+                                 errp,
+                                 "credtype", "x509",
+                                 "endpoint", "server",
+                                 "dir", dir,
+                                 "verify-peer", x509verify ? "yes" : "no",
+                                 NULL);
+    } else {
+        creds = object_new_propv(TYPE_QCRYPTO_TLS_CREDS,
+                                 credsid,
+                                 errp,
+                                 "credtype", "anon",
+                                 "endpoint", "server",
+                                 NULL);
+    }
+
+    g_free(credsid);
+
+    if (*errp) {
+        return NULL;
+    }
+
+    return QCRYPTO_TLS_CREDS(creds);
 }
 
 void vnc_display_open(const char *id, Error **errp)
@@ -3369,18 +3370,13 @@ void vnc_display_open(const char *id, Error **errp)
     char *h;
     bool has_ipv4 = false;
     bool has_ipv6 = false;
+    const char *credid;
     const char *websocket;
-    bool tls = false, x509 = false;
-#ifdef CONFIG_VNC_TLS
-    const char *path;
-#endif
     bool sasl = false;
 #ifdef CONFIG_VNC_SASL
     int saslErr;
 #endif
-#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
     int acl = 0;
-#endif
     int lock_key_sync = 1;
     Error *err = NULL;
 
@@ -3455,32 +3451,55 @@ void vnc_display_open(const char *id, Error **errp)
         goto fail;
     }
 #endif /* CONFIG_VNC_SASL */
-    tls  = qemu_opt_get_bool(opts, "tls", false);
-#ifdef CONFIG_VNC_TLS
-    path = qemu_opt_get(opts, "x509");
-    if (!path) {
-        path = qemu_opt_get(opts, "x509verify");
-        if (path) {
-            vs->tls.x509verify = true;
-        }
-    }
-    if (path) {
-        x509 = true;
-        if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
-            error_setg(errp, "Failed to find x509 certificates/keys in %s",
-                       path);
+    credid = qemu_opt_get(opts, "tls-cred");
+    if (credid) {
+        Object *container;
+        if (qemu_opt_get(opts, "tls") ||
+            qemu_opt_get(opts, "x509") ||
+            qemu_opt_get(opts, "x509verify")) {
+            error_setg(errp, "%s",
+                       _("'credid' parameter is mutually exclusive with "
+                         "'tls', 'x509' and 'x509verify' parameters"));
             goto fail;
         }
+
+        container = container_get(object_get_root(), "/objects");
+        /* XXX this type cast causes an abort if the type is wrong.
+         * This is bad. We should check and set an error */
+        vs->creds = QCRYPTO_TLS_CREDS(
+            object_resolve_path_component(container, credid));
+        if (!vs->creds) {
+            error_setg(errp, _("No TLS credentials with id '%s'"),
+                       credid);
+            goto fail;
+        }
+        object_ref(OBJECT(vs->creds));
+    } else {
+        const char *path;
+        bool tls = false, x509 = false, x509verify = false;
+        tls  = qemu_opt_get_bool(opts, "tls", false);
+        if (tls) {
+            path = qemu_opt_get(opts, "x509");
+            if (path) {
+                x509 = true;
+            } else {
+                path = qemu_opt_get(opts, "x509verify");
+                if (path) {
+                    x509 = true;
+                    x509verify = true;
+                }
+            }
+            vs->creds = vnc_display_create_creds(x509,
+                                                 x509verify,
+                                                 path,
+                                                 vs->id,
+                                                 errp);
+            if (!vs->creds) {
+                goto fail;
+            }
+        }
     }
-#else /* ! CONFIG_VNC_TLS */
-    if (tls) {
-        error_setg(errp, "VNC TLS auth requires gnutls support");
-        goto fail;
-    }
-#endif /* ! CONFIG_VNC_TLS */
-#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
     acl = qemu_opt_get_bool(opts, "acl", false);
-#endif
 
     share = qemu_opt_get(opts, "share");
     if (share) {
@@ -3520,19 +3539,14 @@ void vnc_display_open(const char *id, Error **errp)
         vs->non_adaptive = true;
     }
 
-#ifdef CONFIG_VNC_TLS
-    if (acl && x509 && vs->tls.x509verify) {
-        char *aclname;
-
+    if (acl) {
         if (strcmp(vs->id, "default") == 0) {
-            aclname = g_strdup("vnc.x509dname");
+            vs->tlsaclname = g_strdup("vnc.x509dname");
         } else {
-            aclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
+            vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
         }
-        vs->tls.acl = qemu_acl_init(aclname);
-        g_free(aclname);
+        qemu_acl_init(vs->tlsaclname);
     }
-#endif
 #ifdef CONFIG_VNC_SASL
     if (acl && sasl) {
         char *aclname;
@@ -3547,7 +3561,9 @@ void vnc_display_open(const char *id, Error **errp)
     }
 #endif
 
-    vnc_display_setup_auth(vs, password, sasl, tls, x509, websocket);
+    if (vnc_display_setup_auth(vs, password, sasl, websocket, errp) < 0) {
+        goto fail;
+    }
 
 #ifdef CONFIG_VNC_SASL
     if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
diff --git a/ui/vnc.h b/ui/vnc.h
index 593e6b6..008489b 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -35,6 +35,7 @@
 #include "qemu/bitmap.h"
 #include "io/buffer.h"
 #include "io/channel-socket.h"
+#include "io/channel-tls.h"
 #include <zlib.h>
 #include <stdbool.h>
 
@@ -96,10 +97,7 @@ typedef void VncSendHextileTile(VncState *vs,
 
 typedef struct VncDisplay VncDisplay;
 
-#ifdef CONFIG_VNC_TLS
-#include "vnc-tls.h"
 #include "vnc-auth-vencrypt.h"
-#endif
 #ifdef CONFIG_VNC_SASL
 #include "vnc-auth-sasl.h"
 #endif
@@ -178,9 +176,8 @@ struct VncDisplay
     bool ws_tls; /* Used by websockets */
     bool lossy;
     bool non_adaptive;
-#ifdef CONFIG_VNC_TLS
-    VncDisplayTLS tls;
-#endif
+    QCryptoTLSCreds *creds;
+    char *tlsaclname;
 #ifdef CONFIG_VNC_SASL
     VncDisplaySASL sasl;
 #endif
@@ -284,9 +281,7 @@ struct VncState
     int auth;
     int subauth; /* Used by VeNCrypt */
     char challenge[VNC_AUTH_CHALLENGE_SIZE];
-#ifdef CONFIG_VNC_TLS
-    VncStateTLS tls;
-#endif
+    QCryptoTLSSession *tls; /* Borrowed pointer from channel, don't free */
 #ifdef CONFIG_VNC_SASL
     VncStateSASL sasl;
 #endif
-- 
2.1.0

  parent reply	other threads:[~2015-04-17 14:26 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-17 14:22 [Qemu-devel] [PATCH v1 RFC 00/34] Generic support for TLS protocol & I/O channels Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 01/34] ui: remove check for failure of qemu_acl_init() Daniel P. Berrange
2015-04-17 15:56   ` Eric Blake
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 02/34] qom: document user creatable object types in help text Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 03/34] qom: create objects in two phases Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 04/34] qom: add object_new_propv / object_new_proplist constructors Daniel P. Berrange
2015-04-17 14:55   ` Paolo Bonzini
2015-04-17 15:16     ` Daniel P. Berrange
2015-04-17 16:11   ` Eric Blake
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 05/34] qom: make enum string tables const-correct Daniel P. Berrange
2015-04-17 14:56   ` Paolo Bonzini
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 06/34] qom: add a object_property_add_enum helper method Daniel P. Berrange
2015-04-17 14:56   ` Paolo Bonzini
2015-04-17 15:01     ` Paolo Bonzini
2015-04-17 15:11       ` Daniel P. Berrange
2015-04-17 15:19         ` Paolo Bonzini
2015-04-17 15:22           ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 07/34] qom: don't pass string table to object_get_enum method Daniel P. Berrange
2015-04-17 15:05   ` Paolo Bonzini
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 08/34] crypto: introduce new module for computing hash digests Daniel P. Berrange
2015-05-13 17:04   ` Daniel P. Berrange
2015-05-13 17:12     ` Paolo Bonzini
2015-05-13 17:21       ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 09/34] crypto: move built-in AES implementation into crypto/ Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 10/34] crypto: move built-in D3DES " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 11/34] crypto: introduce generic cipher API & built-in implementation Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 12/34] crypto: add a gcrypt cipher implementation Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 13/34] crypto: add a nettle " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 14/34] crypto: introduce new module for handling TLS credentials Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 15/34] crypto: add sanity checking of " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 16/34] crypto: introduce new module for handling TLS sessions Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 17/34] block: convert quorum blockdrv to use crypto APIs Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 18/34] ui: convert VNC websockets " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 19/34] block: convert qcow/qcow2 to use generic cipher API Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 20/34] ui: convert VNC " Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 21/34] io: add abstract QIOChannel classes Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 22/34] io: add helper module for creating watches on UNIX FDs Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 23/34] io: add QIOChannelSocket class Daniel P. Berrange
2015-04-17 15:28   ` Paolo Bonzini
2015-04-17 15:52     ` Daniel P. Berrange
2015-04-17 16:00       ` Paolo Bonzini
2015-04-20  7:18   ` Gerd Hoffmann
2015-04-23 12:31     ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 24/34] io: add QIOChannelFile class Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 25/34] io: add QIOTask class for async operations Daniel P. Berrange
2015-04-17 15:16   ` Paolo Bonzini
2015-04-17 15:49     ` Daniel P. Berrange
2015-04-17 15:57       ` Paolo Bonzini
2015-04-17 16:11         ` Daniel P. Berrange
2015-04-17 17:06           ` Paolo Bonzini
2015-04-17 17:38             ` Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 26/34] io: add QIOChannelTLS class Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 27/34] io: pull Buffer code out of VNC module Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 28/34] io: add QIOChannelWebsock class Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 29/34] ui: convert VNC server to use QEMUIOChannelSocket classes Daniel P. Berrange
2015-04-17 14:22 ` Daniel P. Berrange [this message]
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 31/34] ui: convert VNC server to use QIOChannelWebsock Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 32/34] char: convert from GIOChannel to QIOChannel Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 33/34] char: don't assume telnet initialization will not block Daniel P. Berrange
2015-04-17 14:22 ` [Qemu-devel] [PATCH v1 RFC 34/34] char: introduce support for TLS encrypted TCP chardev backend Daniel P. Berrange
2015-04-17 18:27   ` Eric Blake
2015-04-23 12:32     ` Daniel P. Berrange
2015-05-04 20:07   ` Kashyap Chamarthy
2015-05-05 13:49     ` Daniel P. Berrange
2015-05-05 13:53       ` Paolo Bonzini
2015-05-05 13:56         ` Daniel P. Berrange
2015-05-05 14:54       ` Kashyap Chamarthy
2015-05-06  8:34         ` Kashyap Chamarthy
2015-05-06 10:18           ` Daniel P. Berrange
2015-05-06 11:38             ` Kashyap Chamarthy
2015-04-23 12:28 ` [Qemu-devel] [PATCH v1 RFC 00/34] Generic support for TLS protocol & I/O channels Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1429280557-8887-31-git-send-email-berrange@redhat.com \
    --to=berrange@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).