[Qemu-devel] [PATCH v2] TLS support for VNC Websockets
Added TLS support to the VNC QEMU Websockets implementation. VNC-TLS needs to be enabled for this feature to be used. The required certificates are specified as in case of VNC-TLS with the VNC parameter x509=path. If the server certificate isn't signed by a rooth authority it needs to be manually imported in the browser because at least in case of Firefox and Chrome there is no user dialog, the connection just gets canceled. As a side note VEncrypt over Websocket doesn't work atm because TLS can't be stacked in the current implementation. (It also didn't work before) Nevertheless to my knowledge there is no HTML 5 VNC client which supports it and the Websocket connection can be encrypted with regular TLS now so it should be fine for most use cases. Signed-off-by: Tim Hardeck thard...@suse.de --- Changes v2 * a peek buffer of 4 Byte is enough --- qemu-options.hx | 2 ++ ui/vnc-tls.c| 61 +--- ui/vnc-ws.c | 63 ++ ui/vnc-ws.h | 3 ++ ui/vnc.c| 86 - ui/vnc.h| 5 +++- 6 files changed, 178 insertions(+), 42 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 7cd6002..e19db6f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1127,6 +1127,8 @@ 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}. @item password diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c index 8d4cc8e..50275de 100644 --- a/ui/vnc-tls.c +++ b/ui/vnc-tls.c @@ -334,29 +334,38 @@ static int vnc_set_gnutls_priority(gnutls_session_t s, int x509) int vnc_tls_client_setup(struct VncState *vs, int needX509Creds) { +VncStateTLS *tls; VNC_DEBUG(Do TLS setup\n); +#ifdef CONFIG_VNC_WS +if (vs-websocket) { +tls = vs-ws_tls; +} else +#endif /* CONFIG_VNC_WS */ +{ +tls = vs-tls; +} 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) { +if (tls-session == NULL) { +if (gnutls_init(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; +if (gnutls_set_default_priority(tls-session) 0) { +gnutls_deinit(tls-session); +tls-session = NULL; vnc_client_error(vs); return -1; } -if (vnc_set_gnutls_priority(vs-tls.session, needX509Creds) 0) { -gnutls_deinit(vs-tls.session); -vs-tls.session = NULL; +if (vnc_set_gnutls_priority(tls-session, needX509Creds) 0) { +gnutls_deinit(tls-session); +tls-session = NULL; vnc_client_error(vs); return -1; } @@ -364,43 +373,43 @@ int vnc_tls_client_setup(struct VncState *vs, 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; +gnutls_deinit(tls-session); +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; +if (gnutls_credentials_set(tls-session, GNUTLS_CRD_CERTIFICATE, x509_cred) 0) { +gnutls_deinit(tls-session); +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); +gnutls_certificate_server_set_request (tls-session, GNUTLS_CERT_REQUEST); } } else { gnutls_anon_server_credentials_t anon_cred = vnc_tls_initialize_anon_cred(); if (!anon_cred) { -gnutls_deinit(vs-tls.session); -vs-tls.session = NULL; +gnutls_deinit(tls-session); +tls-session = NULL; vnc_client_error(vs
Re: [Qemu-devel] [PATCH] Initial TLS support for VNC Websockets
Hi, did anybody had time yet to review my patch? Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH] Initial TLS support for VNC Websockets
Added TLS support to the VNC QEMU Websockets implementation. VNC-TLS needs to be enabled for this feature to be used. The required certificates are specified as in case of VNC-TLS with the VNC parameter x509=path. If the server certificate isn't signed by a rooth authority it needs to be manually imported in the browser because at least in case of Firefox and Chrome there is no user dialog, the connection just gets canceled. As a side note VEncrypt over Websocket doesn't work atm because TLS can't be stacked in the current implementation. (It also didn't work before) Nevertheless to my knowledge there is no HTML 5 VNC client which supports it and the Websocket connection can be encrypted with regular TLS now so it should be fine for most use cases. Signed-off-by: Tim Hardeck thard...@suse.de --- qemu-options.hx | 2 ++ ui/vnc-tls.c| 61 +--- ui/vnc-ws.c | 63 ++ ui/vnc-ws.h | 3 ++ ui/vnc.c| 86 - ui/vnc.h| 5 +++- 6 files changed, 178 insertions(+), 42 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 7cd6002..e19db6f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1127,6 +1127,8 @@ 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}. @item password diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c index 8d4cc8e..50275de 100644 --- a/ui/vnc-tls.c +++ b/ui/vnc-tls.c @@ -334,29 +334,38 @@ static int vnc_set_gnutls_priority(gnutls_session_t s, int x509) int vnc_tls_client_setup(struct VncState *vs, int needX509Creds) { +VncStateTLS *tls; VNC_DEBUG(Do TLS setup\n); +#ifdef CONFIG_VNC_WS +if (vs-websocket) { +tls = vs-ws_tls; +} else +#endif /* CONFIG_VNC_WS */ +{ +tls = vs-tls; +} 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) { +if (tls-session == NULL) { +if (gnutls_init(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; +if (gnutls_set_default_priority(tls-session) 0) { +gnutls_deinit(tls-session); +tls-session = NULL; vnc_client_error(vs); return -1; } -if (vnc_set_gnutls_priority(vs-tls.session, needX509Creds) 0) { -gnutls_deinit(vs-tls.session); -vs-tls.session = NULL; +if (vnc_set_gnutls_priority(tls-session, needX509Creds) 0) { +gnutls_deinit(tls-session); +tls-session = NULL; vnc_client_error(vs); return -1; } @@ -364,43 +373,43 @@ int vnc_tls_client_setup(struct VncState *vs, 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; +gnutls_deinit(tls-session); +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; +if (gnutls_credentials_set(tls-session, GNUTLS_CRD_CERTIFICATE, x509_cred) 0) { +gnutls_deinit(tls-session); +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); +gnutls_certificate_server_set_request (tls-session, GNUTLS_CERT_REQUEST); } } else { gnutls_anon_server_credentials_t anon_cred = vnc_tls_initialize_anon_cred(); if (!anon_cred) { -gnutls_deinit(vs-tls.session); -vs-tls.session = NULL; +gnutls_deinit(tls-session); +tls-session = NULL; vnc_client_error(vs); return -1
Re: [Qemu-devel] VNC Websocket TLS support design decisions
Hi, I have sent in my current implementation some minutes ago. On 04/11/2013 03:33 PM, Tim Hardeck wrote: Websockets over TLS need certificates. We already have the x509 vnc parameter for VNC-TLS to provide the certificates but user might have one webserver certificate and one for VNC TLS authentication. Of course in this case they could use two vnc instances. The other issue is that Websockets TLS should work when vnc-tls is disabled since GnuTLS is already a requirement for Websockets anyway. Should I use this x509 certificate parameter also or add an additional parameter like ws_x509? In my current implementation the general x509 vnc parameter is used to provide the path for the certificates. Should there be an option to only allow Websockets over TLS? For example how to react in case of the option tls=1. In my current implementation the Websocket connection is checked during initiation for an encryption handshake and and then acted accordingly. If tls is specified Websockets can't be used because VEncrypt is enforced then which is not supported by noVNC. In general VNC TLS is decrypted before the Websocket decoding so it can't be stacked atm. I don't think that it is needed anyway since there is Websocket TLS support now but there might be HTML 5 clients with VEncrypt support in the future. I haven't added any option to only allow encrypted Websockets connections [yet]. Let me know if this is worth adding another VNC option. To my knowledge current HTML5 VNC clients do not support another authentication then password, so no VEncrypt. This means that if I enable tls=1 Websockets connection can't be established for this vnc instance. Should I add some workaround to use password authentication for Websockets or just document it so users could use two vnc instances for this use case? If tls=1 is specified noVNC shows the message that this security type is not supported which should be fine I suppose. For my implementation I am using many parts of vnc-tls. I am planning to make some functions in vnc-tls more flexible or add some checks to allow them to be used for Websocket TLS connections. Would this be OK or do you have other suggestions. I got rid of all duplicates except of the functions regarding the TLS handshake which I imported from vnc-auth-vencrypt.c. Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/
[Qemu-devel] VNC Websocket TLS support design decisions
Hi, I am working on TLS support for VNC Websockets in QEMU and while I already got it working I need to make some design decisions. Websockets over TLS need certificates. We already have the x509 vnc parameter for VNC-TLS to provide the certificates but user might have one webserver certificate and one for VNC TLS authentication. Of course in this case they could use two vnc instances. The other issue is that Websockets TLS should work when vnc-tls is disabled since GnuTLS is already a requirement for Websockets anyway. Should I use this x509 certificate parameter also or add an additional parameter like ws_x509? Should there be an option to only allow Websockets over TLS? For example how to react in case of the option tls=1. In my current implementation the Websocket connection is checked during initiation for an encryption handshake and and then acted accordingly. To my knowledge current HTML5 VNC clients do not support another authentication then password, so no VEncrypt. This means that if I enable tls=1 Websockets connection can't be established for this vnc instance. Should I add some workaround to use password authentication for Websockets or just document it so users could use two vnc instances for this use case? For my implementation I am using many parts of vnc-tls. I am planning to make some functions in vnc-tls more flexible or add some checks to allow them to be used for Websocket TLS connections. Would this be OK or do you have other suggestions. Thanks in advance Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/
Re: [Qemu-devel] [PATCH] vnc-tls: Fix compilation with newer versions of GNU-TLS
Hi, On Thu, 2012-10-18 at 11:23 +0200, Gerd Hoffmann wrote: On 10/18/12 11:16, Andre Przywara wrote: In my installation of GNU-TLS (v3.0.23) the type gnutls_anon_server_credentials is marked deprecated, so -Werror breaks compilation. Simply replacing it with the newer ..._t version fixed the compilation on my machine (Slackware 14.0). I cannot tell how far back this new type goes, at least the header file in RHEL 5.0 (v1.4.1) seems to have it already. If someone finds a broken distribution, tell me and I insert some compat code. Acked-by: Gerd Hoffmann kra...@redhat.com is there a reason why this wasn't applied yet? Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/
Re: [Qemu-devel] [PATCH] vnc: Clean up vncws_send_handshake_response()
Hi Markus, thanks for your input. On Wed, 2013-01-23 at 18:16 +0100, Markus Armbruster wrote: Use appropriate types, drop superfluous casts, use sizeof, don't exploit that this particular call of gnutls_fingerprint() doesn't change its last argument. your patch does work fine but if we expect gnutls_fingerprint to change the hash_size there has to be an additional check if the hash_size is bigger than SHA1_DIGEST_LEN. For example: diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index de7e74c..e64c895 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -132,7 +132,7 @@ static void vncws_send_handshake_response(VncState *vs, const char* key) in.data = (void *)combined_key; in.size = WS_CLIENT_KEY_LEN + WS_GUID_LEN; if (gnutls_fingerprint(GNUTLS_DIG_SHA1, in, hash, hash_size) -== GNUTLS_E_SUCCESS) { +== GNUTLS_E_SUCCESS hash_size = SHA1_DIGEST_LEN) { accept = g_base64_encode(hash, hash_size); } if (accept == NULL) { -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: This is a digitally signed message part
Re: [Qemu-devel] [PATCH] vnc: Clean up vncws_send_handshake_response()
Hi Markus, On 01/23/2013 06:16 PM, Markus Armbruster wrote: Use appropriate types, drop superfluous casts, use sizeof, don't exploit that this particular call of gnutls_fingerprint() doesn't change its last argument. Signed-off-by: Markus Armbruster arm...@redhat.com Reviewed-by: Tim Hardeck thard...@suse.de Regards Tim --- ui/vnc-ws.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 9ccdc19..de7e74c 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -120,8 +120,8 @@ static char *vncws_extract_handshake_entry(const char *handshake, static void vncws_send_handshake_response(VncState *vs, const char* key) { char combined_key[WS_CLIENT_KEY_LEN + WS_GUID_LEN + 1]; -char hash[SHA1_DIGEST_LEN]; -size_t hash_size = SHA1_DIGEST_LEN; +unsigned char hash[SHA1_DIGEST_LEN]; +size_t hash_size = sizeof(hash); char *accept = NULL, *response = NULL; gnutls_datum_t in; @@ -133,7 +133,7 @@ static void vncws_send_handshake_response(VncState *vs, const char* key) in.size = WS_CLIENT_KEY_LEN + WS_GUID_LEN; if (gnutls_fingerprint(GNUTLS_DIG_SHA1, in, hash, hash_size) == GNUTLS_E_SUCCESS) { -accept = g_base64_encode((guchar *)hash, SHA1_DIGEST_LEN); +accept = g_base64_encode(hash, hash_size); } if (accept == NULL) { VNC_DEBUG(Hashing Websocket combined key failed\n); -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH 0/3 v7] vnc: added initial websocket protocol support
This patch set adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocket is used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Changes v2 * removed automatic websocket recognition * added new lwebsock socket on port 5700 + display when the vnc option websocket is passed on * adapted vnc_connect vnc_listen_read to differ between websocket * added separate event handler to read the Websocket handshake Changes v3 * added manual port specification by using ,websocket=port * switched from memmem() to g_strstr_len() * removed masked_size from vncws_decode_frame() * resetted vnc_tls variable to default in the configure script Changes v4 * incorporated suggestions from Stefan Hajnoczi * moved websockets encoding from vnc_write to its own client_write function * moved websockets decoding to its own client_read function * added initialization checks to vnc_disconnect to prevent crashes if a regular client connects to the websocket port Changes v5 * added initialized variable to VncState to prevent crashes during vnc_disconnect - the previously added initialization checks didn't prevent segfaults when a websocket client was connected Changes v6 * incorporated suggestions from Blue Swirl * updated vncws_handshake_read to check for the header end tag and to not reset the buffer afterwards Changes v7 * fixed vnc-ws header define Tim Hardeck (3): vnc: added buffer_advance function vnc: added initial websocket protocol support vnc: fix possible uninitialized removals configure| 27 +- qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 284 ++ ui/vnc-ws.h | 86 + ui/vnc.c | 211 +++- ui/vnc.h | 21 7 files changed, 610 insertions(+), 28 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h -- 1.7.10.4
[Qemu-devel] [PATCH 2/3] vnc: added initial websocket protocol support
This patch adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocketis used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Parts of the implementation base on Anthony Liguori's QEMU Websocket patch from 2010 and on Joel Martin's LibVNC Websocket implementation. Signed-off-by: Tim Hardeck thard...@suse.de --- configure| 27 +- qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 284 ++ ui/vnc-ws.h | 86 + ui/vnc.c | 187 +++ ui/vnc.h | 19 7 files changed, 591 insertions(+), 21 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h diff --git a/configure b/configure index 837a84a..ac3198c 100755 --- a/configure +++ b/configure @@ -158,6 +158,7 @@ vnc_tls= vnc_sasl= vnc_jpeg= vnc_png= +vnc_ws= xen= xen_ctrl_version= xen_pci_passthrough= @@ -715,6 +716,10 @@ for opt do ;; --enable-vnc-png) vnc_png=yes ;; + --disable-vnc-ws) vnc_ws=no + ;; + --enable-vnc-ws) vnc_ws=yes + ;; --disable-slirp) slirp=no ;; --disable-uuid) uuid=no @@ -1064,6 +1069,8 @@ echo --disable-vnc-jpeg disable JPEG lossy compression for VNC server echo --enable-vnc-jpegenable JPEG lossy compression for VNC server echo --disable-vnc-pngdisable PNG compression for VNC server (default) echo --enable-vnc-png enable PNG compression for VNC server +echo --disable-vnc-ws disable Websockets support for VNC server +echo --enable-vnc-ws enable Websockets support for VNC server echo --disable-curses disable curses output echo --enable-curses enable curses output echo --disable-curl disable curl connectivity @@ -1707,8 +1714,8 @@ EOF fi ## -# VNC TLS detection -if test $vnc = yes -a $vnc_tls != no ; then +# VNC TLS/WS detection +if test $vnc = yes -a \( $vnc_tls != no -o $vnc_ws != no \) ; then cat $TMPC EOF #include gnutls/gnutls.h int main(void) { gnutls_session_t s; gnutls_init(s, GNUTLS_SERVER); return 0; } @@ -1716,14 +1723,23 @@ 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 -vnc_tls=yes +if test $vnc_tls != no ; then + vnc_tls=yes +fi +if test $vnc_ws != no ; then + vnc_ws=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 fi +if test $vnc_ws = yes ; then + feature_not_found vnc-ws +fi vnc_tls=no +vnc_ws=no fi fi @@ -3263,6 +3279,7 @@ if test $vnc = yes ; then echo VNC SASL support $vnc_sasl echo VNC JPEG support $vnc_jpeg echo VNC PNG support $vnc_png +echo VNC WS support$vnc_ws fi if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu @@ -3437,6 +3454,10 @@ fi if test $vnc_png = yes ; then echo CONFIG_VNC_PNG=y $config_host_mak fi +if test $vnc_ws = yes ; then + echo CONFIG_VNC_WS=y $config_host_mak + echo VNC_WS_CFLAGS=$vnc_ws_cflags $config_host_mak +fi if test $fnmatch = yes ; then echo CONFIG_FNMATCH=y $config_host_mak fi diff --git a/qemu-options.hx b/qemu-options.hx index 9df0cde..38ff002 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1096,6 +1096,14 @@ client is specified by the @var{display}. For reverse network connections (@var{host}:@var{d},@code{reverse}), the @var{d} argument is a TCP port number, not a display number. +@item websocket + +Opens an additional TCP listening port dedicated to VNC Websocket connections. +By defintion 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}. + @item password Require that password based authentication is used for client connections. diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 6768bb7..d9db073 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -4,6 +4,7 @@ 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-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o +vnc-obj-$(CONFIG_VNC_WS) += vnc-ws.o vnc-obj-y += vnc-jobs.o common-obj-y += keymaps.o console.o
[Qemu-devel] [PATCH 1/3] vnc: added buffer_advance function
Following Anthony Liguori's Websocket implementation I have added the buffer_advance function to VNC and replaced all related buffer memmove operations with it. Signed-off-by: Tim Hardeck thard...@suse.de Reviewed-by: Anthony Liguori aligu...@us.ibm.com --- ui/vnc.c | 13 + ui/vnc.h |1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 8912b78..ddf01f1 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -510,6 +510,13 @@ void buffer_append(Buffer *buffer, const void *data, size_t len) buffer-offset += len; } +void buffer_advance(Buffer *buf, size_t len) +{ +memmove(buf-buffer, buf-buffer + len, +(buf-offset - len)); +buf-offset -= len; +} + static void vnc_desktop_resize(VncState *vs) { DisplayState *ds = vs-ds; @@ -1166,8 +1173,7 @@ static long vnc_client_write_plain(VncState *vs) if (!ret) return 0; -memmove(vs-output.buffer, vs-output.buffer + ret, (vs-output.offset - ret)); -vs-output.offset -= ret; +buffer_advance(vs-output, ret); if (vs-output.offset == 0) { qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, vs); @@ -1313,8 +1319,7 @@ void vnc_client_read(void *opaque) } if (!ret) { -memmove(vs-input.buffer, vs-input.buffer + len, (vs-input.offset - len)); -vs-input.offset -= len; +buffer_advance(vs-input, len); } else { vs-read_handler_expect = ret; } diff --git a/ui/vnc.h b/ui/vnc.h index 8b40f09..5059cbe 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -510,6 +510,7 @@ void buffer_reserve(Buffer *buffer, size_t len); void buffer_reset(Buffer *buffer); void buffer_free(Buffer *buffer); void buffer_append(Buffer *buffer, const void *data, size_t len); +void buffer_advance(Buffer *buf, size_t len); /* Misc helpers */ -- 1.7.10.4
[Qemu-devel] [PATCH 3/3] vnc: fix possible uninitialized removals
Some VncState values are not initialized before the Websocket handshake. If it fails QEMU segfaults during the cleanup. To prevent this behavior intialization checks are added. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c | 11 --- ui/vnc.h |1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index ee08894..ff4e2ae 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1053,20 +1053,24 @@ void vnc_disconnect_finish(VncState *vs) audio_del(vs); vnc_release_modifiers(vs); -QTAILQ_REMOVE(vs-vd-clients, vs, next); +if (vs-initialized) { +QTAILQ_REMOVE(vs-vd-clients, vs, next); +qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); +} if (QTAILQ_EMPTY(vs-vd-clients)) { dcl-idle = 1; } -qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); vnc_remove_timer(vs-vd); if (vs-vd-lock_key_sync) qemu_remove_led_event_handler(vs-led); vnc_unlock_output(vs); qemu_mutex_destroy(vs-output_mutex); -qemu_bh_delete(vs-bh); +if (vs-bh != NULL) { +qemu_bh_delete(vs-bh); +} buffer_free(vs-jobs_buffer); for (i = 0; i VNC_STAT_ROWS; ++i) { @@ -2749,6 +2753,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket) void vnc_init_state(VncState *vs) { +vs-initialized = true; VncDisplay *vd = vs-vd; vs-ds = vd-ds; diff --git a/ui/vnc.h b/ui/vnc.h index f93c89a..45d7686 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -306,6 +306,7 @@ struct VncState QEMUPutLEDEntry *led; bool abort; +bool initialized; QemuMutex output_mutex; QEMUBH *bh; Buffer jobs_buffer; -- 1.7.10.4
Re: [Qemu-devel] [PATCH 2/3] vnc: added initial websocket protocol support
On 01/08/2013 01:38 AM, Anthony Liguori wrote: Better, but I still think it's better to advance the buffer based on the parsed header sizes that to assume there's no additional data. I have used buffer_advance in the patch set v6. Does anything else need to be changed? Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH 0/3 v6] vnc: added initial websocket protocol support
This patch set adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocket is used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Changes v2 * removed automatic websocket recognition * added new lwebsock socket on port 5700 + display when the vnc option websocket is passed on * adapted vnc_connect vnc_listen_read to differ between websocket * added separate event handler to read the Websocket handshake Changes v3 * added manual port specification by using ,websocket=port * switched from memmem() to g_strstr_len() * removed masked_size from vncws_decode_frame() * resetted vnc_tls variable to default in the configure script Changes v4 * incorporated suggestions from Stefan Hajnoczi * moved websockets encoding from vnc_write to its own client_write function * moved websockets decoding to its own client_read function * added initialization checks to vnc_disconnect to prevent crashes if a regular client connects to the websocket port Changes v5 * added initialized variable to VncState to prevent crashes during vnc_disconnect - the previously added initialization checks didn't prevent segfaults when a websocket client was connected Changes v6 * incorporated suggestions from Blue Swirl * updated vncws_handshake_read to check for the header end tag and to not reset the buffer afterwards Tim Hardeck (3): vnc: added buffer_advance function vnc: added initial websocket protocol support vnc: fix possible uninitialized removals configure| 27 +- qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 284 ++ ui/vnc-ws.h | 86 + ui/vnc.c | 211 +++- ui/vnc.h | 21 7 files changed, 610 insertions(+), 28 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h -- 1.7.10.4
[Qemu-devel] [PATCH 1/3] vnc: added buffer_advance function
Following Anthony Liguori's Websocket implementation I have added the buffer_advance function to VNC and replaced all related buffer memmove operations with it. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c | 13 + ui/vnc.h |1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 8912b78..ddf01f1 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -510,6 +510,13 @@ void buffer_append(Buffer *buffer, const void *data, size_t len) buffer-offset += len; } +void buffer_advance(Buffer *buf, size_t len) +{ +memmove(buf-buffer, buf-buffer + len, +(buf-offset - len)); +buf-offset -= len; +} + static void vnc_desktop_resize(VncState *vs) { DisplayState *ds = vs-ds; @@ -1166,8 +1173,7 @@ static long vnc_client_write_plain(VncState *vs) if (!ret) return 0; -memmove(vs-output.buffer, vs-output.buffer + ret, (vs-output.offset - ret)); -vs-output.offset -= ret; +buffer_advance(vs-output, ret); if (vs-output.offset == 0) { qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, vs); @@ -1313,8 +1319,7 @@ void vnc_client_read(void *opaque) } if (!ret) { -memmove(vs-input.buffer, vs-input.buffer + len, (vs-input.offset - len)); -vs-input.offset -= len; +buffer_advance(vs-input, len); } else { vs-read_handler_expect = ret; } diff --git a/ui/vnc.h b/ui/vnc.h index 8b40f09..5059cbe 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -510,6 +510,7 @@ void buffer_reserve(Buffer *buffer, size_t len); void buffer_reset(Buffer *buffer); void buffer_free(Buffer *buffer); void buffer_append(Buffer *buffer, const void *data, size_t len); +void buffer_advance(Buffer *buf, size_t len); /* Misc helpers */ -- 1.7.10.4
[Qemu-devel] [PATCH 3/3] vnc: fix possible uninitialized removals
Some VncState values are not initialized before the Websocket handshake. If it fails QEMU segfaults during the cleanup. To prevent this behavior intialization checks are added. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c | 11 --- ui/vnc.h |1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index ee08894..ff4e2ae 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1053,20 +1053,24 @@ void vnc_disconnect_finish(VncState *vs) audio_del(vs); vnc_release_modifiers(vs); -QTAILQ_REMOVE(vs-vd-clients, vs, next); +if (vs-initialized) { +QTAILQ_REMOVE(vs-vd-clients, vs, next); +qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); +} if (QTAILQ_EMPTY(vs-vd-clients)) { dcl-idle = 1; } -qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); vnc_remove_timer(vs-vd); if (vs-vd-lock_key_sync) qemu_remove_led_event_handler(vs-led); vnc_unlock_output(vs); qemu_mutex_destroy(vs-output_mutex); -qemu_bh_delete(vs-bh); +if (vs-bh != NULL) { +qemu_bh_delete(vs-bh); +} buffer_free(vs-jobs_buffer); for (i = 0; i VNC_STAT_ROWS; ++i) { @@ -2749,6 +2753,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket) void vnc_init_state(VncState *vs) { +vs-initialized = true; VncDisplay *vd = vs-vd; vs-ds = vd-ds; diff --git a/ui/vnc.h b/ui/vnc.h index f93c89a..45d7686 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -306,6 +306,7 @@ struct VncState QEMUPutLEDEntry *led; bool abort; +bool initialized; QemuMutex output_mutex; QEMUBH *bh; Buffer jobs_buffer; -- 1.7.10.4
[Qemu-devel] [PATCH 2/3] vnc: added initial websocket protocol support
This patch adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocketis used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Parts of the implementation base on Anthony Liguori's QEMU Websocket patch from 2010 and on Joel Martin's LibVNC Websocket implementation. Signed-off-by: Tim Hardeck thard...@suse.de --- configure| 27 +- qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 284 ++ ui/vnc-ws.h | 86 + ui/vnc.c | 187 +++ ui/vnc.h | 19 7 files changed, 591 insertions(+), 21 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h diff --git a/configure b/configure index 837a84a..ac3198c 100755 --- a/configure +++ b/configure @@ -158,6 +158,7 @@ vnc_tls= vnc_sasl= vnc_jpeg= vnc_png= +vnc_ws= xen= xen_ctrl_version= xen_pci_passthrough= @@ -715,6 +716,10 @@ for opt do ;; --enable-vnc-png) vnc_png=yes ;; + --disable-vnc-ws) vnc_ws=no + ;; + --enable-vnc-ws) vnc_ws=yes + ;; --disable-slirp) slirp=no ;; --disable-uuid) uuid=no @@ -1064,6 +1069,8 @@ echo --disable-vnc-jpeg disable JPEG lossy compression for VNC server echo --enable-vnc-jpegenable JPEG lossy compression for VNC server echo --disable-vnc-pngdisable PNG compression for VNC server (default) echo --enable-vnc-png enable PNG compression for VNC server +echo --disable-vnc-ws disable Websockets support for VNC server +echo --enable-vnc-ws enable Websockets support for VNC server echo --disable-curses disable curses output echo --enable-curses enable curses output echo --disable-curl disable curl connectivity @@ -1707,8 +1714,8 @@ EOF fi ## -# VNC TLS detection -if test $vnc = yes -a $vnc_tls != no ; then +# VNC TLS/WS detection +if test $vnc = yes -a \( $vnc_tls != no -o $vnc_ws != no \) ; then cat $TMPC EOF #include gnutls/gnutls.h int main(void) { gnutls_session_t s; gnutls_init(s, GNUTLS_SERVER); return 0; } @@ -1716,14 +1723,23 @@ 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 -vnc_tls=yes +if test $vnc_tls != no ; then + vnc_tls=yes +fi +if test $vnc_ws != no ; then + vnc_ws=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 fi +if test $vnc_ws = yes ; then + feature_not_found vnc-ws +fi vnc_tls=no +vnc_ws=no fi fi @@ -3263,6 +3279,7 @@ if test $vnc = yes ; then echo VNC SASL support $vnc_sasl echo VNC JPEG support $vnc_jpeg echo VNC PNG support $vnc_png +echo VNC WS support$vnc_ws fi if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu @@ -3437,6 +3454,10 @@ fi if test $vnc_png = yes ; then echo CONFIG_VNC_PNG=y $config_host_mak fi +if test $vnc_ws = yes ; then + echo CONFIG_VNC_WS=y $config_host_mak + echo VNC_WS_CFLAGS=$vnc_ws_cflags $config_host_mak +fi if test $fnmatch = yes ; then echo CONFIG_FNMATCH=y $config_host_mak fi diff --git a/qemu-options.hx b/qemu-options.hx index 9df0cde..38ff002 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1096,6 +1096,14 @@ client is specified by the @var{display}. For reverse network connections (@var{host}:@var{d},@code{reverse}), the @var{d} argument is a TCP port number, not a display number. +@item websocket + +Opens an additional TCP listening port dedicated to VNC Websocket connections. +By defintion 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}. + @item password Require that password based authentication is used for client connections. diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 6768bb7..d9db073 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -4,6 +4,7 @@ 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-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o +vnc-obj-$(CONFIG_VNC_WS) += vnc-ws.o vnc-obj-y += vnc-jobs.o common-obj-y += keymaps.o console.o
Re: [Qemu-devel] [PATCH 2/3] vnc: added initial websocket protocol support
Hi Anthony, thanks for your feedback. On Mon, 2013-01-07 at 13:52 -0600, Anthony Liguori wrote: Tim Hardeck thard...@suse.de writes: +void vncws_handshake_read(void *opaque) +{ +VncState *vs = opaque; +long ret; +buffer_reserve(vs-ws_input, 4096); +ret = vnc_client_read_buf(vs, buffer_end(vs-ws_input), 4096); + +if (!ret) { +if (vs-csock == -1) { +vnc_disconnect_finish(vs); +} +return; +} +vs-ws_input.offset += ret; + +if (vs-ws_input.offset 0) { +qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, vs); +vncws_process_handshake(vs, vs-ws_input.buffer, vs-ws_input.offset); +buffer_reset(vs-ws_input); This is making a bad assumption. You're assuming that vnc_client_read_buf() is always going to return at least the amount of data you need to do the handshake and never any more data. Following the Websocket protocol specification there shouldn't be more data until a handshake response from the server. You need something more sophisticated that keeps reading data until you've gotten the complete set of headers and the trailing double EOL. How about that: diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 6b98d6b..298bc20 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -35,7 +35,8 @@ void vncws_handshake_read(void *opaque) } vs-ws_input.offset += ret; -if (vs-ws_input.offset 0) { +if (g_strstr_len((char *)vs-ws_input.buffer, vs-ws_input.offset, +WS_HANDSHAKE_END)) { qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs-ws_input.buffer, vs-ws_input.offset); buffer_reset(vs-ws_input); diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h index 7402e77..c8dfe34 100644 --- a/ui/vnc-ws.h +++ b/ui/vnc-ws.h @@ -38,6 +38,7 @@ Sec-WebSocket-Accept: %s\r\n\ Sec-WebSocket-Protocol: binary\r\n\ \r\n #define WS_HANDSHAKE_DELIM \r\n +#define WS_HANDSHAKE_END \r\n\r\n #define WS_SUPPORTED_VERSION 13 #define WS_HEAD_MIN_LEN sizeof(uint16_t) We also could calculate the handshake size and use buffer_advance instead but since there shouldn't be any additional data received from the client until a server response anyway I would prefer it this way. +long vnc_client_read_ws(VncState *vs) +{ +int ret, err; +uint8_t *payload; +size_t payload_size, frame_size; +VNC_DEBUG(Read websocket %p size %zd offset %zd\n, vs-ws_input.buffer, +vs-ws_input.capacity, vs-ws_input.offset); +buffer_reserve(vs-ws_input, 4096); +ret = vnc_client_read_buf(vs, buffer_end(vs-ws_input), 4096); +if (!ret) { +return 0; +} +vs-ws_input.offset += ret; + +/* make sure that nothing is left in the ws_input buffer */ +do { +err = vncws_decode_frame(vs-ws_input, payload, + payload_size, frame_size); +if (err = 0) { +return err; +} + +buffer_reserve(vs-input, payload_size); +buffer_append(vs-input, payload, payload_size); + +buffer_advance(vs-ws_input, frame_size); +} while (vs-ws_input.offset 0); This likewise seems wrong. What happens if you get a read of a partial frame? This code will fail, no? In case of a partial frame err would be 0 and QEMU would wait for more data until processing. Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: This is a digitally signed message part
Re: [Qemu-devel] [PATCH 2/3] vnc: added initial websocket protocol support
Hi, thanks for your suggestions. On Fri, 2013-01-04 at 20:20 +, Blue Swirl wrote: On Wed, Jan 2, 2013 at 1:29 PM, Tim Hardeck thard...@suse.de wrote: + * We are working around a bug present in GCC 4.6 which prevented + * it from recognizing anonymous structs and unions. + * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4784 + */ +typedef struct __attribute__ ((__packed__)) ws_header_s { Please use QEMU_PACKED. +unsigned char b0; +unsigned char b1; +union { +struct __attribute__ ((__packed__)) { I think individual items inside a packed struct are automatically packed. According to http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Type-Attributes.html the packed attribute should work like you suggest but if I don't add QEMU_PACKED to the member structs too I get decoding issues. I have incorporated everything else in my new patch set but am going to wait for more feedback. Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: This is a digitally signed message part
[Qemu-devel] [PATCH 3/3] vnc: fix possible uninitialized removals
Some VncState values are not initialized before the Websocket handshake. If it fails QEMU segfaults during the cleanup. To prevent this behavior intialization checks are added. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c | 11 --- ui/vnc.h |1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index ee08894..ff4e2ae 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1053,20 +1053,24 @@ void vnc_disconnect_finish(VncState *vs) audio_del(vs); vnc_release_modifiers(vs); -QTAILQ_REMOVE(vs-vd-clients, vs, next); +if (vs-initialized) { +QTAILQ_REMOVE(vs-vd-clients, vs, next); +qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); +} if (QTAILQ_EMPTY(vs-vd-clients)) { dcl-idle = 1; } -qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); vnc_remove_timer(vs-vd); if (vs-vd-lock_key_sync) qemu_remove_led_event_handler(vs-led); vnc_unlock_output(vs); qemu_mutex_destroy(vs-output_mutex); -qemu_bh_delete(vs-bh); +if (vs-bh != NULL) { +qemu_bh_delete(vs-bh); +} buffer_free(vs-jobs_buffer); for (i = 0; i VNC_STAT_ROWS; ++i) { @@ -2749,6 +2753,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket) void vnc_init_state(VncState *vs) { +vs-initialized = true; VncDisplay *vd = vs-vd; vs-ds = vd-ds; diff --git a/ui/vnc.h b/ui/vnc.h index f93c89a..45d7686 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -306,6 +306,7 @@ struct VncState QEMUPutLEDEntry *led; bool abort; +bool initialized; QemuMutex output_mutex; QEMUBH *bh; Buffer jobs_buffer; -- 1.7.10.4
[Qemu-devel] [PATCH 1/3] vnc: added buffer_advance function
Following Anthony Liguori's Websocket implementation I have added the buffer_advance function to VNC and replaced all related buffer memmove operations with it. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c | 13 + ui/vnc.h |1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 8912b78..ddf01f1 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -510,6 +510,13 @@ void buffer_append(Buffer *buffer, const void *data, size_t len) buffer-offset += len; } +void buffer_advance(Buffer *buf, size_t len) +{ +memmove(buf-buffer, buf-buffer + len, +(buf-offset - len)); +buf-offset -= len; +} + static void vnc_desktop_resize(VncState *vs) { DisplayState *ds = vs-ds; @@ -1166,8 +1173,7 @@ static long vnc_client_write_plain(VncState *vs) if (!ret) return 0; -memmove(vs-output.buffer, vs-output.buffer + ret, (vs-output.offset - ret)); -vs-output.offset -= ret; +buffer_advance(vs-output, ret); if (vs-output.offset == 0) { qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, vs); @@ -1313,8 +1319,7 @@ void vnc_client_read(void *opaque) } if (!ret) { -memmove(vs-input.buffer, vs-input.buffer + len, (vs-input.offset - len)); -vs-input.offset -= len; +buffer_advance(vs-input, len); } else { vs-read_handler_expect = ret; } diff --git a/ui/vnc.h b/ui/vnc.h index 8b40f09..5059cbe 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -510,6 +510,7 @@ void buffer_reserve(Buffer *buffer, size_t len); void buffer_reset(Buffer *buffer); void buffer_free(Buffer *buffer); void buffer_append(Buffer *buffer, const void *data, size_t len); +void buffer_advance(Buffer *buf, size_t len); /* Misc helpers */ -- 1.7.10.4
[Qemu-devel] [PATCH 0/3 v5] vnc: added initial websocket protocol support
This patch set adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocket is used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Changes v2 * removed automatic websocket recognition * added new lwebsock socket on port 5700 + display when the vnc option websocket is passed on * adapted vnc_connect vnc_listen_read to differ between websocket * added separate event handler to read the Websocket handshake Changes v3 * added manual port specification by using ,websocket=port * switched from memmem() to g_strstr_len() * removed masked_size from vncws_decode_frame() * resetted vnc_tls variable to default in the configure script Changes v4 * incorporated suggestions from Stefan Hajnoczi * moved websockets encoding from vnc_write to its own client_write function * moved websockets decoding to its own client_read function * added initialization checks to vnc_disconnect to prevent crashes if a regular client connects to the websocket port Changes v5 * added initialized variable to VncState to prevent crashes during vnc_disconnect - the previously added initialization checks didn't prevent segfaults when a websocket client was connected Tim Hardeck (3): vnc: added buffer_advance function vnc: added initial websocket protocol support vnc: fix possible uninitialized removals configure| 27 +- qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 282 ++ ui/vnc-ws.h | 92 ++ ui/vnc.c | 211 +++- ui/vnc.h | 21 7 files changed, 614 insertions(+), 28 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h -- 1.7.10.4
[Qemu-devel] [Bug 1087974] Re: [regression] vnc tight png produces garbled output
The patch does fix the issue for me, thanks. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1087974 Title: [regression] vnc tight png produces garbled output Status in QEMU: New Bug description: VNC Tight PNG compression did work fine two or three month ago but don't anymore. Now when Tight PNG is used parts of the desktop are shown but they are scrambled together. I have always tested this feature against QEMU git with noVNC by only allowing Tight PNG compression. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1087974/+subscriptions
Re: [Qemu-devel] [PATCH 2/3 v4] vnc: added initial websocket protocol support
On 12/11/2012 11:04 AM, Stefan Hajnoczi wrote: On Fri, Dec 07, 2012 at 03:56:34PM +0100, Tim Hardeck wrote: Thanks for addressing my review comments. @@ -1328,13 +1358,14 @@ void vnc_client_read(void *opaque) void vnc_write(VncState *vs, const void *data, size_t len) { -buffer_reserve(vs-output, len); +buffer_reserve(vs-output, len); -if (vs-csock != -1 buffer_empty(vs-output)) { -qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, vnc_client_write, vs); -} +if (vs-csock != -1 buffer_empty(vs-output)) { +qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, +vnc_client_write, vs); +} -buffer_append(vs-output, data, len); +buffer_append(vs-output, data, len); QEMU uses 4 spaces for indentation. I don't know how I missed that, probably during the removal of the previous parts, but `scripts/checkpatch.pl` didn't complain either. Is the rest of the patchset fine? Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: OpenPGP digital signature
[Qemu-devel] [Bug 1087974] Re: [regression] vnc tight png produces garbled output
* make sure that qemu is compiled with --enable-vnc-png * git clone git://github.com/kanaka/noVNC * edit include/rfb.js at line 50 and comment out or remove all encodings above ['TIGHT_PNG',-260 ], * open vnc.html in Firefox or Chrome *apply either my patch to QEMU https://lists.nongnu.org/archive/html /qemu-devel/2012-12/msg00869.html or use Websockify https://github.com/kanaka/websockify to get Websocket support. * in case of my patch run QEMU with `-vnc :0,websocket` and connect with noVNC to port 5700. * in case of Websockify run QEMU with `./websockify.py 5900 -- qemu- system-x86_64 -vnc :0` and connect to port 5900 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1087974 Title: [regression] vnc tight png produces garbled output Status in QEMU: New Bug description: VNC Tight PNG compression did work fine two or three month ago but don't anymore. Now when Tight PNG is used parts of the desktop are shown but they are scrambled together. I have always tested this feature against QEMU git with noVNC by only allowing Tight PNG compression. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1087974/+subscriptions
[Qemu-devel] [Bug 1087974] Re: [regression] vnc tight png produces garbled output
** Attachment added: screenshot of the issue https://bugs.launchpad.net/qemu/+bug/1087974/+attachment/3457223/+files/tight-png-compression-issue.png -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1087974 Title: [regression] vnc tight png produces garbled output Status in QEMU: New Bug description: VNC Tight PNG compression did work fine two or three month ago but don't anymore. Now when Tight PNG is used parts of the desktop are shown but they are scrambled together. I have always tested this feature against QEMU git with noVNC by only allowing Tight PNG compression. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1087974/+subscriptions
[Qemu-devel] [Bug 1087974] Re: [regression] vnc tight png produces garbled output
If you had opened vnc.html before the rfb.js might be still in the browser cache, at least I had a similar issue once. I have tested this with Chrome but I think it happened in Firefox too. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1087974 Title: [regression] vnc tight png produces garbled output Status in QEMU: New Bug description: VNC Tight PNG compression did work fine two or three month ago but don't anymore. Now when Tight PNG is used parts of the desktop are shown but they are scrambled together. I have always tested this feature against QEMU git with noVNC by only allowing Tight PNG compression. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1087974/+subscriptions
[Qemu-devel] [Bug 1087974] Re: [regression] vnc tight png produces garbled output
47683d669f993308c2b84bed4ce64aafb5d7ced4 is the first bad commit commit 47683d669f993308c2b84bed4ce64aafb5d7ced4 Author: Gerd Hoffmann kra...@redhat.com Date: Thu Oct 11 12:04:33 2012 +0200 pixman/vnc: remove rgb_prepare_row* functions Let pixman do it instead. Signed-off-by: Gerd Hoffmann kra...@redhat.com :04 04 653d58e66bf3a2d8240b2f9176979c44ccd720e1 6b6e367a8522cb58b42ad8f204387a354d3b3d00 M ui Just reverting this particular commit isn't enough thou but it is connected. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1087974 Title: [regression] vnc tight png produces garbled output Status in QEMU: New Bug description: VNC Tight PNG compression did work fine two or three month ago but don't anymore. Now when Tight PNG is used parts of the desktop are shown but they are scrambled together. I have always tested this feature against QEMU git with noVNC by only allowing Tight PNG compression. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1087974/+subscriptions
[Qemu-devel] [Bug 1087974] [NEW] [regression] vnc tight png produces garbled output
Public bug reported: VNC Tight PNG compression did work fine two or three month ago but don't anymore. Now when Tight PNG is used parts of the desktop are shown but they are scrambled together. I have always tested this feature against QEMU git with noVNC by only allowing Tight PNG compression. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1087974 Title: [regression] vnc tight png produces garbled output Status in QEMU: New Bug description: VNC Tight PNG compression did work fine two or three month ago but don't anymore. Now when Tight PNG is used parts of the desktop are shown but they are scrambled together. I have always tested this feature against QEMU git with noVNC by only allowing Tight PNG compression. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1087974/+subscriptions
[Qemu-devel] [PATCH 0/3 v4] vnc: added initial websocket protocol support
This patch set adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocketis used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Changes v2 * removed automatic websocket recognition * added new lwebsock socket on port 5700 + display when the vnc option websocket is passed on * adapted vnc_connect vnc_listen_read to differ between websocket * added separate event handler to read the Websocket handshake Changes v3 * added manual port specification by using ,websocket=port * switched from memmem() to g_strstr_len() * removed masked_size from vncws_decode_frame() * resetted vnc_tls variable to default in the configure script Changes v4 * incorporated suggestions from Stefan Hajnoczi * moved websockets encoding from vnc_write to its own client_write function * moved websockets decoding to its own client_read function * added initialization checks to vnc_disconnect to prevent crashes if a regular client connects to the websocket port Tim Hardeck (3): vnc: added buffer_advance function vnc: added initial websocket protocol support vnc: fix possible uninitialized removals configure| 27 +- qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 282 ++ ui/vnc-ws.h | 92 ++ ui/vnc.c | 223 -- ui/vnc.h | 20 7 files changed, 620 insertions(+), 33 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h -- 1.7.10.4
[Qemu-devel] [PATCH 1/3] vnc: added buffer_advance function
Following Anthony Liguori's Websocket implementation I have added the buffer_advance function to VNC and replaced all related buffer memmove operations with it. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c | 13 + ui/vnc.h |1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index ba30362..87bdd5f 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -510,6 +510,13 @@ void buffer_append(Buffer *buffer, const void *data, size_t len) buffer-offset += len; } +void buffer_advance(Buffer *buf, size_t len) +{ +memmove(buf-buffer, buf-buffer + len, +(buf-offset - len)); +buf-offset -= len; +} + static void vnc_desktop_resize(VncState *vs) { DisplayState *ds = vs-ds; @@ -1166,8 +1173,7 @@ static long vnc_client_write_plain(VncState *vs) if (!ret) return 0; -memmove(vs-output.buffer, vs-output.buffer + ret, (vs-output.offset - ret)); -vs-output.offset -= ret; +buffer_advance(vs-output, ret); if (vs-output.offset == 0) { qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, vs); @@ -1313,8 +1319,7 @@ void vnc_client_read(void *opaque) } if (!ret) { -memmove(vs-input.buffer, vs-input.buffer + len, (vs-input.offset - len)); -vs-input.offset -= len; +buffer_advance(vs-input, len); } else { vs-read_handler_expect = ret; } diff --git a/ui/vnc.h b/ui/vnc.h index 6141e88..ea82875 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -510,6 +510,7 @@ void buffer_reserve(Buffer *buffer, size_t len); void buffer_reset(Buffer *buffer); void buffer_free(Buffer *buffer); void buffer_append(Buffer *buffer, const void *data, size_t len); +void buffer_advance(Buffer *buf, size_t len); /* Misc helpers */ -- 1.7.10.4
[Qemu-devel] [PATCH 2/3 v4] vnc: added initial websocket protocol support
This patch adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocketis used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Parts of the implementation base on Anthony Liguori's QEMU Websocket patch from 2010 and on Joel Martin's LibVNC Websocket implementation. Signed-off-by: Tim Hardeck thard...@suse.de --- configure| 27 +- qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 282 ++ ui/vnc-ws.h | 92 ++ ui/vnc.c | 198 +- ui/vnc.h | 19 7 files changed, 601 insertions(+), 26 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h diff --git a/configure b/configure index 994f731..ca519c6 100755 --- a/configure +++ b/configure @@ -158,6 +158,7 @@ vnc_tls= vnc_sasl= vnc_jpeg= vnc_png= +vnc_ws= xen= xen_ctrl_version= xen_pci_passthrough= @@ -703,6 +704,10 @@ for opt do ;; --enable-vnc-png) vnc_png=yes ;; + --disable-vnc-ws) vnc_ws=no + ;; + --enable-vnc-ws) vnc_ws=yes + ;; --disable-slirp) slirp=no ;; --disable-uuid) uuid=no @@ -1048,6 +1053,8 @@ echo --disable-vnc-jpeg disable JPEG lossy compression for VNC server echo --enable-vnc-jpegenable JPEG lossy compression for VNC server echo --disable-vnc-pngdisable PNG compression for VNC server (default) echo --enable-vnc-png enable PNG compression for VNC server +echo --disable-vnc-ws disable Websockets support for VNC server +echo --enable-vnc-ws enable Websockets support for VNC server echo --disable-curses disable curses output echo --enable-curses enable curses output echo --disable-curl disable curl connectivity @@ -1692,8 +1699,8 @@ EOF fi ## -# VNC TLS detection -if test $vnc = yes -a $vnc_tls != no ; then +# VNC TLS/WS detection +if test $vnc = yes -a \( $vnc_tls != no -o $vnc_ws != no \) ; then cat $TMPC EOF #include gnutls/gnutls.h int main(void) { gnutls_session_t s; gnutls_init(s, GNUTLS_SERVER); return 0; } @@ -1701,13 +1708,22 @@ 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 -vnc_tls=yes +if test $vnc_tls != no ; then + vnc_tls=yes +fi +if test $vnc_ws != no ; then + vnc_ws=yes +fi libs_softmmu=$vnc_tls_libs $libs_softmmu else if test $vnc_tls = yes ; then feature_not_found vnc-tls fi +if test $vnc_ws = yes ; then + feature_not_found vnc-ws +fi vnc_tls=no +vnc_ws=no fi fi @@ -3209,6 +3225,7 @@ if test $vnc = yes ; then echo VNC SASL support $vnc_sasl echo VNC JPEG support $vnc_jpeg echo VNC PNG support $vnc_png +echo VNC WS support$vnc_ws fi if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu @@ -3385,6 +3402,10 @@ if test $vnc_png = yes ; then echo CONFIG_VNC_PNG=y $config_host_mak echo VNC_PNG_CFLAGS=$vnc_png_cflags $config_host_mak fi +if test $vnc_ws = yes ; then + echo CONFIG_VNC_WS=y $config_host_mak + echo VNC_WS_CFLAGS=$vnc_ws_cflags $config_host_mak +fi if test $fnmatch = yes ; then echo CONFIG_FNMATCH=y $config_host_mak fi diff --git a/qemu-options.hx b/qemu-options.hx index de43b1b..d7c4d81 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1096,6 +1096,14 @@ client is specified by the @var{display}. For reverse network connections (@var{host}:@var{d},@code{reverse}), the @var{d} argument is a TCP port number, not a display number. +@item websocket + +Opens an additional TCP listening port dedicated to VNC Websocket connections. +By defintion 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}. + @item password Require that password based authentication is used for client connections. diff --git a/ui/Makefile.objs b/ui/Makefile.objs index adc07be..58e191b 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -4,6 +4,7 @@ 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-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o +vnc-obj-$(CONFIG_VNC_WS) += vnc-ws.o vnc-obj-y += vnc-jobs.o common-obj-y += keymaps.o diff
[Qemu-devel] [PATCH 3/3] vnc: fix possible uninitialized removals
Some VncState values are not initialized before the Websocket handshake. If it fails QEMU segfaults during the cleanup. To prevent this behavior intialization checks are added. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index a5c16e0..3af1840 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1053,20 +1053,26 @@ void vnc_disconnect_finish(VncState *vs) audio_del(vs); vnc_release_modifiers(vs); -QTAILQ_REMOVE(vs-vd-clients, vs, next); +if (!QTAILQ_EMPTY(vs-vd-clients)) { +QTAILQ_REMOVE(vs-vd-clients, vs, next); +} if (QTAILQ_EMPTY(vs-vd-clients)) { dcl-idle = 1; } -qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); +if (vs-mouse_mode_notifier.notify != NULL) { +qemu_remove_mouse_mode_change_notifier(vs-mouse_mode_notifier); +} vnc_remove_timer(vs-vd); if (vs-vd-lock_key_sync) qemu_remove_led_event_handler(vs-led); vnc_unlock_output(vs); qemu_mutex_destroy(vs-output_mutex); -qemu_bh_delete(vs-bh); +if (vs-bh != NULL) { +qemu_bh_delete(vs-bh); +} buffer_free(vs-jobs_buffer); for (i = 0; i VNC_STAT_ROWS; ++i) { -- 1.7.10.4
Re: [Qemu-devel] [PATCH v3] vnc: added initial websocket protocol support
Hi Stefan, On 12/03/2012 05:22 PM, Stefan Hajnoczi wrote: Thanks for the patch, Tim. Some general code review comments below. Thanks for the code review. I am going to incorporate them in my new patch. I hope someone has time to review the VNC and WebSocket specific stuff. I didn't check the details of buffers, whether the WebSocket spec is correctly implemented, etc. I have mainly tested my websockets implementation with the guest OS openSUSE 12.2 which worked fine during all my tests on several browsers. I recently found out though that when I run Firefox in openSUSE 12.1, noVNC complains about an unsupported VNC encoding and QEMU crashes. I have attached the back trace at the end of this mail. This issue could be fixed by not encoding Websocket frames directly in vnc_write but in vnc_client_write_locked. This should also decrease the overhead through websocket frame headers. Nevertheless it looks like QEMU did crash because of the sudden disconnect which shouldn't happen. I have created a vnc_client_write_ws function which is used instead of vnc_client_write_plain. I have also moved the decoding part to vnc_client_read_ws to keep consistency? Is this Ok or should I add the websocket en/decoding to the existing vnc plain functions? Regards Tim #0 0x73f92d25 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 resultvar = 0 pid = 24308 selftid = 24312 #1 0x73f941a8 in __GI_abort () at abort.c:91 save_stage = 2 act = {__sigaction_handler = {sa_handler = 0x559153c0 __func__.4908, sa_sigaction = 0x559153c0 __func__.4908}, sa_mask = {__val = {140737287809753, 0, 18374686479671623680, 0, 140737286898450, 131072, 93825010082032, 2064448, 93825010157472, 1989008, 22, 140737218422160, 1, 140737488346032, 0, 140737218426624}}, sa_flags = -201457138, sa_restorer = 0x6d940} sigs = {__val = {32, 0 repeats 15 times}} #2 0x5577b5c2 in error_exit (err=22, msg=0x559153c0 __func__.4908 qemu_mutex_lock) at qemu-thread-posix.c:28 No locals. #3 0x5577b6e1 in qemu_mutex_lock (mutex=0x5328) at qemu-thread-posix.c:59 err = 22 __func__ = qemu_mutex_lock #4 0x557bb075 in vnc_lock_output (vs=0x5665a100) at ui/vnc-jobs.h:63 No locals. #5 0x557bb5eb in vnc_jobs_consume_buffer (vs=0x5665a100) at ui/vnc-jobs.c:166 flush = false #6 0x557bb5ae in vnc_jobs_join (vs=0x5665a100) at ui/vnc-jobs.c:159 No locals. #7 0x557bf9d9 in vnc_update_client_sync (vs=0x5665a100, has_dirty=1) at ui/vnc.c:876 ret = 0 ---Type return to continue, or q return to quit--- #8 0x557bf308 in vnc_dpy_copy (ds=0x56583240, src_x=99, src_y=143, dst_x=99, dst_y= 146, w=8, h=1) at ui/vnc.c:752 vd = 0x7fffeea48010 vs = 0x5665a100 vn = 0x0 src_row = 0x18 Address 0x18 out of bounds dst_row = 0xc000c00 Address 0xc000c00 out of bounds i = 768 x = -1 y = 24 pitch = 1024 inc = 0 w_lim = 0 s = 8 cmp_bytes = 2359296 #9 0x55623e78 in dpy_gfx_copy (s=0x56583240, src_x=99, src_y=143, dst_x=99, dst_y=146, w=8, h=1) at console.h:275 dcl = 0x565f38e0 #10 0x556281f4 in qemu_console_copy (ds=0x56583240, src_x=99, src_y=143, dst_x=99, dst_y=146, w=8, h=1) at console.c:1598 No locals. #11 0x5566a79a in cirrus_do_copy (s=0x565afc08, dst=448832, src=439616, w=8, h=1) at hw/cirrus_vga.c:732 sx = 99 sy = 143 dx = 99 ---Type return to continue, or q return to quit--- dy = 146 depth = 3 notify = 1 #12 0x5566a8f7 in cirrus_bitblt_videotovideo_copy (s=0x565afc08) at hw/cirrus_vga.c:750 No locals. #13 0x5566ae8b in cirrus_bitblt_videotovideo (s=0x565afc08) at hw/cirrus_vga.c:872 ret = 1 #14 0x5566b61c in cirrus_bitblt_start (s=0x565afc08) at hw/cirrus_vga.c:1013 blt_rop = 13 '\r' #15 0x5566b6c8 in cirrus_write_bitblt (s=0x565afc08, reg_value=2) at hw/cirrus_vga.c:1034 old_value = 0 #16 0x5566c589 in cirrus_vga_write_gr (s=0x565afc08, reg_index=49, reg_value=2) at hw/cirrus_vga.c:1529 No locals. #17 0x5566cebb in cirrus_mmio_blt_write (s=0x565afc08, address=64, value=2 '\002') at hw/cirrus_vga.c:1883 No locals. #18 0x5566ed4c in cirrus_mmio_write (opaque=0x565afc08, addr=320, val=2, size=1) at hw/cirrus_vga.c:2659 s = 0x565afc08 #19 0x5584b7ca in memory_region_write_accessor (opaque=0x565c0538, addr=320, value= 0x7fffefe92a98, size=1, shift=0, mask=255) at /suse/thardeck/Development/qemu/memory.c:334 mr = 0x565c0538 tmp = 2 #20 0x5584b8ac in access_with_adjusted_size (addr=320, value=0x7fffefe92a98, size=4, ---Type return to
[Qemu-devel] [PATCH v3] vnc: added initial websocket protocol support
This patch adds basic Websocket Protocol version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is mandatory. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websocket support the VNC option websocketis used, for example -vnc :0,websocket. The listen port for Websocket connections is (5700 + display) so if QEMU VNC is started with :0 the Websocket port would be 5700. As an alternative the Websocket port could be manually specified by using ,websocket=port instead. Parts of the implementation base on Anthony Liguori's QEMU Websocket patch from 2010 and on Joel Martin's LibVNC Websocket implementation. Signed-off-by: Tim Hardeck thard...@suse.de --- Changes v2 * removed automatic websocket recognition * added new lwebsock socket on port 5700 + display when the vnc option websocket is passed on * adapted vnc_connect vnc_listen_read to differ between websocket * added separate event handler to read the Websocket handshake Changes v3 * added manual port specification by using ,websocket=port * switched from memmem() to g_strstr_len() * removed masked_size from vncws_decode_frame() * resetted vnc_tls variable to default in the configure script QEMU does segfault if a regular VNC client connects to the Websocket port and then disconnects because of several unitialized lists since vnc_init_state wasn't run before. The segfault could be fixed by applying my previously sent patches [PATCH 0/2] fix segfaults triggered by failed vnc handshakes. I have used parts of the LibVNC websockets implementation that's why I have added the GPL header to the new files. --- configure| 32 qemu-options.hx |8 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 206 + ui/vnc-ws.h | 101 ui/vnc.c | 226 +- ui/vnc.h | 21 + 7 files changed, 575 insertions(+), 20 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h diff --git a/configure b/configure index 780b19a..c384138 100755 --- a/configure +++ b/configure @@ -158,6 +158,7 @@ vnc_tls= vnc_sasl= vnc_jpeg= vnc_png= +vnc_ws= xen= xen_ctrl_version= xen_pci_passthrough= @@ -703,6 +704,10 @@ for opt do ;; --enable-vnc-png) vnc_png=yes ;; + --disable-vnc-ws) vnc_ws=no + ;; + --enable-vnc-ws) vnc_ws=yes + ;; --disable-slirp) slirp=no ;; --disable-uuid) uuid=no @@ -1048,6 +1053,8 @@ echo --disable-vnc-jpeg disable JPEG lossy compression for VNC server echo --enable-vnc-jpegenable JPEG lossy compression for VNC server echo --disable-vnc-pngdisable PNG compression for VNC server (default) echo --enable-vnc-png enable PNG compression for VNC server +echo --disable-vnc-ws disable Websockets support for VNC server +echo --enable-vnc-ws enable Websockets support for VNC server echo --disable-curses disable curses output echo --enable-curses enable curses output echo --disable-curl disable curl connectivity @@ -1772,6 +1779,26 @@ EOF fi ## +# VNC WS detection +if test $vnc = yes -a $vnc_ws != 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_ws_cflags=`$pkg_config --cflags gnutls 2 /dev/null` + vnc_ws_libs=`$pkg_config --libs gnutls 2 /dev/null` + if compile_prog $vnc_ws_cflags $vnc_ws_libs ; then +vnc_ws=yes +libs_softmmu=$vnc_ws_libs $libs_softmmu + else +if test $vnc_ws = yes ; then + feature_not_found vnc-ws +fi +vnc_ws=no + fi +fi + +## # fnmatch() probe, used for ACL routines fnmatch=no cat $TMPC EOF @@ -3194,6 +3221,7 @@ if test $vnc = yes ; then echo VNC SASL support $vnc_sasl echo VNC JPEG support $vnc_jpeg echo VNC PNG support $vnc_png +echo VNC WS support$vnc_ws fi if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu @@ -3370,6 +3398,10 @@ if test $vnc_png = yes ; then echo CONFIG_VNC_PNG=y $config_host_mak echo VNC_PNG_CFLAGS=$vnc_png_cflags $config_host_mak fi +if test $vnc_ws = yes ; then + echo CONFIG_VNC_WS=y $config_host_mak + echo VNC_WS_CFLAGS=$vnc_ws_cflags $config_host_mak +fi if test $fnmatch = yes ; then echo CONFIG_FNMATCH=y $config_host_mak fi diff --git a/qemu-options.hx b/qemu-options.hx index 9bb29d3..647071e 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1096,6 +1096,14 @@ client is specified by the @var{display}. For reverse network connections (@var{host}:@var{d},@code{reverse}), the @var{d} argument is a TCP port number, not a display number. +@item websocket + +Opens an additional TCP listening port dedicated to VNC Websocket connections. +By defintion
[Qemu-devel] [PATCH v2] vnc: added initial websockets support
This patch adds basic Websockets version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is required. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websockets during runtime the VNC option websocket is used, for example -vnc :0,websocket would activate Websockets. The port for Websockets connections is (5700 + display) so if QEMU VNC is started with :0 the websockets port would be 5700. SHA1 is required for the handshake which is generated by GnuTLS. Since using GnuTLS does automatically activate VNC-TLS, which has warnings about deprecated parts, I have changed the configure script to disable VNC-TLS if not explicitly enabled. Parts of the implementation base on Anthony Liguori's QEMU Websockets patch from 2010 and on Joel Martin's LibVNC Websockets implementation. Signed-off-by: Tim Hardeck thard...@suse.de --- Changes to v1 * removed automatic websocket recognition * added new lwebsock socket on port 5700 + display when the vnc option websocket is passed on * adapted vnc_connect vnc_listen_read to differ between websocket * added separate event handler to read the Websocket handshake Would it be Ok to use a public domain SHA1 implementation like tests/tcg/sha1.c and if so where should the sha1.c be stored? Without the GnuTLS dependency would it be Ok to make Websockets not optional because this would clean up the patch/code quite a bit? QEMU does segfault if a regular VNC client connects to the Websocket port and then disconnects because of several unitialized lists since vnc_init_state wasn't run before. The segfault could be fixed by applying my previously sent patches [PATCH 0/2] fix segfaults triggered by failed vnc handshakes. I have used parts of the LibVNC websockets implementation that's why I have added the GPL header to the new files. --- configure| 34 - qemu-options.hx |6 ++ ui/Makefile.objs |1 + ui/vnc-ws.c | 211 ++ ui/vnc-ws.h | 101 ++ ui/vnc.c | 185 +-- ui/vnc.h | 20 ++ 7 files changed, 537 insertions(+), 21 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h diff --git a/configure b/configure index 780b19a..ac9da73 100755 --- a/configure +++ b/configure @@ -154,10 +154,11 @@ vnc=yes sparse=no uuid= vde= -vnc_tls= +vnc_tls=no vnc_sasl= vnc_jpeg= vnc_png= +vnc_ws= xen= xen_ctrl_version= xen_pci_passthrough= @@ -703,6 +704,10 @@ for opt do ;; --enable-vnc-png) vnc_png=yes ;; + --disable-vnc-ws) vnc_ws=no + ;; + --enable-vnc-ws) vnc_ws=yes + ;; --disable-slirp) slirp=no ;; --disable-uuid) uuid=no @@ -1048,6 +1053,8 @@ echo --disable-vnc-jpeg disable JPEG lossy compression for VNC server echo --enable-vnc-jpegenable JPEG lossy compression for VNC server echo --disable-vnc-pngdisable PNG compression for VNC server (default) echo --enable-vnc-png enable PNG compression for VNC server +echo --disable-vnc-ws disable Websockets support for VNC server +echo --enable-vnc-ws enable Websockets support for VNC server echo --disable-curses disable curses output echo --enable-curses enable curses output echo --disable-curl disable curl connectivity @@ -1772,6 +1779,26 @@ EOF fi ## +# VNC WS detection +if test $vnc = yes -a $vnc_ws != 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_ws_cflags=`$pkg_config --cflags gnutls 2 /dev/null` + vnc_ws_libs=`$pkg_config --libs gnutls 2 /dev/null` + if compile_prog $vnc_ws_cflags $vnc_ws_libs ; then +vnc_ws=yes +libs_softmmu=$vnc_ws_libs $libs_softmmu + else +if test $vnc_ws = yes ; then + feature_not_found vnc-ws +fi +vnc_ws=no + fi +fi + +## # fnmatch() probe, used for ACL routines fnmatch=no cat $TMPC EOF @@ -3194,6 +3221,7 @@ if test $vnc = yes ; then echo VNC SASL support $vnc_sasl echo VNC JPEG support $vnc_jpeg echo VNC PNG support $vnc_png +echo VNC WS support$vnc_ws fi if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu @@ -3370,6 +3398,10 @@ if test $vnc_png = yes ; then echo CONFIG_VNC_PNG=y $config_host_mak echo VNC_PNG_CFLAGS=$vnc_png_cflags $config_host_mak fi +if test $vnc_ws = yes ; then + echo CONFIG_VNC_WS=y $config_host_mak + echo VNC_WS_CFLAGS=$vnc_ws_cflags $config_host_mak +fi if test $fnmatch = yes ; then echo CONFIG_FNMATCH=y $config_host_mak fi diff --git a/qemu-options.hx b/qemu-options.hx index 9bb29d3..3b3fff8 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1096,6 +1096,12 @@ client is specified by the @var
Re: [Qemu-devel] [PATCH v2] vnc: added initial websockets support
On 11/20/2012 10:47 AM, Daniel P. Berrange wrote: On Tue, Nov 20, 2012 at 10:21:58AM +0100, Tim Hardeck wrote: This patch adds basic Websockets version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is required. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). To activate Websockets during runtime the VNC option websocket is used, for example -vnc :0,websocket would activate Websockets. The port for Websockets connections is (5700 + display) so if QEMU VNC is started with :0 the websockets port would be 5700. We need to be able to specify an explicit port number for the websockets listen address, separately from the main VNC port number. This automatic pick of websockets port might be nice for a user starting QEMU manually, but for management apps we need full direct control. Ok, this should be no problem to add something like websocket=port but I just thought that a correlation between the vnc and websocket port would be quite useful especially when several QEMU instances are run on one machine. Would it be Ok to keep the correlation if no port is specified? I am going to add the websocket port option after some more feedback. Changes to v1 * removed automatic websocket recognition * added new lwebsock socket on port 5700 + display when the vnc option websocket is passed on * adapted vnc_connect vnc_listen_read to differ between websocket * added separate event handler to read the Websocket handshake Would it be Ok to use a public domain SHA1 implementation like tests/tcg/sha1.c and if so where should the sha1.c be stored? Without the GnuTLS dependency would it be Ok to make Websockets not optional because this would clean up the patch/code quite a bit? IMHO using gcrypt/GNUTLS is a good thing. Creating our own copies of encryption algorithms in source tree causes significant complications getting QEMU security certified. GNUTLS is a common enough crypto library that I don't think it is unreasonably onerous to expect it to be used for WebSockets. It even works fine on Windows. That's one of the reasons why I have used GnuTLS but it is quite a huge dependency for just one algorithm and the many ifdefs don't really help the code quality. Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH] vnc: added initial websockets support
On 11/19/2012 09:56 AM, Gerd Hoffmann wrote: On 11/19/12 00:29, Tim Hardeck wrote: Hi Stefan, thanks for your input but how should it be implemented? I personally would like activating Websockets as a VNC option like: -vnc :0 -vnc :1,websockets I have already tested this locally and it does work but only for one protocol since QEMU does only interpret the last vnc option. So is allowing more than one VNC command line entry in combination with having more than one VNC thread for the same display worth working on or do you have something different in mind? -vnc :0,websock=$portnr ? This sounds resonable although maybe the websockets port could just always be display + 1 so there is no need to parse a port. Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH] vnc: added initial websockets support
On 11/19/2012 10:07 AM, Stefan Hajnoczi wrote: On Mon, Nov 19, 2012 at 12:29:44AM +0100, Tim Hardeck wrote: Hi Stefan, thanks for your input but how should it be implemented? I personally would like activating Websockets as a VNC option like: -vnc :0 -vnc :1,websockets I have already tested this locally and it does work but only for one protocol since QEMU does only interpret the last vnc option. So is allowing more than one VNC command line entry in combination with having more than one VNC thread for the same display worth working on or do you have something different in mind? I'm not familiar enough with the VNC code to suggest how to best implement this. One thing to think about is that Websockets is a transport. Perhaps the VNC code itself shouldn't speak it, instead generic QEMU socket code should implement Websockets so that non-VNC components can also make use of it in the future. I have talked about this with a colleague and it seems like quite some effort for no use case besides VNC. It might be interesting in the long run though. Is the rest of my implementation OK besides the protocol recognition by timeout - which should only be an issue for high latency websockets connection? Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH] vnc: added initial websockets support
Hi Stefan, thanks for your input but how should it be implemented? I personally would like activating Websockets as a VNC option like: -vnc :0 -vnc :1,websockets I have already tested this locally and it does work but only for one protocol since QEMU does only interpret the last vnc option. So is allowing more than one VNC command line entry in combination with having more than one VNC thread for the same display worth working on or do you have something different in mind? Regards Tim On Sun, 2012-11-18 at 10:31 +0100, Stefan Hajnoczi wrote: On Fri, Nov 16, 2012 at 4:13 PM, Tim Hardeck thard...@suse.de wrote: Websockets connections are recognized by waiting 500ms for a Websocket handshake. If no data is received a regular vnc connection is assumed. If this is not acceptable please suggest if Websockets should be activated by a new VNC option or by an additional console parameter on a different port. Perhaps it's better to speak Websockets on a different port. That way no timer is required and we never fail to detect the correct protocol to speak. Stefan -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: This is a digitally signed message part
[Qemu-devel] [PATCH] vnc: added initial websockets support
This patch adds basic Websockets support to the QEMU VNC component. Websockets allow every modern web browser to connect to QEMU VNC without any additional plugins. Because of the GnuTLS requirement the Websockets implementation is optional (--enable-vnc-ws). Websockets connections are recognized by waiting 500ms for a Websocket handshake. If no data is received a regular vnc connection is assumed. If this is not acceptable please suggest if Websockets should be activated by a new VNC option or by an additional console parameter on a different port. SHA1 is required for the handshake which is generated with GnuTLS. Since using GnuTLS does automatically activate VNC-TLS, which has warnings about deprecated parts, I have changed the configure script to disable VNC-TLS if not explicitly enabled. The Websockets support was tested with noVNC http://kanaka.github.com/noVNC/ . I have used parts of the LibVNC websockets implementation that's why I have added the GPL header to the new files. I hope that it is fine that way. Tim Hardeck (1): vnc: added initial websockets support configure| 34 +++- ui/Makefile.objs |1 + ui/vnc-ws.c | 236 ++ ui/vnc-ws.h | 104 ui/vnc.c | 93 ++--- ui/vnc.h | 15 6 files changed, 471 insertions(+), 12 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h -- 1.7.10.4
[Qemu-devel] [PATCH] vnc: added initial websockets support
This patch adds basic Websockets version 13 - RFC 6455 - support to QEMU VNC. Binary encoding support on the client side is required. Websockets support in QEMU is enabled by the configure option --enable-vnc-ws. Websockets connections are recognized by waiting 500ms for a Websocket handshake. If no data is received a regular vnc connection is assumed. SHA1 is required for the handshake which is generated by GnuTLS. Since using GnuTLS does automatically activate VNC-TLS, which has warnings about deprecated parts, I have changed the configure script to disable VNC-TLS if not explicitly enabled. Parts of the implementation base on Anthony Liguori's QEMU Websockets patch from 2010 and on Joel Martin's LibVNC Websockets implementation. Signed-off-by: Tim Hardeck thard...@suse.de --- configure| 34 +++- ui/Makefile.objs |1 + ui/vnc-ws.c | 236 ++ ui/vnc-ws.h | 104 ui/vnc.c | 93 ++--- ui/vnc.h | 15 6 files changed, 471 insertions(+), 12 deletions(-) create mode 100644 ui/vnc-ws.c create mode 100644 ui/vnc-ws.h diff --git a/configure b/configure index 7290f50..d252da5 100755 --- a/configure +++ b/configure @@ -154,10 +154,11 @@ vnc=yes sparse=no uuid= vde= -vnc_tls= +vnc_tls=no vnc_sasl= vnc_jpeg= vnc_png= +vnc_ws= xen= xen_ctrl_version= xen_pci_passthrough= @@ -703,6 +704,10 @@ for opt do ;; --enable-vnc-png) vnc_png=yes ;; + --disable-vnc-ws) vnc_ws=no + ;; + --enable-vnc-ws) vnc_ws=yes + ;; --disable-slirp) slirp=no ;; --disable-uuid) uuid=no @@ -1048,6 +1053,8 @@ echo --disable-vnc-jpeg disable JPEG lossy compression for VNC server echo --enable-vnc-jpegenable JPEG lossy compression for VNC server echo --disable-vnc-pngdisable PNG compression for VNC server (default) echo --enable-vnc-png enable PNG compression for VNC server +echo --disable-vnc-ws disable Websockets support for VNC server +echo --enable-vnc-ws enable Websockets support for VNC server echo --disable-curses disable curses output echo --enable-curses enable curses output echo --disable-curl disable curl connectivity @@ -1772,6 +1779,26 @@ EOF fi ## +# VNC WS detection +if test $vnc = yes -a $vnc_ws != 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_ws_cflags=`$pkg_config --cflags gnutls 2 /dev/null` + vnc_ws_libs=`$pkg_config --libs gnutls 2 /dev/null` + if compile_prog $vnc_ws_cflags $vnc_ws_libs ; then +vnc_ws=yes +libs_softmmu=$vnc_ws_libs $libs_softmmu + else +if test $vnc_ws = yes ; then + feature_not_found vnc-ws +fi +vnc_ws=no + fi +fi + +## # fnmatch() probe, used for ACL routines fnmatch=no cat $TMPC EOF @@ -3191,6 +3218,7 @@ if test $vnc = yes ; then echo VNC SASL support $vnc_sasl echo VNC JPEG support $vnc_jpeg echo VNC PNG support $vnc_png +echo VNC WS support$vnc_ws fi if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu @@ -3367,6 +3395,10 @@ if test $vnc_png = yes ; then echo CONFIG_VNC_PNG=y $config_host_mak echo VNC_PNG_CFLAGS=$vnc_png_cflags $config_host_mak fi +if test $vnc_ws = yes ; then + echo CONFIG_VNC_WS=y $config_host_mak + echo VNC_WS_CFLAGS=$vnc_ws_cflags $config_host_mak +fi if test $fnmatch = yes ; then echo CONFIG_FNMATCH=y $config_host_mak fi diff --git a/ui/Makefile.objs b/ui/Makefile.objs index adc07be..58e191b 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -4,6 +4,7 @@ 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-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o +vnc-obj-$(CONFIG_VNC_WS) += vnc-ws.o vnc-obj-y += vnc-jobs.o common-obj-y += keymaps.o diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c new file mode 100644 index 000..c40266a --- /dev/null +++ b/ui/vnc-ws.c @@ -0,0 +1,236 @@ +/* + * QEMU VNC display driver: Websockets support + * + * Copyright (C) 2010 Joel Martin + * Copyright (C) 2012 Tim Hardeck + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation
Re: [Qemu-devel] [PATCH 2/2] qemu queue: fix uninitialized removals
Hi Andreas, On Wednesday 17 October 2012 17:00:15 Andreas Färber wrote: Tim, Am 14.10.2012 15:08, schrieb Tim Hardeck: When calling QTAILQ_REMOVE or QLIST_REMOVE on an unitialized list QEMU segfaults. Can this be reproduced by a user today? Or is this just fixing the case that a developer forgot to initialize a list? I am not sure but in this case it happened during an early VNC connection state failure which most likely wouldn't happen to regular users. I triggered it while working on the VNC connection part. The issue could most likely be also fixed in the VNC connection initialization process but if this changes doesn't have a relevant performance impact they might prevent some other/future crashes. Regards Tim Regards, Andreas Check for this case specifically on item removal. Signed-off-by: Tim Hardeck thard...@suse.de --- qemu-queue.h |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qemu-queue.h b/qemu-queue.h index 9288cd8..47ed239 100644 --- a/qemu-queue.h +++ b/qemu-queue.h @@ -141,7 +141,9 @@ struct { \ if ((elm)-field.le_next != NULL) \ (elm)-field.le_next-field.le_prev = \ (elm)-field.le_prev; \ -*(elm)-field.le_prev = (elm)-field.le_next; \ +if ((elm)-field.le_prev != NULL) { \ +*(elm)-field.le_prev = (elm)-field.le_next; \ +} \ } while (/*CONSTCOND*/0) #define QLIST_FOREACH(var, head, field) \ @@ -381,7 +383,9 @@ struct { \ (elm)-field.tqe_prev; \ else\ (head)-tqh_last = (elm)-field.tqe_prev; \ -*(elm)-field.tqe_prev = (elm)-field.tqe_next; \ +if ((elm)-field.tqe_prev != NULL) {\ +*(elm)-field.tqe_prev = (elm)-field.tqe_next; \ +} \ } while (/*CONSTCOND*/0) #define QTAILQ_FOREACH(var, head, field)\ -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/ signature.asc Description: This is a digitally signed message part.
[Qemu-devel] [PATCH 2/2] qemu queue: fix uninitialized removals
When calling QTAILQ_REMOVE or QLIST_REMOVE on an unitialized list QEMU segfaults. Check for this case specifically on item removal. Signed-off-by: Tim Hardeck thard...@suse.de --- qemu-queue.h |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qemu-queue.h b/qemu-queue.h index 9288cd8..47ed239 100644 --- a/qemu-queue.h +++ b/qemu-queue.h @@ -141,7 +141,9 @@ struct { \ if ((elm)-field.le_next != NULL) \ (elm)-field.le_next-field.le_prev = \ (elm)-field.le_prev; \ -*(elm)-field.le_prev = (elm)-field.le_next; \ +if ((elm)-field.le_prev != NULL) { \ +*(elm)-field.le_prev = (elm)-field.le_next; \ +} \ } while (/*CONSTCOND*/0) #define QLIST_FOREACH(var, head, field) \ @@ -381,7 +383,9 @@ struct { \ (elm)-field.tqe_prev; \ else\ (head)-tqh_last = (elm)-field.tqe_prev; \ -*(elm)-field.tqe_prev = (elm)-field.tqe_next; \ +if ((elm)-field.tqe_prev != NULL) {\ +*(elm)-field.tqe_prev = (elm)-field.tqe_next; \ +} \ } while (/*CONSTCOND*/0) #define QTAILQ_FOREACH(var, head, field)\ -- 1.7.10.4
[Qemu-devel] [PATCH 0/2] fix segfaults triggered by failed vnc handshakes
While trying to adapt Anthony Liguori's websockets patches to the current standard I ran into some segfaults. They were triggered during disconnects due to failed VNC handshakes. I have added checks to prevent them. Tim Hardeck (2): vnc: fix segfault due to failed handshake qemu queue: fix uninitialized removals qemu-queue.h |8 ++-- ui/vnc.c |4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) -- 1.7.10.4
[Qemu-devel] [PATCH 1/2] vnc: fix segfault due to failed handshake
When the VNC server disconnects due to a failed handshake we don't have vs-bh allocated yet. Check for this case and don't delete it. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/vnc.c b/ui/vnc.c index 01b2daf..656895a 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1055,7 +1055,9 @@ static void vnc_disconnect_finish(VncState *vs) vnc_unlock_output(vs); qemu_mutex_destroy(vs-output_mutex); -qemu_bh_delete(vs-bh); +if (vs-bh != NULL) { +qemu_bh_delete(vs-bh); +} buffer_free(vs-jobs_buffer); for (i = 0; i VNC_STAT_ROWS; ++i) { -- 1.7.10.4
[Qemu-devel] [PATCH 2/2] qemu queue: fix uninitialized removals
When calling QTAILQ_REMOVE or QLIST_REMOVE on an unitialized list QEMU segfaults. Check for this case specifically on item removal. Signed-off-by: Tim Hardeck thard...@suse.de --- qemu-queue.h |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qemu-queue.h b/qemu-queue.h index 9288cd8..47ed239 100644 --- a/qemu-queue.h +++ b/qemu-queue.h @@ -141,7 +141,9 @@ struct { \ if ((elm)-field.le_next != NULL) \ (elm)-field.le_next-field.le_prev = \ (elm)-field.le_prev; \ -*(elm)-field.le_prev = (elm)-field.le_next; \ +if ((elm)-field.le_prev != NULL) { \ +*(elm)-field.le_prev = (elm)-field.le_next; \ +} \ } while (/*CONSTCOND*/0) #define QLIST_FOREACH(var, head, field) \ @@ -381,7 +383,9 @@ struct { \ (elm)-field.tqe_prev; \ else\ (head)-tqh_last = (elm)-field.tqe_prev; \ -*(elm)-field.tqe_prev = (elm)-field.tqe_next; \ +if ((elm)-field.tqe_prev != NULL) {\ +*(elm)-field.tqe_prev = (elm)-field.tqe_next; \ +} \ } while (/*CONSTCOND*/0) #define QTAILQ_FOREACH(var, head, field)\ -- 1.7.10.4
[Qemu-devel] [PATCH 1/2] vnc: fix segfault due to failed handshake
When the VNC server disconnects due to a failed handshake we don't have vs-bh allocated yet. Check for this case and don't delete it. Signed-off-by: Tim Hardeck thard...@suse.de --- ui/vnc.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/vnc.c b/ui/vnc.c index 01b2daf..656895a 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1055,7 +1055,9 @@ static void vnc_disconnect_finish(VncState *vs) vnc_unlock_output(vs); qemu_mutex_destroy(vs-output_mutex); -qemu_bh_delete(vs-bh); +if (vs-bh != NULL) { +qemu_bh_delete(vs-bh); +} buffer_free(vs-jobs_buffer); for (i = 0; i VNC_STAT_ROWS; ++i) { -- 1.7.10.4
[Qemu-devel] [PATCH 0/2] fix segfaults triggered by failed vnc handshakes
While trying to adapt Anthony Liguori's websockets patches to the current standard I ran into some segfaults. They were triggered during disconnects due to failed VNC handshakes. I have added checks to prevent them. Tim Hardeck (2): vnc: fix segfault due to failed handshake qemu queue: fix uninitialized removals qemu-queue.h |8 ++-- ui/vnc.c |4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) -- 1.7.10.4