Commit Graph

29 Commits

Author SHA1 Message Date
Ding Hui 2ddafce7f7 vnc: fix resource leak when websocket channel error
When we connect to vnc by websocket channel, and disconnect
(maybe by some network exception) before handshake,
qemu will left CLOSE_WAIT socket and never close it

After 04d2529da2 ("ui: convert VNC server to use QIOChannelSocket")
and dd154c4d9f ("io: fix handling of EOF / error conditions in websock GSource"),
the vnc call qio_channel_add_watch only care about G_IO_IN,
but mising G_IO_HUP and G_IO_ERR.
When the websocket channel get EOF or error, it cannot callback,
because the caller ignore the event, that leads to resource leak

We need handle G_IO_HUP and G_IO_ERR event, then cleanup the channel

Fixes: 04d2529da2 ("ui: convert VNC server to use QIOChannelSocket")
Fixes: dd154c4d9f ("io: fix handling of EOF / error conditions in websock GSource")
Cc: qemu-stable@nongnu.org
Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
Message-id: 20201029032241.11040-1-dinghui@sangfor.com.cn
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2020-11-04 08:25:17 +01:00
Daniel P. Berrange b76806d4ec authz: delete existing ACL implementation
The 'qemu_acl' type was a previous non-QOM based attempt to provide an
authorization facility in QEMU. Because it is non-QOM based it cannot be
created via the command line and requires special monitor commands to
manipulate it.

The new QAuthZ subclasses provide a superset of the functionality in
qemu_acl, so the latter can now be deleted. The HMP 'acl_*' monitor
commands are converted to use the new QAuthZSimple data type instead
in order to provide temporary backwards compatibility.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2019-02-26 15:32:19 +00:00
Peter Xu 1939ccdaa6 qio: non-default context for TLS handshake
A new parameter "context" is added to qio_channel_tls_handshake() is to
allow the TLS to be run on a non-default context.  Still, no functional
change.

Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-03-06 10:19:07 +00:00
Brandon Carpenter a75d6f0761 ui: Always remove an old VNC channel watch before adding a new one
Also set saved handle to zero when removing without adding a new watch.

Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
2017-10-04 13:21:53 +01:00
Daniel P. Berrange ad6374c43e ui: add tracing of VNC operations related to QIOChannel
Trace anything which opens/closes/wraps a QIOChannel in the
VNC server.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 20170921121528.23935-2-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2017-09-29 10:36:33 +02:00
Daniel P. Berrange 60e705c51c io: change the QIOTask callback signature
Currently the QIOTaskFunc signature takes an Object * for
the source, and an Error * for any error. We also need to
be able to provide a result pointer. Rather than continue
to add parameters to QIOTaskFunc, remove the existing
ones and simply pass the QIOTask object instead. This
has methods to access all the other data items required
in the callback impl.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-01-23 15:32:18 +00:00
Daniel P. Berrange 10bcfe5897 vnc: set name for all I/O channels created
Ensure that all I/O channels created for VNC are given names
to distinguish their respective roles.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-10-27 09:13:10 +02:00
Daniel P. Berrange dbee9897d5 ui: rename vnc_init_state to vnc_start_protocol
Rename the vnc_init_state method to reflect what its actual
purpose is, to discourage future devs from using it for more
general state initialization.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 1475163940-26094-10-git-send-email-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2016-10-13 09:22:31 +02:00
Paolo Bonzini 58369e22cf qemu-common: stop including qemu/bswap.h from qemu-common.h
Move it to the actual users.  There are still a few includes of
qemu/bswap.h in headers; removing them is left for future work.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-05-19 16:42:28 +02:00
Markus Armbruster da34e65cb4 include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef.  Since then, we've moved to include qemu/osdep.h
everywhere.  Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h.  That's in excess of
100KiB of crap most .c files don't actually need.

Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h.  Include qapi/error.h in .c files that need it and don't
get it now.  Include qapi-types.h in qom/object.h for uint16List.

Update scripts/clean-includes accordingly.  Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h.  Update the list of includes in the qemu/osdep.h
comment quoted above similarly.

This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third.  Unfortunately, the number depending on
qapi-types.h shrinks only a little.  More work is needed for that one.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-03-22 22:20:15 +01:00
Peter Maydell e16f4c8770 ui: Clean up includes
Clean up includes so that osdep.h is included first and headers
which it implies are not included manually.

This commit was created with scripts/clean-includes.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1454089805-5470-2-git-send-email-peter.maydell@linaro.org
2016-02-04 17:01:04 +00:00
Daniel P. Berrange d5f042232c ui: convert VNC server to use QIOChannelWebsock
Remove custom websock handling code from the VNC server and use
the QIOChannelWebsock class instead.

Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-12-18 15:02:11 +00:00
Daniel P. Berrange 2cc452281e ui: convert VNC server to use QIOChannelTLS
Switch VNC server over to using the QIOChannelTLS object for
the TLS session. This removes all remaining VNC specific code
for dealing with TLS handshakes.

Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-12-18 15:02:11 +00:00
Daniel P. Berrange 04d2529da2 ui: convert VNC server to use QIOChannelSocket
The minimal first step conversion to use QIOChannelSocket
classes instead of directly using POSIX sockets API. This
will later be extended to also cover the TLS, SASL and
websockets code.

Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-12-18 15:02:11 +00:00
Daniel P. Berrange 3e305e4a47 ui: convert VNC server to use QCryptoTLSSession
Switch VNC server over to using the QCryptoTLSSession object
for the TLS session. This removes the direct use of gnutls
from the VNC server code. It also removes most knowledge
about TLS certificate handling from the VNC server code.
This has the nice effect that all the CONFIG_VNC_TLS
conditionals go away and the user gets an actual error
message when requesting TLS instead of it being silently
ignored.

With this change, the existing configuration options for
enabling TLS with -vnc are deprecated.

Old syntax for anon-DH credentials:

  -vnc hostname:0,tls

New syntax:

  -object tls-creds-anon,id=tls0,endpoint=server \
  -vnc hostname:0,tls-creds=tls0

Old syntax for x509 credentials, no client certs:

  -vnc hostname:0,tls,x509=/path/to/certs

New syntax:

  -object tls-creds-x509,id=tls0,dir=/path/to/certs,endpoint=server,verify-peer=no \
  -vnc hostname:0,tls-creds=tls0

Old syntax for x509 credentials, requiring client certs:

  -vnc hostname:0,tls,x509verify=/path/to/certs

New syntax:

  -object tls-creds-x509,id=tls0,dir=/path/to/certs,endpoint=server,verify-peer=yes \
  -vnc hostname:0,tls-creds=tls0

This aligns VNC with the way TLS credentials are to be
configured in the future for chardev, nbd and migration
backends. It also has the benefit that the same TLS
credentials can be shared across multiple VNC server
instances, if desired.

If someone uses the deprecated syntax, it will internally
result in the creation of a 'tls-creds' object with an ID
based on the VNC server ID. This allows backwards compat
with the CLI syntax, while still deleting all the original
TLS code from the VNC server.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-09-15 15:20:55 +01:00
Daniel P. Berrange 8e9b0d24fb ui: convert VNC websockets to use crypto APIs
Remove the direct use of gnutls for hash processing in the
websockets code, in favour of using the crypto APIs. This
allows the websockets code to be built unconditionally
removing countless conditional checks from the VNC code.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1435770638-25715-9-git-send-email-berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-08 13:11:01 +02:00
Fam Zheng 82e1cc4bf9 Change qemu_set_fd_handler2(..., NULL, ...) to qemu_set_fd_handler
Done with following Coccinelle semantic patch, plus manual cosmetic changes in
net/*.c.

    @@
    expression E1, E2, E3, E4;
    @@
    -   qemu_set_fd_handler2(E1, NULL, E2, E3, E4);
    +   qemu_set_fd_handler(E1, E2, E3, E4);

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1433400324-7358-8-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-06-12 13:26:21 +01:00
Chih-Min Chao 4769a881cb ui/vnc : remove 'struct' of 'typedef struct'
Signed-off-by: Chih-Min Chao <cmchao@gmail.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Daniel P. Berrange 2cdb5e142f CVE-2015-1779: limit size of HTTP headers from websockets clients
The VNC server websockets decoder will read and buffer data from
websockets clients until it sees the end of the HTTP headers,
as indicated by \r\n\r\n. In theory this allows a malicious to
trick QEMU into consuming an arbitrary amount of RAM. In practice,
because QEMU runs g_strstr_len() across the buffered header data,
it will spend increasingly long burning CPU time searching for
the substring match and less & less time reading data. So while
this does cause arbitrary memory growth, the bigger problem is
that QEMU will be burning 100% of available CPU time.

A novnc websockets client typically sends headers of around
512 bytes in length. As such it is reasonable to place a 4096
byte limit on the amount of data buffered while searching for
the end of HTTP headers.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-01 17:12:55 +02:00
Daniel P. Berrange a2bebfd6e0 CVE-2015-1779: incrementally decode websocket frames
The logic for decoding websocket frames wants to fully
decode the frame header and payload, before allowing the
VNC server to see any of the payload data. There is no
size limit on websocket payloads, so this allows a
malicious network client to consume 2^64 bytes in memory
in QEMU. It can trigger this denial of service before
the VNC server even performs any authentication.

The fix is to decode the header, and then incrementally
decode the payload data as it is needed. With this fix
the websocket decoder will allow at most 4k of data to
be buffered before decoding and processing payload.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

[ kraxel: fix frequent spurious disconnects, suggested by Peter Maydell ]

  @@ -361,7 +361,7 @@ int vncws_decode_frame_payload(Buffer *input,
  -        *payload_size = input->offset;
  +        *payload_size = *payload_remain;

[ kraxel: fix 32bit build ]

  @@ -306,7 +306,7 @@ struct VncState
  -    uint64_t ws_payload_remain;
  +    size_t ws_payload_remain;

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-01 17:11:34 +02:00
Daniel P. Berrange 4a48aaa9f5 ui: ensure VNC websockets server checks the ACL if requested
If the x509verify option is requested, the VNC websockets server
was failing to validate that the websockets client provided an
x509 certificate matching the ACL rules.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-03-18 09:25:14 +01:00
Daniel P. Berrange 7b45a00d05 ui: remove separate gnutls_session for websockets server
The previous change to the auth scheme handling guarantees we
can never have nested TLS sessions in the VNC websockets server.
Thus we can remove the separate gnutls_session instance.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-03-18 09:25:14 +01:00
Daniel P. Berrange 51941e4695 ui: enforce TLS when using websockets server
When TLS is required, the primary VNC server considers it to be
mandatory. ie the server admin decides whether or not TLS is used,
and the client has to comply with this decision. The websockets
server, however, treated it as optional, allowing non-TLS clients
to connect to a server which had setup TLS. Thus enabling websockets
lowers the security of the VNC server leaving the admin no way to
enforce use of TLS.

This removes the code that allows non-TLS fallback in the websockets
server, so that if TLS is requested for VNC it is now mandatory for
both the primary VNC server and the websockets VNC server.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-03-18 09:25:13 +01:00
Daniel P. Berrange a2f45bc02a ui: remove unused 'wiremode' variable in VncState struct
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-03-18 09:25:13 +01:00
Jorge Acereda Maciá b57489cfe4 Fix crash when connecting to VNC through websocket
Connecting to VNC through websocket crashes in vnc_flush() when trying
to acquire a mutex that hasn't been initialized (vnc_init_state(vs)
hasn't been called at this point).

Signed-off-by: Jorge Acereda Macia <jacereda@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-03-10 11:33:42 +01:00
Alex Bligh 6a1751b7aa aio / timers: Untangle include files
include/qemu/timer.h has no need to include main-loop.h and
doing so causes an issue for the next patch. Unfortunately
various files assume including timers.h will pull in main-loop.h.
Untangle this mess.

Signed-off-by: Alex Bligh <alex@alex.org.uk>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2013-08-22 19:10:27 +02:00
Tim Hardeck 0057a0d590 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 <thardeck@suse.de>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1366727581-5772-1-git-send-email-thardeck@suse.de
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-05-03 12:04:57 -05:00
Markus Armbruster cfba8e6f92 vnc: Clean up vncws_send_handshake_response()
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 <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2013-01-30 10:31:22 +01:00
Tim Hardeck 7536ee4bc3 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 "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.

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 <thardeck@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-01-21 13:33:12 -06:00