]> git.proxmox.com Git - qemu.git/blobdiff - ui/vnc-ws.c
Update version for 1.7.0-rc1 release
[qemu.git] / ui / vnc-ws.c
index 3e3020916ce70d7102b4bfb81c52a34e864a1388..e304bafeb09ecf9f36fc07b694eaf0b1aad82656 100644 (file)
  */
 
 #include "vnc.h"
+#include "qemu/main-loop.h"
+
+#ifdef CONFIG_VNC_TLS
+#include "qemu/sockets.h"
+
+static void vncws_tls_handshake_io(void *opaque);
+
+static int vncws_start_tls_handshake(struct VncState *vs)
+{
+    int ret = gnutls_handshake(vs->ws_tls.session);
+
+    if (ret < 0) {
+        if (!gnutls_error_is_fatal(ret)) {
+            VNC_DEBUG("Handshake interrupted (blocking)\n");
+            if (!gnutls_record_get_direction(vs->ws_tls.session)) {
+                qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io,
+                                    NULL, vs);
+            } else {
+                qemu_set_fd_handler(vs->csock, NULL, vncws_tls_handshake_io,
+                                    vs);
+            }
+            return 0;
+        }
+        VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
+        vnc_client_error(vs);
+        return -1;
+    }
+
+    VNC_DEBUG("Handshake done, switching to TLS data mode\n");
+    vs->ws_tls.wiremode = VNC_WIREMODE_TLS;
+    qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs);
+
+    return 0;
+}
+
+static void vncws_tls_handshake_io(void *opaque)
+{
+    struct VncState *vs = (struct VncState *)opaque;
+
+    VNC_DEBUG("Handshake IO continue\n");
+    vncws_start_tls_handshake(vs);
+}
+
+void vncws_tls_handshake_peek(void *opaque)
+{
+    VncState *vs = opaque;
+    long ret;
+
+    if (!vs->ws_tls.session) {
+        char peek[4];
+        ret = qemu_recv(vs->csock, peek, sizeof(peek), MSG_PEEK);
+        if (ret && (strncmp(peek, "\x16", 1) == 0
+                    || strncmp(peek, "\x80", 1) == 0)) {
+            VNC_DEBUG("TLS Websocket connection recognized");
+            vnc_tls_client_setup(vs, 1);
+            vncws_start_tls_handshake(vs);
+        } else {
+            vncws_handshake_read(vs);
+        }
+    } else {
+        qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs);
+    }
+}
+#endif /* CONFIG_VNC_TLS */
 
 void vncws_handshake_read(void *opaque)
 {