mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 08:43:55 -06:00
ui: convert VNC websockets to use crypto APIs
Remove the direct use of gnutls for hash processing in the websockets code, in favour of using the crypto APIs. This allows the websockets code to be built unconditionally removing countless conditional checks from the VNC code. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-Id: <1435770638-25715-9-git-send-email-berrange@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
488981a4af
commit
8e9b0d24fb
6 changed files with 25 additions and 95 deletions
67
ui/vnc.c
67
ui/vnc.c
|
@ -40,6 +40,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "ui/input.h"
|
||||
#include "qapi-event.h"
|
||||
#include "crypto/hash.h"
|
||||
|
||||
#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
|
||||
#define VNC_REFRESH_INTERVAL_INC 50
|
||||
|
@ -355,9 +356,7 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
|
|||
info->base->host = g_strdup(host);
|
||||
info->base->service = g_strdup(serv);
|
||||
info->base->family = inet_netfamily(sa.ss_family);
|
||||
#ifdef CONFIG_VNC_WS
|
||||
info->base->websocket = client->websocket;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VNC_TLS
|
||||
if (client->tls.session && client->tls.dname) {
|
||||
|
@ -582,12 +581,10 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
|
|||
info->server = qmp_query_server_entry(vd->lsock, false,
|
||||
info->server);
|
||||
}
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (vd->lwebsock != -1) {
|
||||
info->server = qmp_query_server_entry(vd->lwebsock, true,
|
||||
info->server);
|
||||
}
|
||||
#endif
|
||||
|
||||
item = g_new0(VncInfo2List, 1);
|
||||
item->value = info;
|
||||
|
@ -1231,10 +1228,8 @@ void vnc_disconnect_finish(VncState *vs)
|
|||
|
||||
buffer_free(&vs->input);
|
||||
buffer_free(&vs->output);
|
||||
#ifdef CONFIG_VNC_WS
|
||||
buffer_free(&vs->ws_input);
|
||||
buffer_free(&vs->ws_output);
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
|
||||
qapi_free_VncClientInfo(vs->info);
|
||||
|
||||
|
@ -1413,12 +1408,9 @@ static void vnc_client_write_locked(void *opaque)
|
|||
} else
|
||||
#endif /* CONFIG_VNC_SASL */
|
||||
{
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (vs->encode_ws) {
|
||||
vnc_client_write_ws(vs);
|
||||
} else
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
{
|
||||
} else {
|
||||
vnc_client_write_plain(vs);
|
||||
}
|
||||
}
|
||||
|
@ -1429,11 +1421,7 @@ void vnc_client_write(void *opaque)
|
|||
VncState *vs = opaque;
|
||||
|
||||
vnc_lock_output(vs);
|
||||
if (vs->output.offset
|
||||
#ifdef CONFIG_VNC_WS
|
||||
|| vs->ws_output.offset
|
||||
#endif
|
||||
) {
|
||||
if (vs->output.offset || vs->ws_output.offset) {
|
||||
vnc_client_write_locked(opaque);
|
||||
} else if (vs->csock != -1) {
|
||||
qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
|
||||
|
@ -1539,7 +1527,6 @@ void vnc_client_read(void *opaque)
|
|||
ret = vnc_client_read_sasl(vs);
|
||||
else
|
||||
#endif /* CONFIG_VNC_SASL */
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (vs->encode_ws) {
|
||||
ret = vnc_client_read_ws(vs);
|
||||
if (ret == -1) {
|
||||
|
@ -1549,10 +1536,8 @@ void vnc_client_read(void *opaque)
|
|||
vnc_client_error(vs);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
{
|
||||
ret = vnc_client_read_plain(vs);
|
||||
} else {
|
||||
ret = vnc_client_read_plain(vs);
|
||||
}
|
||||
if (!ret) {
|
||||
if (vs->csock == -1)
|
||||
|
@ -1624,11 +1609,8 @@ void vnc_write_u8(VncState *vs, uint8_t value)
|
|||
void vnc_flush(VncState *vs)
|
||||
{
|
||||
vnc_lock_output(vs);
|
||||
if (vs->csock != -1 && (vs->output.offset
|
||||
#ifdef CONFIG_VNC_WS
|
||||
|| vs->ws_output.offset
|
||||
#endif
|
||||
)) {
|
||||
if (vs->csock != -1 && (vs->output.offset ||
|
||||
vs->ws_output.offset)) {
|
||||
vnc_client_write_locked(vs);
|
||||
}
|
||||
vnc_unlock_output(vs);
|
||||
|
@ -3019,7 +3001,6 @@ static void vnc_connect(VncDisplay *vd, int csock,
|
|||
VNC_DEBUG("New client on socket %d\n", csock);
|
||||
update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
|
||||
qemu_set_nonblock(vs->csock);
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (websocket) {
|
||||
vs->websocket = 1;
|
||||
#ifdef CONFIG_VNC_TLS
|
||||
|
@ -3031,7 +3012,6 @@ static void vnc_connect(VncDisplay *vd, int csock,
|
|||
qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs);
|
||||
}
|
||||
} else
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
{
|
||||
qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
|
||||
}
|
||||
|
@ -3040,10 +3020,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
|
|||
vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
|
||||
vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
|
||||
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (!vs->websocket)
|
||||
#endif
|
||||
{
|
||||
if (!vs->websocket) {
|
||||
vnc_init_state(vs);
|
||||
}
|
||||
|
||||
|
@ -3099,12 +3076,9 @@ static void vnc_listen_read(void *opaque, bool websocket)
|
|||
|
||||
/* Catch-up */
|
||||
graphic_hw_update(vs->dcl.con);
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (websocket) {
|
||||
csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
|
||||
} else
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
{
|
||||
} else {
|
||||
csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
|
||||
}
|
||||
|
||||
|
@ -3119,12 +3093,10 @@ static void vnc_listen_regular_read(void *opaque)
|
|||
vnc_listen_read(opaque, false);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VNC_WS
|
||||
static void vnc_listen_websocket_read(void *opaque)
|
||||
{
|
||||
vnc_listen_read(opaque, true);
|
||||
}
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
|
||||
static const DisplayChangeListenerOps dcl_ops = {
|
||||
.dpy_name = "vnc",
|
||||
|
@ -3150,9 +3122,7 @@ void vnc_display_init(const char *id)
|
|||
QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
|
||||
|
||||
vs->lsock = -1;
|
||||
#ifdef CONFIG_VNC_WS
|
||||
vs->lwebsock = -1;
|
||||
#endif
|
||||
|
||||
QTAILQ_INIT(&vs->clients);
|
||||
vs->expires = TIME_MAX;
|
||||
|
@ -3186,14 +3156,12 @@ static void vnc_display_close(VncDisplay *vs)
|
|||
close(vs->lsock);
|
||||
vs->lsock = -1;
|
||||
}
|
||||
#ifdef CONFIG_VNC_WS
|
||||
vs->ws_enabled = false;
|
||||
if (vs->lwebsock != -1) {
|
||||
qemu_set_fd_handler(vs->lwebsock, NULL, NULL, NULL);
|
||||
close(vs->lwebsock);
|
||||
vs->lwebsock = -1;
|
||||
}
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
vs->auth = VNC_AUTH_INVALID;
|
||||
vs->subauth = VNC_AUTH_INVALID;
|
||||
#ifdef CONFIG_VNC_TLS
|
||||
|
@ -3579,13 +3547,12 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
|
||||
websocket = qemu_opt_get(opts, "websocket");
|
||||
if (websocket) {
|
||||
#ifdef CONFIG_VNC_WS
|
||||
vs->ws_enabled = true;
|
||||
qemu_opt_set(wsopts, "port", websocket, &error_abort);
|
||||
#else /* ! CONFIG_VNC_WS */
|
||||
error_setg(errp, "Websockets protocol requires gnutls support");
|
||||
goto fail;
|
||||
#endif /* ! CONFIG_VNC_WS */
|
||||
if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
|
||||
error_setg(errp, "SHA1 hash support is required for websockets");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VNC_JPEG
|
||||
|
@ -3668,9 +3635,7 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
/* connect to viewer */
|
||||
int csock;
|
||||
vs->lsock = -1;
|
||||
#ifdef CONFIG_VNC_WS
|
||||
vs->lwebsock = -1;
|
||||
#endif
|
||||
if (strncmp(vnc, "unix:", 5) == 0) {
|
||||
csock = unix_connect(vnc+5, errp);
|
||||
} else {
|
||||
|
@ -3693,7 +3658,6 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
if (vs->lsock < 0) {
|
||||
goto fail;
|
||||
}
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (vs->ws_enabled) {
|
||||
vs->lwebsock = inet_listen_opts(wsopts, 0, errp);
|
||||
if (vs->lwebsock < 0) {
|
||||
|
@ -3704,16 +3668,13 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
}
|
||||
vs->enabled = true;
|
||||
qemu_set_fd_handler(vs->lsock, vnc_listen_regular_read, NULL, vs);
|
||||
#ifdef CONFIG_VNC_WS
|
||||
if (vs->ws_enabled) {
|
||||
qemu_set_fd_handler(vs->lwebsock, vnc_listen_websocket_read,
|
||||
NULL, vs);
|
||||
}
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
}
|
||||
qemu_opts_del(sopts);
|
||||
qemu_opts_del(wsopts);
|
||||
|
@ -3723,9 +3684,7 @@ fail:
|
|||
qemu_opts_del(sopts);
|
||||
qemu_opts_del(wsopts);
|
||||
vs->enabled = false;
|
||||
#ifdef CONFIG_VNC_WS
|
||||
vs->ws_enabled = false;
|
||||
#endif /* CONFIG_VNC_WS */
|
||||
}
|
||||
|
||||
void vnc_display_add_client(const char *id, int csock, bool skipauth)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue