meson.build: Declare global edk2_targets / install_edk2_blobs variables
[qemu/ar7.git] / ui / vnc.c
blobd429bfee5a65661ca31b580196a471df638a9f64
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "vnc.h"
29 #include "vnc-jobs.h"
30 #include "trace.h"
31 #include "hw/qdev-core.h"
32 #include "sysemu/sysemu.h"
33 #include "sysemu/runstate.h"
34 #include "qemu/error-report.h"
35 #include "qemu/main-loop.h"
36 #include "qemu/module.h"
37 #include "qemu/option.h"
38 #include "qemu/sockets.h"
39 #include "qemu/timer.h"
40 #include "authz/list.h"
41 #include "qemu/config-file.h"
42 #include "qapi/qapi-emit-events.h"
43 #include "qapi/qapi-events-ui.h"
44 #include "qapi/error.h"
45 #include "qapi/qapi-commands-ui.h"
46 #include "ui/input.h"
47 #include "crypto/hash.h"
48 #include "crypto/tlscredsanon.h"
49 #include "crypto/tlscredsx509.h"
50 #include "crypto/random.h"
51 #include "qom/object_interfaces.h"
52 #include "qemu/cutils.h"
53 #include "io/dns-resolver.h"
55 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
56 #define VNC_REFRESH_INTERVAL_INC 50
57 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
58 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
59 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
61 #include "vnc_keysym.h"
62 #include "crypto/cipher.h"
64 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
65 QTAILQ_HEAD_INITIALIZER(vnc_displays);
67 static int vnc_cursor_define(VncState *vs);
68 static void vnc_update_throttle_offset(VncState *vs);
70 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
72 #ifdef _VNC_DEBUG
73 static const char *mn[] = {
74 [0] = "undefined",
75 [VNC_SHARE_MODE_CONNECTING] = "connecting",
76 [VNC_SHARE_MODE_SHARED] = "shared",
77 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
78 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
80 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
81 vs->ioc, mn[vs->share_mode], mn[mode]);
82 #endif
84 switch (vs->share_mode) {
85 case VNC_SHARE_MODE_CONNECTING:
86 vs->vd->num_connecting--;
87 break;
88 case VNC_SHARE_MODE_SHARED:
89 vs->vd->num_shared--;
90 break;
91 case VNC_SHARE_MODE_EXCLUSIVE:
92 vs->vd->num_exclusive--;
93 break;
94 default:
95 break;
98 vs->share_mode = mode;
100 switch (vs->share_mode) {
101 case VNC_SHARE_MODE_CONNECTING:
102 vs->vd->num_connecting++;
103 break;
104 case VNC_SHARE_MODE_SHARED:
105 vs->vd->num_shared++;
106 break;
107 case VNC_SHARE_MODE_EXCLUSIVE:
108 vs->vd->num_exclusive++;
109 break;
110 default:
111 break;
116 static void vnc_init_basic_info(SocketAddress *addr,
117 VncBasicInfo *info,
118 Error **errp)
120 switch (addr->type) {
121 case SOCKET_ADDRESS_TYPE_INET:
122 info->host = g_strdup(addr->u.inet.host);
123 info->service = g_strdup(addr->u.inet.port);
124 if (addr->u.inet.ipv6) {
125 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
126 } else {
127 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
129 break;
131 case SOCKET_ADDRESS_TYPE_UNIX:
132 info->host = g_strdup("");
133 info->service = g_strdup(addr->u.q_unix.path);
134 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
135 break;
137 case SOCKET_ADDRESS_TYPE_VSOCK:
138 case SOCKET_ADDRESS_TYPE_FD:
139 error_setg(errp, "Unsupported socket address type %s",
140 SocketAddressType_str(addr->type));
141 break;
142 default:
143 abort();
146 return;
149 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
150 VncBasicInfo *info,
151 Error **errp)
153 SocketAddress *addr = NULL;
155 if (!ioc) {
156 error_setg(errp, "No listener socket available");
157 return;
160 addr = qio_channel_socket_get_local_address(ioc, errp);
161 if (!addr) {
162 return;
165 vnc_init_basic_info(addr, info, errp);
166 qapi_free_SocketAddress(addr);
169 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
170 VncBasicInfo *info,
171 Error **errp)
173 SocketAddress *addr = NULL;
175 addr = qio_channel_socket_get_remote_address(ioc, errp);
176 if (!addr) {
177 return;
180 vnc_init_basic_info(addr, info, errp);
181 qapi_free_SocketAddress(addr);
184 static const char *vnc_auth_name(VncDisplay *vd) {
185 switch (vd->auth) {
186 case VNC_AUTH_INVALID:
187 return "invalid";
188 case VNC_AUTH_NONE:
189 return "none";
190 case VNC_AUTH_VNC:
191 return "vnc";
192 case VNC_AUTH_RA2:
193 return "ra2";
194 case VNC_AUTH_RA2NE:
195 return "ra2ne";
196 case VNC_AUTH_TIGHT:
197 return "tight";
198 case VNC_AUTH_ULTRA:
199 return "ultra";
200 case VNC_AUTH_TLS:
201 return "tls";
202 case VNC_AUTH_VENCRYPT:
203 switch (vd->subauth) {
204 case VNC_AUTH_VENCRYPT_PLAIN:
205 return "vencrypt+plain";
206 case VNC_AUTH_VENCRYPT_TLSNONE:
207 return "vencrypt+tls+none";
208 case VNC_AUTH_VENCRYPT_TLSVNC:
209 return "vencrypt+tls+vnc";
210 case VNC_AUTH_VENCRYPT_TLSPLAIN:
211 return "vencrypt+tls+plain";
212 case VNC_AUTH_VENCRYPT_X509NONE:
213 return "vencrypt+x509+none";
214 case VNC_AUTH_VENCRYPT_X509VNC:
215 return "vencrypt+x509+vnc";
216 case VNC_AUTH_VENCRYPT_X509PLAIN:
217 return "vencrypt+x509+plain";
218 case VNC_AUTH_VENCRYPT_TLSSASL:
219 return "vencrypt+tls+sasl";
220 case VNC_AUTH_VENCRYPT_X509SASL:
221 return "vencrypt+x509+sasl";
222 default:
223 return "vencrypt";
225 case VNC_AUTH_SASL:
226 return "sasl";
228 return "unknown";
231 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
233 VncServerInfo *info;
234 Error *err = NULL;
236 if (!vd->listener || !vd->listener->nsioc) {
237 return NULL;
240 info = g_malloc0(sizeof(*info));
241 vnc_init_basic_info_from_server_addr(vd->listener->sioc[0],
242 qapi_VncServerInfo_base(info), &err);
243 info->has_auth = true;
244 info->auth = g_strdup(vnc_auth_name(vd));
245 if (err) {
246 qapi_free_VncServerInfo(info);
247 info = NULL;
248 error_free(err);
250 return info;
253 static void vnc_client_cache_auth(VncState *client)
255 if (!client->info) {
256 return;
259 if (client->tls) {
260 client->info->x509_dname =
261 qcrypto_tls_session_get_peer_name(client->tls);
262 client->info->has_x509_dname =
263 client->info->x509_dname != NULL;
265 #ifdef CONFIG_VNC_SASL
266 if (client->sasl.conn &&
267 client->sasl.username) {
268 client->info->has_sasl_username = true;
269 client->info->sasl_username = g_strdup(client->sasl.username);
271 #endif
274 static void vnc_client_cache_addr(VncState *client)
276 Error *err = NULL;
278 client->info = g_malloc0(sizeof(*client->info));
279 vnc_init_basic_info_from_remote_addr(client->sioc,
280 qapi_VncClientInfo_base(client->info),
281 &err);
282 client->info->websocket = client->websocket;
283 if (err) {
284 qapi_free_VncClientInfo(client->info);
285 client->info = NULL;
286 error_free(err);
290 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
292 VncServerInfo *si;
294 if (!vs->info) {
295 return;
298 si = vnc_server_info_get(vs->vd);
299 if (!si) {
300 return;
303 switch (event) {
304 case QAPI_EVENT_VNC_CONNECTED:
305 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info));
306 break;
307 case QAPI_EVENT_VNC_INITIALIZED:
308 qapi_event_send_vnc_initialized(si, vs->info);
309 break;
310 case QAPI_EVENT_VNC_DISCONNECTED:
311 qapi_event_send_vnc_disconnected(si, vs->info);
312 break;
313 default:
314 break;
317 qapi_free_VncServerInfo(si);
320 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
322 VncClientInfo *info;
323 Error *err = NULL;
325 info = g_malloc0(sizeof(*info));
327 vnc_init_basic_info_from_remote_addr(client->sioc,
328 qapi_VncClientInfo_base(info),
329 &err);
330 if (err) {
331 error_free(err);
332 qapi_free_VncClientInfo(info);
333 return NULL;
336 info->websocket = client->websocket;
338 if (client->tls) {
339 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
340 info->has_x509_dname = info->x509_dname != NULL;
342 #ifdef CONFIG_VNC_SASL
343 if (client->sasl.conn && client->sasl.username) {
344 info->has_sasl_username = true;
345 info->sasl_username = g_strdup(client->sasl.username);
347 #endif
349 return info;
352 static VncDisplay *vnc_display_find(const char *id)
354 VncDisplay *vd;
356 if (id == NULL) {
357 return QTAILQ_FIRST(&vnc_displays);
359 QTAILQ_FOREACH(vd, &vnc_displays, next) {
360 if (strcmp(id, vd->id) == 0) {
361 return vd;
364 return NULL;
367 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
369 VncClientInfoList *prev = NULL;
370 VncState *client;
372 QTAILQ_FOREACH(client, &vd->clients, next) {
373 QAPI_LIST_PREPEND(prev, qmp_query_vnc_client(client));
375 return prev;
378 VncInfo *qmp_query_vnc(Error **errp)
380 VncInfo *info = g_malloc0(sizeof(*info));
381 VncDisplay *vd = vnc_display_find(NULL);
382 SocketAddress *addr = NULL;
384 if (vd == NULL || !vd->listener || !vd->listener->nsioc) {
385 info->enabled = false;
386 } else {
387 info->enabled = true;
389 /* for compatibility with the original command */
390 info->has_clients = true;
391 info->clients = qmp_query_client_list(vd);
393 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0],
394 errp);
395 if (!addr) {
396 goto out_error;
399 switch (addr->type) {
400 case SOCKET_ADDRESS_TYPE_INET:
401 info->host = g_strdup(addr->u.inet.host);
402 info->service = g_strdup(addr->u.inet.port);
403 if (addr->u.inet.ipv6) {
404 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
405 } else {
406 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
408 break;
410 case SOCKET_ADDRESS_TYPE_UNIX:
411 info->host = g_strdup("");
412 info->service = g_strdup(addr->u.q_unix.path);
413 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
414 break;
416 case SOCKET_ADDRESS_TYPE_VSOCK:
417 case SOCKET_ADDRESS_TYPE_FD:
418 error_setg(errp, "Unsupported socket address type %s",
419 SocketAddressType_str(addr->type));
420 goto out_error;
421 default:
422 abort();
425 info->has_host = true;
426 info->has_service = true;
427 info->has_family = true;
429 info->has_auth = true;
430 info->auth = g_strdup(vnc_auth_name(vd));
433 qapi_free_SocketAddress(addr);
434 return info;
436 out_error:
437 qapi_free_SocketAddress(addr);
438 qapi_free_VncInfo(info);
439 return NULL;
443 static void qmp_query_auth(int auth, int subauth,
444 VncPrimaryAuth *qmp_auth,
445 VncVencryptSubAuth *qmp_vencrypt,
446 bool *qmp_has_vencrypt);
448 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
449 bool websocket,
450 int auth,
451 int subauth,
452 VncServerInfo2List *prev)
454 VncServerInfo2 *info;
455 Error *err = NULL;
456 SocketAddress *addr;
458 addr = qio_channel_socket_get_local_address(ioc, NULL);
459 if (!addr) {
460 return prev;
463 info = g_new0(VncServerInfo2, 1);
464 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
465 qapi_free_SocketAddress(addr);
466 if (err) {
467 qapi_free_VncServerInfo2(info);
468 error_free(err);
469 return prev;
471 info->websocket = websocket;
473 qmp_query_auth(auth, subauth, &info->auth,
474 &info->vencrypt, &info->has_vencrypt);
476 QAPI_LIST_PREPEND(prev, info);
477 return prev;
480 static void qmp_query_auth(int auth, int subauth,
481 VncPrimaryAuth *qmp_auth,
482 VncVencryptSubAuth *qmp_vencrypt,
483 bool *qmp_has_vencrypt)
485 switch (auth) {
486 case VNC_AUTH_VNC:
487 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
488 break;
489 case VNC_AUTH_RA2:
490 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
491 break;
492 case VNC_AUTH_RA2NE:
493 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
494 break;
495 case VNC_AUTH_TIGHT:
496 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
497 break;
498 case VNC_AUTH_ULTRA:
499 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
500 break;
501 case VNC_AUTH_TLS:
502 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
503 break;
504 case VNC_AUTH_VENCRYPT:
505 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
506 *qmp_has_vencrypt = true;
507 switch (subauth) {
508 case VNC_AUTH_VENCRYPT_PLAIN:
509 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
510 break;
511 case VNC_AUTH_VENCRYPT_TLSNONE:
512 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
513 break;
514 case VNC_AUTH_VENCRYPT_TLSVNC:
515 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
516 break;
517 case VNC_AUTH_VENCRYPT_TLSPLAIN:
518 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
519 break;
520 case VNC_AUTH_VENCRYPT_X509NONE:
521 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
522 break;
523 case VNC_AUTH_VENCRYPT_X509VNC:
524 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
525 break;
526 case VNC_AUTH_VENCRYPT_X509PLAIN:
527 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
528 break;
529 case VNC_AUTH_VENCRYPT_TLSSASL:
530 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
531 break;
532 case VNC_AUTH_VENCRYPT_X509SASL:
533 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
534 break;
535 default:
536 *qmp_has_vencrypt = false;
537 break;
539 break;
540 case VNC_AUTH_SASL:
541 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
542 break;
543 case VNC_AUTH_NONE:
544 default:
545 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
546 break;
550 VncInfo2List *qmp_query_vnc_servers(Error **errp)
552 VncInfo2List *prev = NULL;
553 VncInfo2 *info;
554 VncDisplay *vd;
555 DeviceState *dev;
556 size_t i;
558 QTAILQ_FOREACH(vd, &vnc_displays, next) {
559 info = g_new0(VncInfo2, 1);
560 info->id = g_strdup(vd->id);
561 info->clients = qmp_query_client_list(vd);
562 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
563 &info->vencrypt, &info->has_vencrypt);
564 if (vd->dcl.con) {
565 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
566 "device", &error_abort));
567 info->has_display = true;
568 info->display = g_strdup(dev->id);
570 for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) {
571 info->server = qmp_query_server_entry(
572 vd->listener->sioc[i], false, vd->auth, vd->subauth,
573 info->server);
575 for (i = 0; vd->wslistener != NULL && i < vd->wslistener->nsioc; i++) {
576 info->server = qmp_query_server_entry(
577 vd->wslistener->sioc[i], true, vd->ws_auth,
578 vd->ws_subauth, info->server);
581 QAPI_LIST_PREPEND(prev, info);
583 return prev;
586 /* TODO
587 1) Get the queue working for IO.
588 2) there is some weirdness when using the -S option (the screen is grey
589 and not totally invalidated
590 3) resolutions > 1024
593 static int vnc_update_client(VncState *vs, int has_dirty);
594 static void vnc_disconnect_start(VncState *vs);
596 static void vnc_colordepth(VncState *vs);
597 static void framebuffer_update_request(VncState *vs, int incremental,
598 int x_position, int y_position,
599 int w, int h);
600 static void vnc_refresh(DisplayChangeListener *dcl);
601 static int vnc_refresh_server_surface(VncDisplay *vd);
603 static int vnc_width(VncDisplay *vd)
605 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
606 VNC_DIRTY_PIXELS_PER_BIT));
609 static int vnc_height(VncDisplay *vd)
611 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
614 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
615 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
616 VncDisplay *vd,
617 int x, int y, int w, int h)
619 int width = vnc_width(vd);
620 int height = vnc_height(vd);
622 /* this is needed this to ensure we updated all affected
623 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
624 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
625 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
627 x = MIN(x, width);
628 y = MIN(y, height);
629 w = MIN(x + w, width) - x;
630 h = MIN(y + h, height);
632 for (; y < h; y++) {
633 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
634 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
638 static void vnc_dpy_update(DisplayChangeListener *dcl,
639 int x, int y, int w, int h)
641 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
642 struct VncSurface *s = &vd->guest;
644 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
647 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
648 int32_t encoding)
650 vnc_write_u16(vs, x);
651 vnc_write_u16(vs, y);
652 vnc_write_u16(vs, w);
653 vnc_write_u16(vs, h);
655 vnc_write_s32(vs, encoding);
658 static void vnc_desktop_resize_ext(VncState *vs, int reject_reason)
660 vnc_lock_output(vs);
661 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
662 vnc_write_u8(vs, 0);
663 vnc_write_u16(vs, 1); /* number of rects */
664 vnc_framebuffer_update(vs,
665 reject_reason ? 1 : 0,
666 reject_reason,
667 vs->client_width, vs->client_height,
668 VNC_ENCODING_DESKTOP_RESIZE_EXT);
669 vnc_write_u8(vs, 1); /* number of screens */
670 vnc_write_u8(vs, 0); /* padding */
671 vnc_write_u8(vs, 0); /* padding */
672 vnc_write_u8(vs, 0); /* padding */
673 vnc_write_u32(vs, 0); /* screen id */
674 vnc_write_u16(vs, 0); /* screen x-pos */
675 vnc_write_u16(vs, 0); /* screen y-pos */
676 vnc_write_u16(vs, vs->client_width);
677 vnc_write_u16(vs, vs->client_height);
678 vnc_write_u32(vs, 0); /* screen flags */
679 vnc_unlock_output(vs);
680 vnc_flush(vs);
683 static void vnc_desktop_resize(VncState *vs)
685 if (vs->ioc == NULL || (!vnc_has_feature(vs, VNC_FEATURE_RESIZE) &&
686 !vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT))) {
687 return;
690 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
691 pixman_image_get_width(vs->vd->server) >= 0);
692 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
693 pixman_image_get_height(vs->vd->server) >= 0);
694 vs->client_width = pixman_image_get_width(vs->vd->server);
695 vs->client_height = pixman_image_get_height(vs->vd->server);
697 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
698 vnc_desktop_resize_ext(vs, 0);
699 return;
702 vnc_lock_output(vs);
703 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
704 vnc_write_u8(vs, 0);
705 vnc_write_u16(vs, 1); /* number of rects */
706 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
707 VNC_ENCODING_DESKTOPRESIZE);
708 vnc_unlock_output(vs);
709 vnc_flush(vs);
712 static void vnc_abort_display_jobs(VncDisplay *vd)
714 VncState *vs;
716 QTAILQ_FOREACH(vs, &vd->clients, next) {
717 vnc_lock_output(vs);
718 vs->abort = true;
719 vnc_unlock_output(vs);
721 QTAILQ_FOREACH(vs, &vd->clients, next) {
722 vnc_jobs_join(vs);
724 QTAILQ_FOREACH(vs, &vd->clients, next) {
725 vnc_lock_output(vs);
726 if (vs->update == VNC_STATE_UPDATE_NONE &&
727 vs->job_update != VNC_STATE_UPDATE_NONE) {
728 /* job aborted before completion */
729 vs->update = vs->job_update;
730 vs->job_update = VNC_STATE_UPDATE_NONE;
732 vs->abort = false;
733 vnc_unlock_output(vs);
737 int vnc_server_fb_stride(VncDisplay *vd)
739 return pixman_image_get_stride(vd->server);
742 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
744 uint8_t *ptr;
746 ptr = (uint8_t *)pixman_image_get_data(vd->server);
747 ptr += y * vnc_server_fb_stride(vd);
748 ptr += x * VNC_SERVER_FB_BYTES;
749 return ptr;
752 static void vnc_update_server_surface(VncDisplay *vd)
754 int width, height;
756 qemu_pixman_image_unref(vd->server);
757 vd->server = NULL;
759 if (QTAILQ_EMPTY(&vd->clients)) {
760 return;
763 width = vnc_width(vd);
764 height = vnc_height(vd);
765 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
766 width, height,
767 NULL, 0);
769 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
770 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
771 width, height);
774 static bool vnc_check_pageflip(DisplaySurface *s1,
775 DisplaySurface *s2)
777 return (s1 != NULL &&
778 s2 != NULL &&
779 surface_width(s1) == surface_width(s2) &&
780 surface_height(s1) == surface_height(s2) &&
781 surface_format(s1) == surface_format(s2));
785 static void vnc_dpy_switch(DisplayChangeListener *dcl,
786 DisplaySurface *surface)
788 static const char placeholder_msg[] =
789 "Display output is not active.";
790 static DisplaySurface *placeholder;
791 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
792 bool pageflip = vnc_check_pageflip(vd->ds, surface);
793 VncState *vs;
795 if (surface == NULL) {
796 if (placeholder == NULL) {
797 placeholder = qemu_create_message_surface(640, 480, placeholder_msg);
799 surface = placeholder;
802 vnc_abort_display_jobs(vd);
803 vd->ds = surface;
805 /* guest surface */
806 qemu_pixman_image_unref(vd->guest.fb);
807 vd->guest.fb = pixman_image_ref(surface->image);
808 vd->guest.format = surface->format;
810 if (pageflip) {
811 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
812 surface_width(surface),
813 surface_height(surface));
814 return;
817 /* server surface */
818 vnc_update_server_surface(vd);
820 QTAILQ_FOREACH(vs, &vd->clients, next) {
821 vnc_colordepth(vs);
822 vnc_desktop_resize(vs);
823 vnc_cursor_define(vs);
824 memset(vs->dirty, 0x00, sizeof(vs->dirty));
825 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
826 vnc_width(vd),
827 vnc_height(vd));
828 vnc_update_throttle_offset(vs);
832 /* fastest code */
833 static void vnc_write_pixels_copy(VncState *vs,
834 void *pixels, int size)
836 vnc_write(vs, pixels, size);
839 /* slowest but generic code. */
840 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
842 uint8_t r, g, b;
844 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
845 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
846 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
847 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
848 #else
849 # error need some bits here if you change VNC_SERVER_FB_FORMAT
850 #endif
851 v = (r << vs->client_pf.rshift) |
852 (g << vs->client_pf.gshift) |
853 (b << vs->client_pf.bshift);
854 switch (vs->client_pf.bytes_per_pixel) {
855 case 1:
856 buf[0] = v;
857 break;
858 case 2:
859 if (vs->client_be) {
860 buf[0] = v >> 8;
861 buf[1] = v;
862 } else {
863 buf[1] = v >> 8;
864 buf[0] = v;
866 break;
867 default:
868 case 4:
869 if (vs->client_be) {
870 buf[0] = v >> 24;
871 buf[1] = v >> 16;
872 buf[2] = v >> 8;
873 buf[3] = v;
874 } else {
875 buf[3] = v >> 24;
876 buf[2] = v >> 16;
877 buf[1] = v >> 8;
878 buf[0] = v;
880 break;
884 static void vnc_write_pixels_generic(VncState *vs,
885 void *pixels1, int size)
887 uint8_t buf[4];
889 if (VNC_SERVER_FB_BYTES == 4) {
890 uint32_t *pixels = pixels1;
891 int n, i;
892 n = size >> 2;
893 for (i = 0; i < n; i++) {
894 vnc_convert_pixel(vs, buf, pixels[i]);
895 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
900 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
902 int i;
903 uint8_t *row;
904 VncDisplay *vd = vs->vd;
906 row = vnc_server_fb_ptr(vd, x, y);
907 for (i = 0; i < h; i++) {
908 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
909 row += vnc_server_fb_stride(vd);
911 return 1;
914 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
916 int n = 0;
918 switch(vs->vnc_encoding) {
919 case VNC_ENCODING_ZLIB:
920 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
921 break;
922 case VNC_ENCODING_HEXTILE:
923 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
924 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
925 break;
926 case VNC_ENCODING_TIGHT:
927 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
928 break;
929 case VNC_ENCODING_TIGHT_PNG:
930 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
931 break;
932 case VNC_ENCODING_ZRLE:
933 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
934 break;
935 case VNC_ENCODING_ZYWRLE:
936 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
937 break;
938 default:
939 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
940 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
941 break;
943 return n;
946 static void vnc_mouse_set(DisplayChangeListener *dcl,
947 int x, int y, int visible)
949 /* can we ask the client(s) to move the pointer ??? */
952 static int vnc_cursor_define(VncState *vs)
954 QEMUCursor *c = vs->vd->cursor;
955 int isize;
957 if (!vs->vd->cursor) {
958 return -1;
961 if (vnc_has_feature(vs, VNC_FEATURE_ALPHA_CURSOR)) {
962 vnc_lock_output(vs);
963 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
964 vnc_write_u8(vs, 0); /* padding */
965 vnc_write_u16(vs, 1); /* # of rects */
966 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
967 VNC_ENCODING_ALPHA_CURSOR);
968 vnc_write_s32(vs, VNC_ENCODING_RAW);
969 vnc_write(vs, c->data, c->width * c->height * 4);
970 vnc_unlock_output(vs);
971 return 0;
973 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
974 vnc_lock_output(vs);
975 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
976 vnc_write_u8(vs, 0); /* padding */
977 vnc_write_u16(vs, 1); /* # of rects */
978 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
979 VNC_ENCODING_RICH_CURSOR);
980 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
981 vnc_write_pixels_generic(vs, c->data, isize);
982 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
983 vnc_unlock_output(vs);
984 return 0;
986 return -1;
989 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
990 QEMUCursor *c)
992 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
993 VncState *vs;
995 cursor_put(vd->cursor);
996 g_free(vd->cursor_mask);
998 vd->cursor = c;
999 cursor_get(vd->cursor);
1000 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1001 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1002 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1004 QTAILQ_FOREACH(vs, &vd->clients, next) {
1005 vnc_cursor_define(vs);
1009 static int find_and_clear_dirty_height(VncState *vs,
1010 int y, int last_x, int x, int height)
1012 int h;
1014 for (h = 1; h < (height - y); h++) {
1015 if (!test_bit(last_x, vs->dirty[y + h])) {
1016 break;
1018 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1021 return h;
1025 * Figure out how much pending data we should allow in the output
1026 * buffer before we throttle incremental display updates, and/or
1027 * drop audio samples.
1029 * We allow for equiv of 1 full display's worth of FB updates,
1030 * and 1 second of audio samples. If audio backlog was larger
1031 * than that the client would already suffering awful audio
1032 * glitches, so dropping samples is no worse really).
1034 static void vnc_update_throttle_offset(VncState *vs)
1036 size_t offset =
1037 vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
1039 if (vs->audio_cap) {
1040 int bps;
1041 switch (vs->as.fmt) {
1042 default:
1043 case AUDIO_FORMAT_U8:
1044 case AUDIO_FORMAT_S8:
1045 bps = 1;
1046 break;
1047 case AUDIO_FORMAT_U16:
1048 case AUDIO_FORMAT_S16:
1049 bps = 2;
1050 break;
1051 case AUDIO_FORMAT_U32:
1052 case AUDIO_FORMAT_S32:
1053 bps = 4;
1054 break;
1056 offset += vs->as.freq * bps * vs->as.nchannels;
1059 /* Put a floor of 1MB on offset, so that if we have a large pending
1060 * buffer and the display is resized to a small size & back again
1061 * we don't suddenly apply a tiny send limit
1063 offset = MAX(offset, 1024 * 1024);
1065 if (vs->throttle_output_offset != offset) {
1066 trace_vnc_client_throttle_threshold(
1067 vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
1068 vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
1071 vs->throttle_output_offset = offset;
1074 static bool vnc_should_update(VncState *vs)
1076 switch (vs->update) {
1077 case VNC_STATE_UPDATE_NONE:
1078 break;
1079 case VNC_STATE_UPDATE_INCREMENTAL:
1080 /* Only allow incremental updates if the pending send queue
1081 * is less than the permitted threshold, and the job worker
1082 * is completely idle.
1084 if (vs->output.offset < vs->throttle_output_offset &&
1085 vs->job_update == VNC_STATE_UPDATE_NONE) {
1086 return true;
1088 trace_vnc_client_throttle_incremental(
1089 vs, vs->ioc, vs->job_update, vs->output.offset);
1090 break;
1091 case VNC_STATE_UPDATE_FORCE:
1092 /* Only allow forced updates if the pending send queue
1093 * does not contain a previous forced update, and the
1094 * job worker is completely idle.
1096 * Note this means we'll queue a forced update, even if
1097 * the output buffer size is otherwise over the throttle
1098 * output limit.
1100 if (vs->force_update_offset == 0 &&
1101 vs->job_update == VNC_STATE_UPDATE_NONE) {
1102 return true;
1104 trace_vnc_client_throttle_forced(
1105 vs, vs->ioc, vs->job_update, vs->force_update_offset);
1106 break;
1108 return false;
1111 static int vnc_update_client(VncState *vs, int has_dirty)
1113 VncDisplay *vd = vs->vd;
1114 VncJob *job;
1115 int y;
1116 int height, width;
1117 int n = 0;
1119 if (vs->disconnecting) {
1120 vnc_disconnect_finish(vs);
1121 return 0;
1124 vs->has_dirty += has_dirty;
1125 if (!vnc_should_update(vs)) {
1126 return 0;
1129 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
1130 return 0;
1134 * Send screen updates to the vnc client using the server
1135 * surface and server dirty map. guest surface updates
1136 * happening in parallel don't disturb us, the next pass will
1137 * send them to the client.
1139 job = vnc_job_new(vs);
1141 height = pixman_image_get_height(vd->server);
1142 width = pixman_image_get_width(vd->server);
1144 y = 0;
1145 for (;;) {
1146 int x, h;
1147 unsigned long x2;
1148 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1149 height * VNC_DIRTY_BPL(vs),
1150 y * VNC_DIRTY_BPL(vs));
1151 if (offset == height * VNC_DIRTY_BPL(vs)) {
1152 /* no more dirty bits */
1153 break;
1155 y = offset / VNC_DIRTY_BPL(vs);
1156 x = offset % VNC_DIRTY_BPL(vs);
1157 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1158 VNC_DIRTY_BPL(vs), x);
1159 bitmap_clear(vs->dirty[y], x, x2 - x);
1160 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1161 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1162 if (x2 > x) {
1163 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1164 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1166 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1167 y += h;
1168 if (y == height) {
1169 break;
1174 vs->job_update = vs->update;
1175 vs->update = VNC_STATE_UPDATE_NONE;
1176 vnc_job_push(job);
1177 vs->has_dirty = 0;
1178 return n;
1181 /* audio */
1182 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1184 VncState *vs = opaque;
1186 assert(vs->magic == VNC_MAGIC);
1187 switch (cmd) {
1188 case AUD_CNOTIFY_DISABLE:
1189 vnc_lock_output(vs);
1190 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1191 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1192 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1193 vnc_unlock_output(vs);
1194 vnc_flush(vs);
1195 break;
1197 case AUD_CNOTIFY_ENABLE:
1198 vnc_lock_output(vs);
1199 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1200 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1201 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1202 vnc_unlock_output(vs);
1203 vnc_flush(vs);
1204 break;
1208 static void audio_capture_destroy(void *opaque)
1212 static void audio_capture(void *opaque, const void *buf, int size)
1214 VncState *vs = opaque;
1216 assert(vs->magic == VNC_MAGIC);
1217 vnc_lock_output(vs);
1218 if (vs->output.offset < vs->throttle_output_offset) {
1219 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1220 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1221 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1222 vnc_write_u32(vs, size);
1223 vnc_write(vs, buf, size);
1224 } else {
1225 trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
1227 vnc_unlock_output(vs);
1228 vnc_flush(vs);
1231 static void audio_add(VncState *vs)
1233 struct audio_capture_ops ops;
1235 if (vs->audio_cap) {
1236 error_report("audio already running");
1237 return;
1240 ops.notify = audio_capture_notify;
1241 ops.destroy = audio_capture_destroy;
1242 ops.capture = audio_capture;
1244 vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs);
1245 if (!vs->audio_cap) {
1246 error_report("Failed to add audio capture");
1250 static void audio_del(VncState *vs)
1252 if (vs->audio_cap) {
1253 AUD_del_capture(vs->audio_cap, vs);
1254 vs->audio_cap = NULL;
1258 static void vnc_disconnect_start(VncState *vs)
1260 if (vs->disconnecting) {
1261 return;
1263 trace_vnc_client_disconnect_start(vs, vs->ioc);
1264 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1265 if (vs->ioc_tag) {
1266 g_source_remove(vs->ioc_tag);
1267 vs->ioc_tag = 0;
1269 qio_channel_close(vs->ioc, NULL);
1270 vs->disconnecting = TRUE;
1273 void vnc_disconnect_finish(VncState *vs)
1275 int i;
1277 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1279 vnc_jobs_join(vs); /* Wait encoding jobs */
1281 vnc_lock_output(vs);
1282 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1284 buffer_free(&vs->input);
1285 buffer_free(&vs->output);
1287 qapi_free_VncClientInfo(vs->info);
1289 vnc_zlib_clear(vs);
1290 vnc_tight_clear(vs);
1291 vnc_zrle_clear(vs);
1293 #ifdef CONFIG_VNC_SASL
1294 vnc_sasl_client_cleanup(vs);
1295 #endif /* CONFIG_VNC_SASL */
1296 audio_del(vs);
1297 qkbd_state_lift_all_keys(vs->vd->kbd);
1299 if (vs->mouse_mode_notifier.notify != NULL) {
1300 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1302 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1303 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1304 /* last client gone */
1305 vnc_update_server_surface(vs->vd);
1308 vnc_unlock_output(vs);
1310 qemu_mutex_destroy(&vs->output_mutex);
1311 if (vs->bh != NULL) {
1312 qemu_bh_delete(vs->bh);
1314 buffer_free(&vs->jobs_buffer);
1316 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1317 g_free(vs->lossy_rect[i]);
1319 g_free(vs->lossy_rect);
1321 object_unref(OBJECT(vs->ioc));
1322 vs->ioc = NULL;
1323 object_unref(OBJECT(vs->sioc));
1324 vs->sioc = NULL;
1325 vs->magic = 0;
1326 g_free(vs->zrle);
1327 g_free(vs->tight);
1328 g_free(vs);
1331 size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err)
1333 if (ret <= 0) {
1334 if (ret == 0) {
1335 trace_vnc_client_eof(vs, vs->ioc);
1336 vnc_disconnect_start(vs);
1337 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1338 trace_vnc_client_io_error(vs, vs->ioc,
1339 err ? error_get_pretty(err) : "Unknown");
1340 vnc_disconnect_start(vs);
1343 error_free(err);
1344 return 0;
1346 return ret;
1350 void vnc_client_error(VncState *vs)
1352 VNC_DEBUG("Closing down client sock: protocol error\n");
1353 vnc_disconnect_start(vs);
1358 * Called to write a chunk of data to the client socket. The data may
1359 * be the raw data, or may have already been encoded by SASL.
1360 * The data will be written either straight onto the socket, or
1361 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1363 * NB, it is theoretically possible to have 2 layers of encryption,
1364 * both SASL, and this TLS layer. It is highly unlikely in practice
1365 * though, since SASL encryption will typically be a no-op if TLS
1366 * is active
1368 * Returns the number of bytes written, which may be less than
1369 * the requested 'datalen' if the socket would block. Returns
1370 * 0 on I/O error, and disconnects the client socket.
1372 size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1374 Error *err = NULL;
1375 ssize_t ret;
1376 ret = qio_channel_write(vs->ioc, (const char *)data, datalen, &err);
1377 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1378 return vnc_client_io_error(vs, ret, err);
1383 * Called to write buffered data to the client socket, when not
1384 * using any SASL SSF encryption layers. Will write as much data
1385 * as possible without blocking. If all buffered data is written,
1386 * will switch the FD poll() handler back to read monitoring.
1388 * Returns the number of bytes written, which may be less than
1389 * the buffered output data if the socket would block. Returns
1390 * 0 on I/O error, and disconnects the client socket.
1392 static size_t vnc_client_write_plain(VncState *vs)
1394 size_t offset;
1395 size_t ret;
1397 #ifdef CONFIG_VNC_SASL
1398 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1399 vs->output.buffer, vs->output.capacity, vs->output.offset,
1400 vs->sasl.waitWriteSSF);
1402 if (vs->sasl.conn &&
1403 vs->sasl.runSSF &&
1404 vs->sasl.waitWriteSSF) {
1405 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1406 if (ret)
1407 vs->sasl.waitWriteSSF -= ret;
1408 } else
1409 #endif /* CONFIG_VNC_SASL */
1410 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1411 if (!ret)
1412 return 0;
1414 if (ret >= vs->force_update_offset) {
1415 if (vs->force_update_offset != 0) {
1416 trace_vnc_client_unthrottle_forced(vs, vs->ioc);
1418 vs->force_update_offset = 0;
1419 } else {
1420 vs->force_update_offset -= ret;
1422 offset = vs->output.offset;
1423 buffer_advance(&vs->output, ret);
1424 if (offset >= vs->throttle_output_offset &&
1425 vs->output.offset < vs->throttle_output_offset) {
1426 trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
1429 if (vs->output.offset == 0) {
1430 if (vs->ioc_tag) {
1431 g_source_remove(vs->ioc_tag);
1433 vs->ioc_tag = qio_channel_add_watch(
1434 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1435 vnc_client_io, vs, NULL);
1438 return ret;
1443 * First function called whenever there is data to be written to
1444 * the client socket. Will delegate actual work according to whether
1445 * SASL SSF layers are enabled (thus requiring encryption calls)
1447 static void vnc_client_write_locked(VncState *vs)
1449 #ifdef CONFIG_VNC_SASL
1450 if (vs->sasl.conn &&
1451 vs->sasl.runSSF &&
1452 !vs->sasl.waitWriteSSF) {
1453 vnc_client_write_sasl(vs);
1454 } else
1455 #endif /* CONFIG_VNC_SASL */
1457 vnc_client_write_plain(vs);
1461 static void vnc_client_write(VncState *vs)
1463 assert(vs->magic == VNC_MAGIC);
1464 vnc_lock_output(vs);
1465 if (vs->output.offset) {
1466 vnc_client_write_locked(vs);
1467 } else if (vs->ioc != NULL) {
1468 if (vs->ioc_tag) {
1469 g_source_remove(vs->ioc_tag);
1471 vs->ioc_tag = qio_channel_add_watch(
1472 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1473 vnc_client_io, vs, NULL);
1475 vnc_unlock_output(vs);
1478 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1480 vs->read_handler = func;
1481 vs->read_handler_expect = expecting;
1486 * Called to read a chunk of data from the client socket. The data may
1487 * be the raw data, or may need to be further decoded by SASL.
1488 * The data will be read either straight from to the socket, or
1489 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1491 * NB, it is theoretically possible to have 2 layers of encryption,
1492 * both SASL, and this TLS layer. It is highly unlikely in practice
1493 * though, since SASL encryption will typically be a no-op if TLS
1494 * is active
1496 * Returns the number of bytes read, which may be less than
1497 * the requested 'datalen' if the socket would block. Returns
1498 * 0 on I/O error or EOF, and disconnects the client socket.
1500 size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1502 ssize_t ret;
1503 Error *err = NULL;
1504 ret = qio_channel_read(vs->ioc, (char *)data, datalen, &err);
1505 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1506 return vnc_client_io_error(vs, ret, err);
1511 * Called to read data from the client socket to the input buffer,
1512 * when not using any SASL SSF encryption layers. Will read as much
1513 * data as possible without blocking.
1515 * Returns the number of bytes read, which may be less than
1516 * the requested 'datalen' if the socket would block. Returns
1517 * 0 on I/O error or EOF, and disconnects the client socket.
1519 static size_t vnc_client_read_plain(VncState *vs)
1521 size_t ret;
1522 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1523 vs->input.buffer, vs->input.capacity, vs->input.offset);
1524 buffer_reserve(&vs->input, 4096);
1525 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1526 if (!ret)
1527 return 0;
1528 vs->input.offset += ret;
1529 return ret;
1532 static void vnc_jobs_bh(void *opaque)
1534 VncState *vs = opaque;
1536 assert(vs->magic == VNC_MAGIC);
1537 vnc_jobs_consume_buffer(vs);
1541 * First function called whenever there is more data to be read from
1542 * the client socket. Will delegate actual work according to whether
1543 * SASL SSF layers are enabled (thus requiring decryption calls)
1544 * Returns 0 on success, -1 if client disconnected
1546 static int vnc_client_read(VncState *vs)
1548 size_t ret;
1550 #ifdef CONFIG_VNC_SASL
1551 if (vs->sasl.conn && vs->sasl.runSSF)
1552 ret = vnc_client_read_sasl(vs);
1553 else
1554 #endif /* CONFIG_VNC_SASL */
1555 ret = vnc_client_read_plain(vs);
1556 if (!ret) {
1557 if (vs->disconnecting) {
1558 vnc_disconnect_finish(vs);
1559 return -1;
1561 return 0;
1564 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1565 size_t len = vs->read_handler_expect;
1566 int ret;
1568 ret = vs->read_handler(vs, vs->input.buffer, len);
1569 if (vs->disconnecting) {
1570 vnc_disconnect_finish(vs);
1571 return -1;
1574 if (!ret) {
1575 buffer_advance(&vs->input, len);
1576 } else {
1577 vs->read_handler_expect = ret;
1580 return 0;
1583 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1584 GIOCondition condition, void *opaque)
1586 VncState *vs = opaque;
1588 assert(vs->magic == VNC_MAGIC);
1590 if (condition & (G_IO_HUP | G_IO_ERR)) {
1591 vnc_disconnect_start(vs);
1592 return TRUE;
1595 if (condition & G_IO_IN) {
1596 if (vnc_client_read(vs) < 0) {
1597 /* vs is free()ed here */
1598 return TRUE;
1601 if (condition & G_IO_OUT) {
1602 vnc_client_write(vs);
1605 if (vs->disconnecting) {
1606 if (vs->ioc_tag != 0) {
1607 g_source_remove(vs->ioc_tag);
1609 vs->ioc_tag = 0;
1611 return TRUE;
1616 * Scale factor to apply to vs->throttle_output_offset when checking for
1617 * hard limit. Worst case normal usage could be x2, if we have a complete
1618 * incremental update and complete forced update in the output buffer.
1619 * So x3 should be good enough, but we pick x5 to be conservative and thus
1620 * (hopefully) never trigger incorrectly.
1622 #define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1624 void vnc_write(VncState *vs, const void *data, size_t len)
1626 assert(vs->magic == VNC_MAGIC);
1627 if (vs->disconnecting) {
1628 return;
1630 /* Protection against malicious client/guest to prevent our output
1631 * buffer growing without bound if client stops reading data. This
1632 * should rarely trigger, because we have earlier throttling code
1633 * which stops issuing framebuffer updates and drops audio data
1634 * if the throttle_output_offset value is exceeded. So we only reach
1635 * this higher level if a huge number of pseudo-encodings get
1636 * triggered while data can't be sent on the socket.
1638 * NB throttle_output_offset can be zero during early protocol
1639 * handshake, or from the job thread's VncState clone
1641 if (vs->throttle_output_offset != 0 &&
1642 (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
1643 vs->throttle_output_offset) {
1644 trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
1645 vs->throttle_output_offset);
1646 vnc_disconnect_start(vs);
1647 return;
1649 buffer_reserve(&vs->output, len);
1651 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1652 if (vs->ioc_tag) {
1653 g_source_remove(vs->ioc_tag);
1655 vs->ioc_tag = qio_channel_add_watch(
1656 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT,
1657 vnc_client_io, vs, NULL);
1660 buffer_append(&vs->output, data, len);
1663 void vnc_write_s32(VncState *vs, int32_t value)
1665 vnc_write_u32(vs, *(uint32_t *)&value);
1668 void vnc_write_u32(VncState *vs, uint32_t value)
1670 uint8_t buf[4];
1672 buf[0] = (value >> 24) & 0xFF;
1673 buf[1] = (value >> 16) & 0xFF;
1674 buf[2] = (value >> 8) & 0xFF;
1675 buf[3] = value & 0xFF;
1677 vnc_write(vs, buf, 4);
1680 void vnc_write_u16(VncState *vs, uint16_t value)
1682 uint8_t buf[2];
1684 buf[0] = (value >> 8) & 0xFF;
1685 buf[1] = value & 0xFF;
1687 vnc_write(vs, buf, 2);
1690 void vnc_write_u8(VncState *vs, uint8_t value)
1692 vnc_write(vs, (char *)&value, 1);
1695 void vnc_flush(VncState *vs)
1697 vnc_lock_output(vs);
1698 if (vs->ioc != NULL && vs->output.offset) {
1699 vnc_client_write_locked(vs);
1701 if (vs->disconnecting) {
1702 if (vs->ioc_tag != 0) {
1703 g_source_remove(vs->ioc_tag);
1705 vs->ioc_tag = 0;
1707 vnc_unlock_output(vs);
1710 static uint8_t read_u8(uint8_t *data, size_t offset)
1712 return data[offset];
1715 static uint16_t read_u16(uint8_t *data, size_t offset)
1717 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1720 static int32_t read_s32(uint8_t *data, size_t offset)
1722 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1723 (data[offset + 2] << 8) | data[offset + 3]);
1726 uint32_t read_u32(uint8_t *data, size_t offset)
1728 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1729 (data[offset + 2] << 8) | data[offset + 3]);
1732 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1736 static void check_pointer_type_change(Notifier *notifier, void *data)
1738 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1739 int absolute = qemu_input_is_absolute();
1741 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1742 vnc_lock_output(vs);
1743 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1744 vnc_write_u8(vs, 0);
1745 vnc_write_u16(vs, 1);
1746 vnc_framebuffer_update(vs, absolute, 0,
1747 pixman_image_get_width(vs->vd->server),
1748 pixman_image_get_height(vs->vd->server),
1749 VNC_ENCODING_POINTER_TYPE_CHANGE);
1750 vnc_unlock_output(vs);
1751 vnc_flush(vs);
1753 vs->absolute = absolute;
1756 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1758 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1759 [INPUT_BUTTON_LEFT] = 0x01,
1760 [INPUT_BUTTON_MIDDLE] = 0x02,
1761 [INPUT_BUTTON_RIGHT] = 0x04,
1762 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1763 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1765 QemuConsole *con = vs->vd->dcl.con;
1766 int width = pixman_image_get_width(vs->vd->server);
1767 int height = pixman_image_get_height(vs->vd->server);
1769 if (vs->last_bmask != button_mask) {
1770 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1771 vs->last_bmask = button_mask;
1774 if (vs->absolute) {
1775 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1776 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1777 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1778 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1779 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1780 } else {
1781 if (vs->last_x != -1) {
1782 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1783 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1785 vs->last_x = x;
1786 vs->last_y = y;
1788 qemu_input_event_sync();
1791 static void press_key(VncState *vs, QKeyCode qcode)
1793 qkbd_state_key_event(vs->vd->kbd, qcode, true);
1794 qkbd_state_key_event(vs->vd->kbd, qcode, false);
1797 static void vnc_led_state_change(VncState *vs)
1799 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1800 return;
1803 vnc_lock_output(vs);
1804 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1805 vnc_write_u8(vs, 0);
1806 vnc_write_u16(vs, 1);
1807 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1808 vnc_write_u8(vs, vs->vd->ledstate);
1809 vnc_unlock_output(vs);
1810 vnc_flush(vs);
1813 static void kbd_leds(void *opaque, int ledstate)
1815 VncDisplay *vd = opaque;
1816 VncState *client;
1818 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1819 (ledstate & QEMU_NUM_LOCK_LED),
1820 (ledstate & QEMU_SCROLL_LOCK_LED));
1822 if (ledstate == vd->ledstate) {
1823 return;
1826 vd->ledstate = ledstate;
1828 QTAILQ_FOREACH(client, &vd->clients, next) {
1829 vnc_led_state_change(client);
1833 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1835 QKeyCode qcode = qemu_input_key_number_to_qcode(keycode);
1837 /* QEMU console switch */
1838 switch (qcode) {
1839 case Q_KEY_CODE_1 ... Q_KEY_CODE_9: /* '1' to '9' keys */
1840 if (vs->vd->dcl.con == NULL && down &&
1841 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) &&
1842 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {
1843 /* Reset the modifiers sent to the current console */
1844 qkbd_state_lift_all_keys(vs->vd->kbd);
1845 console_select(qcode - Q_KEY_CODE_1);
1846 return;
1848 default:
1849 break;
1852 /* Turn off the lock state sync logic if the client support the led
1853 state extension.
1855 if (down && vs->vd->lock_key_sync &&
1856 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1857 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1858 /* If the numlock state needs to change then simulate an additional
1859 keypress before sending this one. This will happen if the user
1860 toggles numlock away from the VNC window.
1862 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1863 if (!qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1864 trace_vnc_key_sync_numlock(true);
1865 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1867 } else {
1868 if (qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1869 trace_vnc_key_sync_numlock(false);
1870 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1875 if (down && vs->vd->lock_key_sync &&
1876 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1877 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1878 /* If the capslock state needs to change then simulate an additional
1879 keypress before sending this one. This will happen if the user
1880 toggles capslock away from the VNC window.
1882 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1883 bool shift = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_SHIFT);
1884 bool capslock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CAPSLOCK);
1885 if (capslock) {
1886 if (uppercase == shift) {
1887 trace_vnc_key_sync_capslock(false);
1888 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1890 } else {
1891 if (uppercase != shift) {
1892 trace_vnc_key_sync_capslock(true);
1893 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1898 qkbd_state_key_event(vs->vd->kbd, qcode, down);
1899 if (!qemu_console_is_graphic(NULL)) {
1900 bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK);
1901 bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL);
1902 /* QEMU console emulation */
1903 if (down) {
1904 switch (keycode) {
1905 case 0x2a: /* Left Shift */
1906 case 0x36: /* Right Shift */
1907 case 0x1d: /* Left CTRL */
1908 case 0x9d: /* Right CTRL */
1909 case 0x38: /* Left ALT */
1910 case 0xb8: /* Right ALT */
1911 break;
1912 case 0xc8:
1913 kbd_put_keysym(QEMU_KEY_UP);
1914 break;
1915 case 0xd0:
1916 kbd_put_keysym(QEMU_KEY_DOWN);
1917 break;
1918 case 0xcb:
1919 kbd_put_keysym(QEMU_KEY_LEFT);
1920 break;
1921 case 0xcd:
1922 kbd_put_keysym(QEMU_KEY_RIGHT);
1923 break;
1924 case 0xd3:
1925 kbd_put_keysym(QEMU_KEY_DELETE);
1926 break;
1927 case 0xc7:
1928 kbd_put_keysym(QEMU_KEY_HOME);
1929 break;
1930 case 0xcf:
1931 kbd_put_keysym(QEMU_KEY_END);
1932 break;
1933 case 0xc9:
1934 kbd_put_keysym(QEMU_KEY_PAGEUP);
1935 break;
1936 case 0xd1:
1937 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1938 break;
1940 case 0x47:
1941 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1942 break;
1943 case 0x48:
1944 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1945 break;
1946 case 0x49:
1947 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1948 break;
1949 case 0x4b:
1950 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1951 break;
1952 case 0x4c:
1953 kbd_put_keysym('5');
1954 break;
1955 case 0x4d:
1956 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1957 break;
1958 case 0x4f:
1959 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1960 break;
1961 case 0x50:
1962 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1963 break;
1964 case 0x51:
1965 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1966 break;
1967 case 0x52:
1968 kbd_put_keysym('0');
1969 break;
1970 case 0x53:
1971 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1972 break;
1974 case 0xb5:
1975 kbd_put_keysym('/');
1976 break;
1977 case 0x37:
1978 kbd_put_keysym('*');
1979 break;
1980 case 0x4a:
1981 kbd_put_keysym('-');
1982 break;
1983 case 0x4e:
1984 kbd_put_keysym('+');
1985 break;
1986 case 0x9c:
1987 kbd_put_keysym('\n');
1988 break;
1990 default:
1991 if (control) {
1992 kbd_put_keysym(sym & 0x1f);
1993 } else {
1994 kbd_put_keysym(sym);
1996 break;
2002 static const char *code2name(int keycode)
2004 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
2007 static void key_event(VncState *vs, int down, uint32_t sym)
2009 int keycode;
2010 int lsym = sym;
2012 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2013 lsym = lsym - 'A' + 'a';
2016 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
2017 vs->vd->kbd, down) & SCANCODE_KEYMASK;
2018 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2019 do_key_event(vs, down, keycode, sym);
2022 static void ext_key_event(VncState *vs, int down,
2023 uint32_t sym, uint16_t keycode)
2025 /* if the user specifies a keyboard layout, always use it */
2026 if (keyboard_layout) {
2027 key_event(vs, down, sym);
2028 } else {
2029 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2030 do_key_event(vs, down, keycode, sym);
2034 static void framebuffer_update_request(VncState *vs, int incremental,
2035 int x, int y, int w, int h)
2037 if (incremental) {
2038 if (vs->update != VNC_STATE_UPDATE_FORCE) {
2039 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
2041 } else {
2042 vs->update = VNC_STATE_UPDATE_FORCE;
2043 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2044 vnc_colordepth(vs);
2045 vnc_desktop_resize(vs);
2046 vnc_led_state_change(vs);
2047 vnc_cursor_define(vs);
2051 static void send_ext_key_event_ack(VncState *vs)
2053 vnc_lock_output(vs);
2054 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2055 vnc_write_u8(vs, 0);
2056 vnc_write_u16(vs, 1);
2057 vnc_framebuffer_update(vs, 0, 0,
2058 pixman_image_get_width(vs->vd->server),
2059 pixman_image_get_height(vs->vd->server),
2060 VNC_ENCODING_EXT_KEY_EVENT);
2061 vnc_unlock_output(vs);
2062 vnc_flush(vs);
2065 static void send_ext_audio_ack(VncState *vs)
2067 vnc_lock_output(vs);
2068 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2069 vnc_write_u8(vs, 0);
2070 vnc_write_u16(vs, 1);
2071 vnc_framebuffer_update(vs, 0, 0,
2072 pixman_image_get_width(vs->vd->server),
2073 pixman_image_get_height(vs->vd->server),
2074 VNC_ENCODING_AUDIO);
2075 vnc_unlock_output(vs);
2076 vnc_flush(vs);
2079 static void send_xvp_message(VncState *vs, int code)
2081 vnc_lock_output(vs);
2082 vnc_write_u8(vs, VNC_MSG_SERVER_XVP);
2083 vnc_write_u8(vs, 0); /* pad */
2084 vnc_write_u8(vs, 1); /* version */
2085 vnc_write_u8(vs, code);
2086 vnc_unlock_output(vs);
2087 vnc_flush(vs);
2090 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2092 int i;
2093 unsigned int enc = 0;
2095 vs->features = 0;
2096 vs->vnc_encoding = 0;
2097 vs->tight->compression = 9;
2098 vs->tight->quality = -1; /* Lossless by default */
2099 vs->absolute = -1;
2102 * Start from the end because the encodings are sent in order of preference.
2103 * This way the preferred encoding (first encoding defined in the array)
2104 * will be set at the end of the loop.
2106 for (i = n_encodings - 1; i >= 0; i--) {
2107 enc = encodings[i];
2108 switch (enc) {
2109 case VNC_ENCODING_RAW:
2110 vs->vnc_encoding = enc;
2111 break;
2112 case VNC_ENCODING_HEXTILE:
2113 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2114 vs->vnc_encoding = enc;
2115 break;
2116 case VNC_ENCODING_TIGHT:
2117 vs->features |= VNC_FEATURE_TIGHT_MASK;
2118 vs->vnc_encoding = enc;
2119 break;
2120 #ifdef CONFIG_VNC_PNG
2121 case VNC_ENCODING_TIGHT_PNG:
2122 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2123 vs->vnc_encoding = enc;
2124 break;
2125 #endif
2126 case VNC_ENCODING_ZLIB:
2128 * VNC_ENCODING_ZRLE compresses better than VNC_ENCODING_ZLIB.
2129 * So prioritize ZRLE, even if the client hints that it prefers
2130 * ZLIB.
2132 if ((vs->features & VNC_FEATURE_ZRLE_MASK) == 0) {
2133 vs->features |= VNC_FEATURE_ZLIB_MASK;
2134 vs->vnc_encoding = enc;
2136 break;
2137 case VNC_ENCODING_ZRLE:
2138 vs->features |= VNC_FEATURE_ZRLE_MASK;
2139 vs->vnc_encoding = enc;
2140 break;
2141 case VNC_ENCODING_ZYWRLE:
2142 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2143 vs->vnc_encoding = enc;
2144 break;
2145 case VNC_ENCODING_DESKTOPRESIZE:
2146 vs->features |= VNC_FEATURE_RESIZE_MASK;
2147 break;
2148 case VNC_ENCODING_DESKTOP_RESIZE_EXT:
2149 vs->features |= VNC_FEATURE_RESIZE_EXT_MASK;
2150 break;
2151 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2152 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2153 break;
2154 case VNC_ENCODING_RICH_CURSOR:
2155 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2156 break;
2157 case VNC_ENCODING_ALPHA_CURSOR:
2158 vs->features |= VNC_FEATURE_ALPHA_CURSOR_MASK;
2159 break;
2160 case VNC_ENCODING_EXT_KEY_EVENT:
2161 send_ext_key_event_ack(vs);
2162 break;
2163 case VNC_ENCODING_AUDIO:
2164 send_ext_audio_ack(vs);
2165 break;
2166 case VNC_ENCODING_WMVi:
2167 vs->features |= VNC_FEATURE_WMVI_MASK;
2168 break;
2169 case VNC_ENCODING_LED_STATE:
2170 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2171 break;
2172 case VNC_ENCODING_XVP:
2173 if (vs->vd->power_control) {
2174 vs->features |= VNC_FEATURE_XVP;
2175 send_xvp_message(vs, VNC_XVP_CODE_INIT);
2177 break;
2178 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2179 vs->tight->compression = (enc & 0x0F);
2180 break;
2181 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2182 if (vs->vd->lossy) {
2183 vs->tight->quality = (enc & 0x0F);
2185 break;
2186 default:
2187 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2188 break;
2191 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2194 static void set_pixel_conversion(VncState *vs)
2196 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2198 if (fmt == VNC_SERVER_FB_FORMAT) {
2199 vs->write_pixels = vnc_write_pixels_copy;
2200 vnc_hextile_set_pixel_conversion(vs, 0);
2201 } else {
2202 vs->write_pixels = vnc_write_pixels_generic;
2203 vnc_hextile_set_pixel_conversion(vs, 1);
2207 static void send_color_map(VncState *vs)
2209 int i;
2211 vnc_lock_output(vs);
2212 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2213 vnc_write_u8(vs, 0); /* padding */
2214 vnc_write_u16(vs, 0); /* first color */
2215 vnc_write_u16(vs, 256); /* # of colors */
2217 for (i = 0; i < 256; i++) {
2218 PixelFormat *pf = &vs->client_pf;
2220 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2221 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2222 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2224 vnc_unlock_output(vs);
2227 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2228 int big_endian_flag, int true_color_flag,
2229 int red_max, int green_max, int blue_max,
2230 int red_shift, int green_shift, int blue_shift)
2232 if (!true_color_flag) {
2233 /* Expose a reasonable default 256 color map */
2234 bits_per_pixel = 8;
2235 red_max = 7;
2236 green_max = 7;
2237 blue_max = 3;
2238 red_shift = 0;
2239 green_shift = 3;
2240 blue_shift = 6;
2243 switch (bits_per_pixel) {
2244 case 8:
2245 case 16:
2246 case 32:
2247 break;
2248 default:
2249 vnc_client_error(vs);
2250 return;
2253 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2254 vs->client_pf.rbits = ctpopl(red_max);
2255 vs->client_pf.rshift = red_shift;
2256 vs->client_pf.rmask = red_max << red_shift;
2257 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2258 vs->client_pf.gbits = ctpopl(green_max);
2259 vs->client_pf.gshift = green_shift;
2260 vs->client_pf.gmask = green_max << green_shift;
2261 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2262 vs->client_pf.bbits = ctpopl(blue_max);
2263 vs->client_pf.bshift = blue_shift;
2264 vs->client_pf.bmask = blue_max << blue_shift;
2265 vs->client_pf.bits_per_pixel = bits_per_pixel;
2266 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2267 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2268 vs->client_be = big_endian_flag;
2270 if (!true_color_flag) {
2271 send_color_map(vs);
2274 set_pixel_conversion(vs);
2276 graphic_hw_invalidate(vs->vd->dcl.con);
2277 graphic_hw_update(vs->vd->dcl.con);
2280 static void pixel_format_message (VncState *vs) {
2281 char pad[3] = { 0, 0, 0 };
2283 vs->client_pf = qemu_default_pixelformat(32);
2285 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2286 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2288 #ifdef HOST_WORDS_BIGENDIAN
2289 vnc_write_u8(vs, 1); /* big-endian-flag */
2290 #else
2291 vnc_write_u8(vs, 0); /* big-endian-flag */
2292 #endif
2293 vnc_write_u8(vs, 1); /* true-color-flag */
2294 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2295 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2296 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2297 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2298 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2299 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2300 vnc_write(vs, pad, 3); /* padding */
2302 vnc_hextile_set_pixel_conversion(vs, 0);
2303 vs->write_pixels = vnc_write_pixels_copy;
2306 static void vnc_colordepth(VncState *vs)
2308 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2309 /* Sending a WMVi message to notify the client*/
2310 vnc_lock_output(vs);
2311 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2312 vnc_write_u8(vs, 0);
2313 vnc_write_u16(vs, 1); /* number of rects */
2314 vnc_framebuffer_update(vs, 0, 0,
2315 pixman_image_get_width(vs->vd->server),
2316 pixman_image_get_height(vs->vd->server),
2317 VNC_ENCODING_WMVi);
2318 pixel_format_message(vs);
2319 vnc_unlock_output(vs);
2320 vnc_flush(vs);
2321 } else {
2322 set_pixel_conversion(vs);
2326 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2328 int i;
2329 uint16_t limit;
2330 uint32_t freq;
2331 VncDisplay *vd = vs->vd;
2333 if (data[0] > 3) {
2334 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2337 switch (data[0]) {
2338 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2339 if (len == 1)
2340 return 20;
2342 set_pixel_format(vs, read_u8(data, 4),
2343 read_u8(data, 6), read_u8(data, 7),
2344 read_u16(data, 8), read_u16(data, 10),
2345 read_u16(data, 12), read_u8(data, 14),
2346 read_u8(data, 15), read_u8(data, 16));
2347 break;
2348 case VNC_MSG_CLIENT_SET_ENCODINGS:
2349 if (len == 1)
2350 return 4;
2352 if (len == 4) {
2353 limit = read_u16(data, 2);
2354 if (limit > 0)
2355 return 4 + (limit * 4);
2356 } else
2357 limit = read_u16(data, 2);
2359 for (i = 0; i < limit; i++) {
2360 int32_t val = read_s32(data, 4 + (i * 4));
2361 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2364 set_encodings(vs, (int32_t *)(data + 4), limit);
2365 break;
2366 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2367 if (len == 1)
2368 return 10;
2370 framebuffer_update_request(vs,
2371 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2372 read_u16(data, 6), read_u16(data, 8));
2373 break;
2374 case VNC_MSG_CLIENT_KEY_EVENT:
2375 if (len == 1)
2376 return 8;
2378 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2379 break;
2380 case VNC_MSG_CLIENT_POINTER_EVENT:
2381 if (len == 1)
2382 return 6;
2384 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2385 break;
2386 case VNC_MSG_CLIENT_CUT_TEXT:
2387 if (len == 1) {
2388 return 8;
2390 if (len == 8) {
2391 uint32_t dlen = read_u32(data, 4);
2392 if (dlen > (1 << 20)) {
2393 error_report("vnc: client_cut_text msg payload has %u bytes"
2394 " which exceeds our limit of 1MB.", dlen);
2395 vnc_client_error(vs);
2396 break;
2398 if (dlen > 0) {
2399 return 8 + dlen;
2403 client_cut_text(vs, read_u32(data, 4), data + 8);
2404 break;
2405 case VNC_MSG_CLIENT_XVP:
2406 if (!(vs->features & VNC_FEATURE_XVP)) {
2407 error_report("vnc: xvp client message while disabled");
2408 vnc_client_error(vs);
2409 break;
2411 if (len == 1) {
2412 return 4;
2414 if (len == 4) {
2415 uint8_t version = read_u8(data, 2);
2416 uint8_t action = read_u8(data, 3);
2418 if (version != 1) {
2419 error_report("vnc: xvp client message version %d != 1",
2420 version);
2421 vnc_client_error(vs);
2422 break;
2425 switch (action) {
2426 case VNC_XVP_ACTION_SHUTDOWN:
2427 qemu_system_powerdown_request();
2428 break;
2429 case VNC_XVP_ACTION_REBOOT:
2430 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2431 break;
2432 case VNC_XVP_ACTION_RESET:
2433 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
2434 break;
2435 default:
2436 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2437 break;
2440 break;
2441 case VNC_MSG_CLIENT_QEMU:
2442 if (len == 1)
2443 return 2;
2445 switch (read_u8(data, 1)) {
2446 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2447 if (len == 2)
2448 return 12;
2450 ext_key_event(vs, read_u16(data, 2),
2451 read_u32(data, 4), read_u32(data, 8));
2452 break;
2453 case VNC_MSG_CLIENT_QEMU_AUDIO:
2454 if (len == 2)
2455 return 4;
2457 switch (read_u16 (data, 2)) {
2458 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2459 audio_add(vs);
2460 break;
2461 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2462 audio_del(vs);
2463 break;
2464 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2465 if (len == 4)
2466 return 10;
2467 switch (read_u8(data, 4)) {
2468 case 0: vs->as.fmt = AUDIO_FORMAT_U8; break;
2469 case 1: vs->as.fmt = AUDIO_FORMAT_S8; break;
2470 case 2: vs->as.fmt = AUDIO_FORMAT_U16; break;
2471 case 3: vs->as.fmt = AUDIO_FORMAT_S16; break;
2472 case 4: vs->as.fmt = AUDIO_FORMAT_U32; break;
2473 case 5: vs->as.fmt = AUDIO_FORMAT_S32; break;
2474 default:
2475 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2476 vnc_client_error(vs);
2477 break;
2479 vs->as.nchannels = read_u8(data, 5);
2480 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2481 VNC_DEBUG("Invalid audio channel count %d\n",
2482 read_u8(data, 5));
2483 vnc_client_error(vs);
2484 break;
2486 freq = read_u32(data, 6);
2487 /* No official limit for protocol, but 48khz is a sensible
2488 * upper bound for trustworthy clients, and this limit
2489 * protects calculations involving 'vs->as.freq' later.
2491 if (freq > 48000) {
2492 VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
2493 vnc_client_error(vs);
2494 break;
2496 vs->as.freq = freq;
2497 break;
2498 default:
2499 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2500 vnc_client_error(vs);
2501 break;
2503 break;
2505 default:
2506 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2507 vnc_client_error(vs);
2508 break;
2510 break;
2511 case VNC_MSG_CLIENT_SET_DESKTOP_SIZE:
2513 size_t size;
2514 uint8_t screens;
2516 if (len < 8) {
2517 return 8;
2520 screens = read_u8(data, 6);
2521 size = 8 + screens * 16;
2522 if (len < size) {
2523 return size;
2526 if (dpy_ui_info_supported(vs->vd->dcl.con)) {
2527 QemuUIInfo info;
2528 memset(&info, 0, sizeof(info));
2529 info.width = read_u16(data, 2);
2530 info.height = read_u16(data, 4);
2531 dpy_set_ui_info(vs->vd->dcl.con, &info);
2532 vnc_desktop_resize_ext(vs, 4 /* Request forwarded */);
2533 } else {
2534 vnc_desktop_resize_ext(vs, 3 /* Invalid screen layout */);
2537 break;
2539 default:
2540 VNC_DEBUG("Msg: %d\n", data[0]);
2541 vnc_client_error(vs);
2542 break;
2545 vnc_update_throttle_offset(vs);
2546 vnc_read_when(vs, protocol_client_msg, 1);
2547 return 0;
2550 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2552 char buf[1024];
2553 VncShareMode mode;
2554 int size;
2556 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2557 switch (vs->vd->share_policy) {
2558 case VNC_SHARE_POLICY_IGNORE:
2560 * Ignore the shared flag. Nothing to do here.
2562 * Doesn't conform to the rfb spec but is traditional qemu
2563 * behavior, thus left here as option for compatibility
2564 * reasons.
2566 break;
2567 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2569 * Policy: Allow clients ask for exclusive access.
2571 * Implementation: When a client asks for exclusive access,
2572 * disconnect all others. Shared connects are allowed as long
2573 * as no exclusive connection exists.
2575 * This is how the rfb spec suggests to handle the shared flag.
2577 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2578 VncState *client;
2579 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2580 if (vs == client) {
2581 continue;
2583 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2584 client->share_mode != VNC_SHARE_MODE_SHARED) {
2585 continue;
2587 vnc_disconnect_start(client);
2590 if (mode == VNC_SHARE_MODE_SHARED) {
2591 if (vs->vd->num_exclusive > 0) {
2592 vnc_disconnect_start(vs);
2593 return 0;
2596 break;
2597 case VNC_SHARE_POLICY_FORCE_SHARED:
2599 * Policy: Shared connects only.
2600 * Implementation: Disallow clients asking for exclusive access.
2602 * Useful for shared desktop sessions where you don't want
2603 * someone forgetting to say -shared when running the vnc
2604 * client disconnect everybody else.
2606 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2607 vnc_disconnect_start(vs);
2608 return 0;
2610 break;
2612 vnc_set_share_mode(vs, mode);
2614 if (vs->vd->num_shared > vs->vd->connections_limit) {
2615 vnc_disconnect_start(vs);
2616 return 0;
2619 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
2620 pixman_image_get_width(vs->vd->server) >= 0);
2621 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
2622 pixman_image_get_height(vs->vd->server) >= 0);
2623 vs->client_width = pixman_image_get_width(vs->vd->server);
2624 vs->client_height = pixman_image_get_height(vs->vd->server);
2625 vnc_write_u16(vs, vs->client_width);
2626 vnc_write_u16(vs, vs->client_height);
2628 pixel_format_message(vs);
2630 if (qemu_name) {
2631 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2632 if (size > sizeof(buf)) {
2633 size = sizeof(buf);
2635 } else {
2636 size = snprintf(buf, sizeof(buf), "QEMU");
2639 vnc_write_u32(vs, size);
2640 vnc_write(vs, buf, size);
2641 vnc_flush(vs);
2643 vnc_client_cache_auth(vs);
2644 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2646 vnc_read_when(vs, protocol_client_msg, 1);
2648 return 0;
2651 void start_client_init(VncState *vs)
2653 vnc_read_when(vs, protocol_client_init, 1);
2656 static void authentication_failed(VncState *vs)
2658 vnc_write_u32(vs, 1); /* Reject auth */
2659 if (vs->minor >= 8) {
2660 static const char err[] = "Authentication failed";
2661 vnc_write_u32(vs, sizeof(err));
2662 vnc_write(vs, err, sizeof(err));
2664 vnc_flush(vs);
2665 vnc_client_error(vs);
2668 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2670 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2671 size_t i, pwlen;
2672 unsigned char key[8];
2673 time_t now = time(NULL);
2674 QCryptoCipher *cipher = NULL;
2675 Error *err = NULL;
2677 if (!vs->vd->password) {
2678 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2679 goto reject;
2681 if (vs->vd->expires < now) {
2682 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2683 goto reject;
2686 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2688 /* Calculate the expected challenge response */
2689 pwlen = strlen(vs->vd->password);
2690 for (i=0; i<sizeof(key); i++)
2691 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2693 cipher = qcrypto_cipher_new(
2694 QCRYPTO_CIPHER_ALG_DES_RFB,
2695 QCRYPTO_CIPHER_MODE_ECB,
2696 key, G_N_ELEMENTS(key),
2697 &err);
2698 if (!cipher) {
2699 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2700 error_get_pretty(err));
2701 error_free(err);
2702 goto reject;
2705 if (qcrypto_cipher_encrypt(cipher,
2706 vs->challenge,
2707 response,
2708 VNC_AUTH_CHALLENGE_SIZE,
2709 &err) < 0) {
2710 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2711 error_get_pretty(err));
2712 error_free(err);
2713 goto reject;
2716 /* Compare expected vs actual challenge response */
2717 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2718 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2719 goto reject;
2720 } else {
2721 trace_vnc_auth_pass(vs, vs->auth);
2722 vnc_write_u32(vs, 0); /* Accept auth */
2723 vnc_flush(vs);
2725 start_client_init(vs);
2728 qcrypto_cipher_free(cipher);
2729 return 0;
2731 reject:
2732 authentication_failed(vs);
2733 qcrypto_cipher_free(cipher);
2734 return 0;
2737 void start_auth_vnc(VncState *vs)
2739 Error *err = NULL;
2741 if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) {
2742 trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
2743 error_get_pretty(err));
2744 error_free(err);
2745 authentication_failed(vs);
2746 return;
2749 /* Send client a 'random' challenge */
2750 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2751 vnc_flush(vs);
2753 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2757 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2759 /* We only advertise 1 auth scheme at a time, so client
2760 * must pick the one we sent. Verify this */
2761 if (data[0] != vs->auth) { /* Reject auth */
2762 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2763 authentication_failed(vs);
2764 } else { /* Accept requested auth */
2765 trace_vnc_auth_start(vs, vs->auth);
2766 switch (vs->auth) {
2767 case VNC_AUTH_NONE:
2768 if (vs->minor >= 8) {
2769 vnc_write_u32(vs, 0); /* Accept auth completion */
2770 vnc_flush(vs);
2772 trace_vnc_auth_pass(vs, vs->auth);
2773 start_client_init(vs);
2774 break;
2776 case VNC_AUTH_VNC:
2777 start_auth_vnc(vs);
2778 break;
2780 case VNC_AUTH_VENCRYPT:
2781 start_auth_vencrypt(vs);
2782 break;
2784 #ifdef CONFIG_VNC_SASL
2785 case VNC_AUTH_SASL:
2786 start_auth_sasl(vs);
2787 break;
2788 #endif /* CONFIG_VNC_SASL */
2790 default: /* Should not be possible, but just in case */
2791 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2792 authentication_failed(vs);
2795 return 0;
2798 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2800 char local[13];
2802 memcpy(local, version, 12);
2803 local[12] = 0;
2805 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2806 VNC_DEBUG("Malformed protocol version %s\n", local);
2807 vnc_client_error(vs);
2808 return 0;
2810 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2811 if (vs->major != 3 ||
2812 (vs->minor != 3 &&
2813 vs->minor != 4 &&
2814 vs->minor != 5 &&
2815 vs->minor != 7 &&
2816 vs->minor != 8)) {
2817 VNC_DEBUG("Unsupported client version\n");
2818 vnc_write_u32(vs, VNC_AUTH_INVALID);
2819 vnc_flush(vs);
2820 vnc_client_error(vs);
2821 return 0;
2823 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2824 * as equivalent to v3.3 by servers
2826 if (vs->minor == 4 || vs->minor == 5)
2827 vs->minor = 3;
2829 if (vs->minor == 3) {
2830 trace_vnc_auth_start(vs, vs->auth);
2831 if (vs->auth == VNC_AUTH_NONE) {
2832 vnc_write_u32(vs, vs->auth);
2833 vnc_flush(vs);
2834 trace_vnc_auth_pass(vs, vs->auth);
2835 start_client_init(vs);
2836 } else if (vs->auth == VNC_AUTH_VNC) {
2837 VNC_DEBUG("Tell client VNC auth\n");
2838 vnc_write_u32(vs, vs->auth);
2839 vnc_flush(vs);
2840 start_auth_vnc(vs);
2841 } else {
2842 trace_vnc_auth_fail(vs, vs->auth,
2843 "Unsupported auth method for v3.3", "");
2844 vnc_write_u32(vs, VNC_AUTH_INVALID);
2845 vnc_flush(vs);
2846 vnc_client_error(vs);
2848 } else {
2849 vnc_write_u8(vs, 1); /* num auth */
2850 vnc_write_u8(vs, vs->auth);
2851 vnc_read_when(vs, protocol_client_auth, 1);
2852 vnc_flush(vs);
2855 return 0;
2858 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2860 struct VncSurface *vs = &vd->guest;
2862 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2865 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2867 int i, j;
2869 w = (x + w) / VNC_STAT_RECT;
2870 h = (y + h) / VNC_STAT_RECT;
2871 x /= VNC_STAT_RECT;
2872 y /= VNC_STAT_RECT;
2874 for (j = y; j <= h; j++) {
2875 for (i = x; i <= w; i++) {
2876 vs->lossy_rect[j][i] = 1;
2881 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2883 VncState *vs;
2884 int sty = y / VNC_STAT_RECT;
2885 int stx = x / VNC_STAT_RECT;
2886 int has_dirty = 0;
2888 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2889 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2891 QTAILQ_FOREACH(vs, &vd->clients, next) {
2892 int j;
2894 /* kernel send buffers are full -> refresh later */
2895 if (vs->output.offset) {
2896 continue;
2899 if (!vs->lossy_rect[sty][stx]) {
2900 continue;
2903 vs->lossy_rect[sty][stx] = 0;
2904 for (j = 0; j < VNC_STAT_RECT; ++j) {
2905 bitmap_set(vs->dirty[y + j],
2906 x / VNC_DIRTY_PIXELS_PER_BIT,
2907 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2909 has_dirty++;
2912 return has_dirty;
2915 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2917 int width = MIN(pixman_image_get_width(vd->guest.fb),
2918 pixman_image_get_width(vd->server));
2919 int height = MIN(pixman_image_get_height(vd->guest.fb),
2920 pixman_image_get_height(vd->server));
2921 int x, y;
2922 struct timeval res;
2923 int has_dirty = 0;
2925 for (y = 0; y < height; y += VNC_STAT_RECT) {
2926 for (x = 0; x < width; x += VNC_STAT_RECT) {
2927 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2929 rect->updated = false;
2933 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2935 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2936 return has_dirty;
2938 vd->guest.last_freq_check = *tv;
2940 for (y = 0; y < height; y += VNC_STAT_RECT) {
2941 for (x = 0; x < width; x += VNC_STAT_RECT) {
2942 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2943 int count = ARRAY_SIZE(rect->times);
2944 struct timeval min, max;
2946 if (!timerisset(&rect->times[count - 1])) {
2947 continue ;
2950 max = rect->times[(rect->idx + count - 1) % count];
2951 qemu_timersub(tv, &max, &res);
2953 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2954 rect->freq = 0;
2955 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2956 memset(rect->times, 0, sizeof (rect->times));
2957 continue ;
2960 min = rect->times[rect->idx];
2961 max = rect->times[(rect->idx + count - 1) % count];
2962 qemu_timersub(&max, &min, &res);
2964 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2965 rect->freq /= count;
2966 rect->freq = 1. / rect->freq;
2969 return has_dirty;
2972 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2974 int i, j;
2975 double total = 0;
2976 int num = 0;
2978 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2979 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2981 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2982 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2983 total += vnc_stat_rect(vs->vd, i, j)->freq;
2984 num++;
2988 if (num) {
2989 return total / num;
2990 } else {
2991 return 0;
2995 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2997 VncRectStat *rect;
2999 rect = vnc_stat_rect(vd, x, y);
3000 if (rect->updated) {
3001 return ;
3003 rect->times[rect->idx] = *tv;
3004 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
3005 rect->updated = true;
3008 static int vnc_refresh_server_surface(VncDisplay *vd)
3010 int width = MIN(pixman_image_get_width(vd->guest.fb),
3011 pixman_image_get_width(vd->server));
3012 int height = MIN(pixman_image_get_height(vd->guest.fb),
3013 pixman_image_get_height(vd->server));
3014 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
3015 uint8_t *guest_row0 = NULL, *server_row0;
3016 VncState *vs;
3017 int has_dirty = 0;
3018 pixman_image_t *tmpbuf = NULL;
3020 struct timeval tv = { 0, 0 };
3022 if (!vd->non_adaptive) {
3023 gettimeofday(&tv, NULL);
3024 has_dirty = vnc_update_stats(vd, &tv);
3028 * Walk through the guest dirty map.
3029 * Check and copy modified bits from guest to server surface.
3030 * Update server dirty map.
3032 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
3033 server_stride = guest_stride = guest_ll =
3034 pixman_image_get_stride(vd->server);
3035 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
3036 server_stride);
3037 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3038 int width = pixman_image_get_width(vd->server);
3039 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
3040 } else {
3041 int guest_bpp =
3042 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
3043 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
3044 guest_stride = pixman_image_get_stride(vd->guest.fb);
3045 guest_ll = pixman_image_get_width(vd->guest.fb)
3046 * DIV_ROUND_UP(guest_bpp, 8);
3048 line_bytes = MIN(server_stride, guest_ll);
3050 for (;;) {
3051 int x;
3052 uint8_t *guest_ptr, *server_ptr;
3053 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3054 height * VNC_DIRTY_BPL(&vd->guest),
3055 y * VNC_DIRTY_BPL(&vd->guest));
3056 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3057 /* no more dirty bits */
3058 break;
3060 y = offset / VNC_DIRTY_BPL(&vd->guest);
3061 x = offset % VNC_DIRTY_BPL(&vd->guest);
3063 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
3065 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3066 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
3067 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
3068 } else {
3069 guest_ptr = guest_row0 + y * guest_stride;
3071 guest_ptr += x * cmp_bytes;
3073 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
3074 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
3075 int _cmp_bytes = cmp_bytes;
3076 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
3077 continue;
3079 if ((x + 1) * cmp_bytes > line_bytes) {
3080 _cmp_bytes = line_bytes - x * cmp_bytes;
3082 assert(_cmp_bytes >= 0);
3083 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
3084 continue;
3086 memcpy(server_ptr, guest_ptr, _cmp_bytes);
3087 if (!vd->non_adaptive) {
3088 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
3089 y, &tv);
3091 QTAILQ_FOREACH(vs, &vd->clients, next) {
3092 set_bit(x, vs->dirty[y]);
3094 has_dirty++;
3097 y++;
3099 qemu_pixman_image_unref(tmpbuf);
3100 return has_dirty;
3103 static void vnc_refresh(DisplayChangeListener *dcl)
3105 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
3106 VncState *vs, *vn;
3107 int has_dirty, rects = 0;
3109 if (QTAILQ_EMPTY(&vd->clients)) {
3110 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
3111 return;
3114 graphic_hw_update(vd->dcl.con);
3116 if (vnc_trylock_display(vd)) {
3117 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3118 return;
3121 has_dirty = vnc_refresh_server_surface(vd);
3122 vnc_unlock_display(vd);
3124 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
3125 rects += vnc_update_client(vs, has_dirty);
3126 /* vs might be free()ed here */
3129 if (has_dirty && rects) {
3130 vd->dcl.update_interval /= 2;
3131 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3132 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3134 } else {
3135 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3136 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3137 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3142 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
3143 bool skipauth, bool websocket)
3145 VncState *vs = g_new0(VncState, 1);
3146 bool first_client = QTAILQ_EMPTY(&vd->clients);
3147 int i;
3149 trace_vnc_client_connect(vs, sioc);
3150 vs->zrle = g_new0(VncZrle, 1);
3151 vs->tight = g_new0(VncTight, 1);
3152 vs->magic = VNC_MAGIC;
3153 vs->sioc = sioc;
3154 object_ref(OBJECT(vs->sioc));
3155 vs->ioc = QIO_CHANNEL(sioc);
3156 object_ref(OBJECT(vs->ioc));
3157 vs->vd = vd;
3159 buffer_init(&vs->input, "vnc-input/%p", sioc);
3160 buffer_init(&vs->output, "vnc-output/%p", sioc);
3161 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
3163 buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc);
3164 buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc);
3165 buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc);
3166 #ifdef CONFIG_VNC_JPEG
3167 buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc);
3168 #endif
3169 #ifdef CONFIG_VNC_PNG
3170 buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc);
3171 #endif
3172 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3173 buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc);
3174 buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc);
3175 buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc);
3177 if (skipauth) {
3178 vs->auth = VNC_AUTH_NONE;
3179 vs->subauth = VNC_AUTH_INVALID;
3180 } else {
3181 if (websocket) {
3182 vs->auth = vd->ws_auth;
3183 vs->subauth = VNC_AUTH_INVALID;
3184 } else {
3185 vs->auth = vd->auth;
3186 vs->subauth = vd->subauth;
3189 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3190 sioc, websocket, vs->auth, vs->subauth);
3192 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3193 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3194 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3197 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3198 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3199 qio_channel_set_blocking(vs->ioc, false, NULL);
3200 if (vs->ioc_tag) {
3201 g_source_remove(vs->ioc_tag);
3203 if (websocket) {
3204 vs->websocket = 1;
3205 if (vd->tlscreds) {
3206 vs->ioc_tag = qio_channel_add_watch(
3207 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3208 vncws_tls_handshake_io, vs, NULL);
3209 } else {
3210 vs->ioc_tag = qio_channel_add_watch(
3211 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3212 vncws_handshake_io, vs, NULL);
3214 } else {
3215 vs->ioc_tag = qio_channel_add_watch(
3216 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3217 vnc_client_io, vs, NULL);
3220 vnc_client_cache_addr(vs);
3221 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3222 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3224 vs->last_x = -1;
3225 vs->last_y = -1;
3227 vs->as.freq = 44100;
3228 vs->as.nchannels = 2;
3229 vs->as.fmt = AUDIO_FORMAT_S16;
3230 vs->as.endianness = 0;
3232 qemu_mutex_init(&vs->output_mutex);
3233 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3235 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3236 if (first_client) {
3237 vnc_update_server_surface(vd);
3240 graphic_hw_update(vd->dcl.con);
3242 if (!vs->websocket) {
3243 vnc_start_protocol(vs);
3246 if (vd->num_connecting > vd->connections_limit) {
3247 QTAILQ_FOREACH(vs, &vd->clients, next) {
3248 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3249 vnc_disconnect_start(vs);
3250 return;
3256 void vnc_start_protocol(VncState *vs)
3258 vnc_write(vs, "RFB 003.008\n", 12);
3259 vnc_flush(vs);
3260 vnc_read_when(vs, protocol_version, 12);
3262 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3263 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3266 static void vnc_listen_io(QIONetListener *listener,
3267 QIOChannelSocket *cioc,
3268 void *opaque)
3270 VncDisplay *vd = opaque;
3271 bool isWebsock = listener == vd->wslistener;
3273 qio_channel_set_name(QIO_CHANNEL(cioc),
3274 isWebsock ? "vnc-ws-server" : "vnc-server");
3275 qio_channel_set_delay(QIO_CHANNEL(cioc), false);
3276 vnc_connect(vd, cioc, false, isWebsock);
3279 static const DisplayChangeListenerOps dcl_ops = {
3280 .dpy_name = "vnc",
3281 .dpy_refresh = vnc_refresh,
3282 .dpy_gfx_update = vnc_dpy_update,
3283 .dpy_gfx_switch = vnc_dpy_switch,
3284 .dpy_gfx_check_format = qemu_pixman_check_format,
3285 .dpy_mouse_set = vnc_mouse_set,
3286 .dpy_cursor_define = vnc_dpy_cursor_define,
3289 void vnc_display_init(const char *id, Error **errp)
3291 VncDisplay *vd;
3293 if (vnc_display_find(id) != NULL) {
3294 return;
3296 vd = g_malloc0(sizeof(*vd));
3298 vd->id = strdup(id);
3299 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3301 QTAILQ_INIT(&vd->clients);
3302 vd->expires = TIME_MAX;
3304 if (keyboard_layout) {
3305 trace_vnc_key_map_init(keyboard_layout);
3306 vd->kbd_layout = init_keyboard_layout(name2keysym,
3307 keyboard_layout, errp);
3308 } else {
3309 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
3312 if (!vd->kbd_layout) {
3313 return;
3316 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3317 vd->connections_limit = 32;
3319 qemu_mutex_init(&vd->mutex);
3320 vnc_start_worker_thread();
3322 vd->dcl.ops = &dcl_ops;
3323 register_displaychangelistener(&vd->dcl);
3324 vd->kbd = qkbd_state_init(vd->dcl.con);
3328 static void vnc_display_close(VncDisplay *vd)
3330 if (!vd) {
3331 return;
3333 vd->is_unix = false;
3335 if (vd->listener) {
3336 qio_net_listener_disconnect(vd->listener);
3337 object_unref(OBJECT(vd->listener));
3339 vd->listener = NULL;
3341 if (vd->wslistener) {
3342 qio_net_listener_disconnect(vd->wslistener);
3343 object_unref(OBJECT(vd->wslistener));
3345 vd->wslistener = NULL;
3347 vd->auth = VNC_AUTH_INVALID;
3348 vd->subauth = VNC_AUTH_INVALID;
3349 if (vd->tlscreds) {
3350 object_unref(OBJECT(vd->tlscreds));
3351 vd->tlscreds = NULL;
3353 if (vd->tlsauthz) {
3354 object_unparent(OBJECT(vd->tlsauthz));
3355 vd->tlsauthz = NULL;
3357 g_free(vd->tlsauthzid);
3358 vd->tlsauthzid = NULL;
3359 if (vd->lock_key_sync) {
3360 qemu_remove_led_event_handler(vd->led);
3361 vd->led = NULL;
3363 #ifdef CONFIG_VNC_SASL
3364 if (vd->sasl.authz) {
3365 object_unparent(OBJECT(vd->sasl.authz));
3366 vd->sasl.authz = NULL;
3368 g_free(vd->sasl.authzid);
3369 vd->sasl.authzid = NULL;
3370 #endif
3373 int vnc_display_password(const char *id, const char *password)
3375 VncDisplay *vd = vnc_display_find(id);
3377 if (!vd) {
3378 return -EINVAL;
3380 if (vd->auth == VNC_AUTH_NONE) {
3381 error_printf_unless_qmp("If you want use passwords please enable "
3382 "password auth using '-vnc ${dpy},password'.\n");
3383 return -EINVAL;
3386 g_free(vd->password);
3387 vd->password = g_strdup(password);
3389 return 0;
3392 int vnc_display_pw_expire(const char *id, time_t expires)
3394 VncDisplay *vd = vnc_display_find(id);
3396 if (!vd) {
3397 return -EINVAL;
3400 vd->expires = expires;
3401 return 0;
3404 static void vnc_display_print_local_addr(VncDisplay *vd)
3406 SocketAddress *addr;
3408 if (!vd->listener || !vd->listener->nsioc) {
3409 return;
3412 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], NULL);
3413 if (!addr) {
3414 return;
3417 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3418 qapi_free_SocketAddress(addr);
3419 return;
3421 error_printf_unless_qmp("VNC server running on %s:%s\n",
3422 addr->u.inet.host,
3423 addr->u.inet.port);
3424 qapi_free_SocketAddress(addr);
3427 static QemuOptsList qemu_vnc_opts = {
3428 .name = "vnc",
3429 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3430 .implied_opt_name = "vnc",
3431 .desc = {
3433 .name = "vnc",
3434 .type = QEMU_OPT_STRING,
3436 .name = "websocket",
3437 .type = QEMU_OPT_STRING,
3439 .name = "tls-creds",
3440 .type = QEMU_OPT_STRING,
3442 .name = "share",
3443 .type = QEMU_OPT_STRING,
3445 .name = "display",
3446 .type = QEMU_OPT_STRING,
3448 .name = "head",
3449 .type = QEMU_OPT_NUMBER,
3451 .name = "connections",
3452 .type = QEMU_OPT_NUMBER,
3454 .name = "to",
3455 .type = QEMU_OPT_NUMBER,
3457 .name = "ipv4",
3458 .type = QEMU_OPT_BOOL,
3460 .name = "ipv6",
3461 .type = QEMU_OPT_BOOL,
3463 .name = "password",
3464 .type = QEMU_OPT_BOOL,
3466 .name = "reverse",
3467 .type = QEMU_OPT_BOOL,
3469 .name = "lock-key-sync",
3470 .type = QEMU_OPT_BOOL,
3472 .name = "key-delay-ms",
3473 .type = QEMU_OPT_NUMBER,
3475 .name = "sasl",
3476 .type = QEMU_OPT_BOOL,
3478 .name = "acl",
3479 .type = QEMU_OPT_BOOL,
3481 .name = "tls-authz",
3482 .type = QEMU_OPT_STRING,
3484 .name = "sasl-authz",
3485 .type = QEMU_OPT_STRING,
3487 .name = "lossy",
3488 .type = QEMU_OPT_BOOL,
3490 .name = "non-adaptive",
3491 .type = QEMU_OPT_BOOL,
3493 .name = "audiodev",
3494 .type = QEMU_OPT_STRING,
3496 .name = "power-control",
3497 .type = QEMU_OPT_BOOL,
3499 { /* end of list */ }
3504 static int
3505 vnc_display_setup_auth(int *auth,
3506 int *subauth,
3507 QCryptoTLSCreds *tlscreds,
3508 bool password,
3509 bool sasl,
3510 bool websocket,
3511 Error **errp)
3514 * We have a choice of 3 authentication options
3516 * 1. none
3517 * 2. vnc
3518 * 3. sasl
3520 * The channel can be run in 2 modes
3522 * 1. clear
3523 * 2. tls
3525 * And TLS can use 2 types of credentials
3527 * 1. anon
3528 * 2. x509
3530 * We thus have 9 possible logical combinations
3532 * 1. clear + none
3533 * 2. clear + vnc
3534 * 3. clear + sasl
3535 * 4. tls + anon + none
3536 * 5. tls + anon + vnc
3537 * 6. tls + anon + sasl
3538 * 7. tls + x509 + none
3539 * 8. tls + x509 + vnc
3540 * 9. tls + x509 + sasl
3542 * These need to be mapped into the VNC auth schemes
3543 * in an appropriate manner. In regular VNC, all the
3544 * TLS options get mapped into VNC_AUTH_VENCRYPT
3545 * sub-auth types.
3547 * In websockets, the https:// protocol already provides
3548 * TLS support, so there is no need to make use of the
3549 * VeNCrypt extension. Furthermore, websockets browser
3550 * clients could not use VeNCrypt even if they wanted to,
3551 * as they cannot control when the TLS handshake takes
3552 * place. Thus there is no option but to rely on https://,
3553 * meaning combinations 4->6 and 7->9 will be mapped to
3554 * VNC auth schemes in the same way as combos 1->3.
3556 * Regardless of fact that we have a different mapping to
3557 * VNC auth mechs for plain VNC vs websockets VNC, the end
3558 * result has the same security characteristics.
3560 if (websocket || !tlscreds) {
3561 if (password) {
3562 VNC_DEBUG("Initializing VNC server with password auth\n");
3563 *auth = VNC_AUTH_VNC;
3564 } else if (sasl) {
3565 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3566 *auth = VNC_AUTH_SASL;
3567 } else {
3568 VNC_DEBUG("Initializing VNC server with no auth\n");
3569 *auth = VNC_AUTH_NONE;
3571 *subauth = VNC_AUTH_INVALID;
3572 } else {
3573 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3574 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3575 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3576 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3578 if (!is_x509 && !is_anon) {
3579 error_setg(errp,
3580 "Unsupported TLS cred type %s",
3581 object_get_typename(OBJECT(tlscreds)));
3582 return -1;
3584 *auth = VNC_AUTH_VENCRYPT;
3585 if (password) {
3586 if (is_x509) {
3587 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3588 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3589 } else {
3590 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3591 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3594 } else if (sasl) {
3595 if (is_x509) {
3596 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3597 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3598 } else {
3599 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3600 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3602 } else {
3603 if (is_x509) {
3604 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3605 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3606 } else {
3607 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3608 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3612 return 0;
3616 static int vnc_display_get_address(const char *addrstr,
3617 bool websocket,
3618 bool reverse,
3619 int displaynum,
3620 int to,
3621 bool has_ipv4,
3622 bool has_ipv6,
3623 bool ipv4,
3624 bool ipv6,
3625 SocketAddress **retaddr,
3626 Error **errp)
3628 int ret = -1;
3629 SocketAddress *addr = NULL;
3631 addr = g_new0(SocketAddress, 1);
3633 if (strncmp(addrstr, "unix:", 5) == 0) {
3634 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3635 addr->u.q_unix.path = g_strdup(addrstr + 5);
3637 if (websocket) {
3638 error_setg(errp, "UNIX sockets not supported with websock");
3639 goto cleanup;
3642 if (to) {
3643 error_setg(errp, "Port range not support with UNIX socket");
3644 goto cleanup;
3646 ret = 0;
3647 } else {
3648 const char *port;
3649 size_t hostlen;
3650 unsigned long long baseport = 0;
3651 InetSocketAddress *inet;
3653 port = strrchr(addrstr, ':');
3654 if (!port) {
3655 if (websocket) {
3656 hostlen = 0;
3657 port = addrstr;
3658 } else {
3659 error_setg(errp, "no vnc port specified");
3660 goto cleanup;
3662 } else {
3663 hostlen = port - addrstr;
3664 port++;
3665 if (*port == '\0') {
3666 error_setg(errp, "vnc port cannot be empty");
3667 goto cleanup;
3671 addr->type = SOCKET_ADDRESS_TYPE_INET;
3672 inet = &addr->u.inet;
3673 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3674 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3675 } else {
3676 inet->host = g_strndup(addrstr, hostlen);
3678 /* plain VNC port is just an offset, for websocket
3679 * port is absolute */
3680 if (websocket) {
3681 if (g_str_equal(addrstr, "") ||
3682 g_str_equal(addrstr, "on")) {
3683 if (displaynum == -1) {
3684 error_setg(errp, "explicit websocket port is required");
3685 goto cleanup;
3687 inet->port = g_strdup_printf(
3688 "%d", displaynum + 5700);
3689 if (to) {
3690 inet->has_to = true;
3691 inet->to = to + 5700;
3693 } else {
3694 inet->port = g_strdup(port);
3696 } else {
3697 int offset = reverse ? 0 : 5900;
3698 if (parse_uint_full(port, &baseport, 10) < 0) {
3699 error_setg(errp, "can't convert to a number: %s", port);
3700 goto cleanup;
3702 if (baseport > 65535 ||
3703 baseport + offset > 65535) {
3704 error_setg(errp, "port %s out of range", port);
3705 goto cleanup;
3707 inet->port = g_strdup_printf(
3708 "%d", (int)baseport + offset);
3710 if (to) {
3711 inet->has_to = true;
3712 inet->to = to + offset;
3716 inet->ipv4 = ipv4;
3717 inet->has_ipv4 = has_ipv4;
3718 inet->ipv6 = ipv6;
3719 inet->has_ipv6 = has_ipv6;
3721 ret = baseport;
3724 *retaddr = addr;
3726 cleanup:
3727 if (ret < 0) {
3728 qapi_free_SocketAddress(addr);
3730 return ret;
3733 static void vnc_free_addresses(SocketAddress ***retsaddr,
3734 size_t *retnsaddr)
3736 size_t i;
3738 for (i = 0; i < *retnsaddr; i++) {
3739 qapi_free_SocketAddress((*retsaddr)[i]);
3741 g_free(*retsaddr);
3743 *retsaddr = NULL;
3744 *retnsaddr = 0;
3747 static int vnc_display_get_addresses(QemuOpts *opts,
3748 bool reverse,
3749 SocketAddress ***retsaddr,
3750 size_t *retnsaddr,
3751 SocketAddress ***retwsaddr,
3752 size_t *retnwsaddr,
3753 Error **errp)
3755 SocketAddress *saddr = NULL;
3756 SocketAddress *wsaddr = NULL;
3757 QemuOptsIter addriter;
3758 const char *addr;
3759 int to = qemu_opt_get_number(opts, "to", 0);
3760 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3761 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3762 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3763 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3764 int displaynum = -1;
3765 int ret = -1;
3767 *retsaddr = NULL;
3768 *retnsaddr = 0;
3769 *retwsaddr = NULL;
3770 *retnwsaddr = 0;
3772 addr = qemu_opt_get(opts, "vnc");
3773 if (addr == NULL || g_str_equal(addr, "none")) {
3774 ret = 0;
3775 goto cleanup;
3777 if (qemu_opt_get(opts, "websocket") &&
3778 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3779 error_setg(errp,
3780 "SHA1 hash support is required for websockets");
3781 goto cleanup;
3784 qemu_opt_iter_init(&addriter, opts, "vnc");
3785 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3786 int rv;
3787 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3788 has_ipv4, has_ipv6,
3789 ipv4, ipv6,
3790 &saddr, errp);
3791 if (rv < 0) {
3792 goto cleanup;
3794 /* Historical compat - first listen address can be used
3795 * to set the default websocket port
3797 if (displaynum == -1) {
3798 displaynum = rv;
3800 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3801 (*retsaddr)[(*retnsaddr)++] = saddr;
3804 /* If we had multiple primary displays, we don't do defaults
3805 * for websocket, and require explicit config instead. */
3806 if (*retnsaddr > 1) {
3807 displaynum = -1;
3810 qemu_opt_iter_init(&addriter, opts, "websocket");
3811 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3812 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3813 has_ipv4, has_ipv6,
3814 ipv4, ipv6,
3815 &wsaddr, errp) < 0) {
3816 goto cleanup;
3819 /* Historical compat - if only a single listen address was
3820 * provided, then this is used to set the default listen
3821 * address for websocket too
3823 if (*retnsaddr == 1 &&
3824 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3825 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3826 g_str_equal(wsaddr->u.inet.host, "") &&
3827 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3828 g_free(wsaddr->u.inet.host);
3829 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3832 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3833 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3836 ret = 0;
3837 cleanup:
3838 if (ret < 0) {
3839 vnc_free_addresses(retsaddr, retnsaddr);
3840 vnc_free_addresses(retwsaddr, retnwsaddr);
3842 return ret;
3845 static int vnc_display_connect(VncDisplay *vd,
3846 SocketAddress **saddr,
3847 size_t nsaddr,
3848 SocketAddress **wsaddr,
3849 size_t nwsaddr,
3850 Error **errp)
3852 /* connect to viewer */
3853 QIOChannelSocket *sioc = NULL;
3854 if (nwsaddr != 0) {
3855 error_setg(errp, "Cannot use websockets in reverse mode");
3856 return -1;
3858 if (nsaddr != 1) {
3859 error_setg(errp, "Expected a single address in reverse mode");
3860 return -1;
3862 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3863 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3864 sioc = qio_channel_socket_new();
3865 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3866 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3867 object_unref(OBJECT(sioc));
3868 return -1;
3870 vnc_connect(vd, sioc, false, false);
3871 object_unref(OBJECT(sioc));
3872 return 0;
3876 static int vnc_display_listen(VncDisplay *vd,
3877 SocketAddress **saddr,
3878 size_t nsaddr,
3879 SocketAddress **wsaddr,
3880 size_t nwsaddr,
3881 Error **errp)
3883 size_t i;
3885 if (nsaddr) {
3886 vd->listener = qio_net_listener_new();
3887 qio_net_listener_set_name(vd->listener, "vnc-listen");
3888 for (i = 0; i < nsaddr; i++) {
3889 if (qio_net_listener_open_sync(vd->listener,
3890 saddr[i], 1,
3891 errp) < 0) {
3892 return -1;
3896 qio_net_listener_set_client_func(vd->listener,
3897 vnc_listen_io, vd, NULL);
3900 if (nwsaddr) {
3901 vd->wslistener = qio_net_listener_new();
3902 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
3903 for (i = 0; i < nwsaddr; i++) {
3904 if (qio_net_listener_open_sync(vd->wslistener,
3905 wsaddr[i], 1,
3906 errp) < 0) {
3907 return -1;
3911 qio_net_listener_set_client_func(vd->wslistener,
3912 vnc_listen_io, vd, NULL);
3915 return 0;
3919 void vnc_display_open(const char *id, Error **errp)
3921 VncDisplay *vd = vnc_display_find(id);
3922 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3923 SocketAddress **saddr = NULL, **wsaddr = NULL;
3924 size_t nsaddr, nwsaddr;
3925 const char *share, *device_id;
3926 QemuConsole *con;
3927 bool password = false;
3928 bool reverse = false;
3929 const char *credid;
3930 bool sasl = false;
3931 int acl = 0;
3932 const char *tlsauthz;
3933 const char *saslauthz;
3934 int lock_key_sync = 1;
3935 int key_delay_ms;
3936 const char *audiodev;
3938 if (!vd) {
3939 error_setg(errp, "VNC display not active");
3940 return;
3942 vnc_display_close(vd);
3944 if (!opts) {
3945 return;
3948 reverse = qemu_opt_get_bool(opts, "reverse", false);
3949 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3950 &wsaddr, &nwsaddr, errp) < 0) {
3951 goto fail;
3954 password = qemu_opt_get_bool(opts, "password", false);
3955 if (password) {
3956 if (fips_get_state()) {
3957 error_setg(errp,
3958 "VNC password auth disabled due to FIPS mode, "
3959 "consider using the VeNCrypt or SASL authentication "
3960 "methods as an alternative");
3961 goto fail;
3963 if (!qcrypto_cipher_supports(
3964 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3965 error_setg(errp,
3966 "Cipher backend does not support DES RFB algorithm");
3967 goto fail;
3971 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3972 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
3973 sasl = qemu_opt_get_bool(opts, "sasl", false);
3974 #ifndef CONFIG_VNC_SASL
3975 if (sasl) {
3976 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3977 goto fail;
3979 #endif /* CONFIG_VNC_SASL */
3980 credid = qemu_opt_get(opts, "tls-creds");
3981 if (credid) {
3982 Object *creds;
3983 creds = object_resolve_path_component(
3984 object_get_objects_root(), credid);
3985 if (!creds) {
3986 error_setg(errp, "No TLS credentials with id '%s'",
3987 credid);
3988 goto fail;
3990 vd->tlscreds = (QCryptoTLSCreds *)
3991 object_dynamic_cast(creds,
3992 TYPE_QCRYPTO_TLS_CREDS);
3993 if (!vd->tlscreds) {
3994 error_setg(errp, "Object with id '%s' is not TLS credentials",
3995 credid);
3996 goto fail;
3998 object_ref(OBJECT(vd->tlscreds));
4000 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
4001 error_setg(errp,
4002 "Expecting TLS credentials with a server endpoint");
4003 goto fail;
4006 if (qemu_opt_get(opts, "acl")) {
4007 error_report("The 'acl' option to -vnc is deprecated. "
4008 "Please use the 'tls-authz' and 'sasl-authz' "
4009 "options instead");
4011 acl = qemu_opt_get_bool(opts, "acl", false);
4012 tlsauthz = qemu_opt_get(opts, "tls-authz");
4013 if (acl && tlsauthz) {
4014 error_setg(errp, "'acl' option is mutually exclusive with the "
4015 "'tls-authz' option");
4016 goto fail;
4018 if (tlsauthz && !vd->tlscreds) {
4019 error_setg(errp, "'tls-authz' provided but TLS is not enabled");
4020 goto fail;
4023 saslauthz = qemu_opt_get(opts, "sasl-authz");
4024 if (acl && saslauthz) {
4025 error_setg(errp, "'acl' option is mutually exclusive with the "
4026 "'sasl-authz' option");
4027 goto fail;
4029 if (saslauthz && !sasl) {
4030 error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
4031 goto fail;
4034 share = qemu_opt_get(opts, "share");
4035 if (share) {
4036 if (strcmp(share, "ignore") == 0) {
4037 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4038 } else if (strcmp(share, "allow-exclusive") == 0) {
4039 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4040 } else if (strcmp(share, "force-shared") == 0) {
4041 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4042 } else {
4043 error_setg(errp, "unknown vnc share= option");
4044 goto fail;
4046 } else {
4047 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4049 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4051 #ifdef CONFIG_VNC_JPEG
4052 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4053 #endif
4054 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
4055 /* adaptive updates are only used with tight encoding and
4056 * if lossy updates are enabled so we can disable all the
4057 * calculations otherwise */
4058 if (!vd->lossy) {
4059 vd->non_adaptive = true;
4062 vd->power_control = qemu_opt_get_bool(opts, "power-control", false);
4064 if (tlsauthz) {
4065 vd->tlsauthzid = g_strdup(tlsauthz);
4066 } else if (acl) {
4067 if (strcmp(vd->id, "default") == 0) {
4068 vd->tlsauthzid = g_strdup("vnc.x509dname");
4069 } else {
4070 vd->tlsauthzid = g_strdup_printf("vnc.%s.x509dname", vd->id);
4072 vd->tlsauthz = QAUTHZ(qauthz_list_new(vd->tlsauthzid,
4073 QAUTHZ_LIST_POLICY_DENY,
4074 &error_abort));
4076 #ifdef CONFIG_VNC_SASL
4077 if (sasl) {
4078 if (saslauthz) {
4079 vd->sasl.authzid = g_strdup(saslauthz);
4080 } else if (acl) {
4081 if (strcmp(vd->id, "default") == 0) {
4082 vd->sasl.authzid = g_strdup("vnc.username");
4083 } else {
4084 vd->sasl.authzid = g_strdup_printf("vnc.%s.username", vd->id);
4086 vd->sasl.authz = QAUTHZ(qauthz_list_new(vd->sasl.authzid,
4087 QAUTHZ_LIST_POLICY_DENY,
4088 &error_abort));
4091 #endif
4093 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4094 vd->tlscreds, password,
4095 sasl, false, errp) < 0) {
4096 goto fail;
4098 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
4100 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4101 vd->tlscreds, password,
4102 sasl, true, errp) < 0) {
4103 goto fail;
4105 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
4107 #ifdef CONFIG_VNC_SASL
4108 if (sasl) {
4109 int saslErr = sasl_server_init(NULL, "qemu");
4111 if (saslErr != SASL_OK) {
4112 error_setg(errp, "Failed to initialize SASL auth: %s",
4113 sasl_errstring(saslErr, NULL, NULL));
4114 goto fail;
4117 #endif
4118 vd->lock_key_sync = lock_key_sync;
4119 if (lock_key_sync) {
4120 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4122 vd->ledstate = 0;
4124 audiodev = qemu_opt_get(opts, "audiodev");
4125 if (audiodev) {
4126 vd->audio_state = audio_state_by_name(audiodev);
4127 if (!vd->audio_state) {
4128 error_setg(errp, "Audiodev '%s' not found", audiodev);
4129 goto fail;
4133 device_id = qemu_opt_get(opts, "display");
4134 if (device_id) {
4135 int head = qemu_opt_get_number(opts, "head", 0);
4136 Error *err = NULL;
4138 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4139 if (err) {
4140 error_propagate(errp, err);
4141 goto fail;
4143 } else {
4144 con = NULL;
4147 if (con != vd->dcl.con) {
4148 qkbd_state_free(vd->kbd);
4149 unregister_displaychangelistener(&vd->dcl);
4150 vd->dcl.con = con;
4151 register_displaychangelistener(&vd->dcl);
4152 vd->kbd = qkbd_state_init(vd->dcl.con);
4154 qkbd_state_set_delay(vd->kbd, key_delay_ms);
4156 if (saddr == NULL) {
4157 goto cleanup;
4160 if (reverse) {
4161 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4162 goto fail;
4164 } else {
4165 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4166 goto fail;
4170 if (qemu_opt_get(opts, "to")) {
4171 vnc_display_print_local_addr(vd);
4174 cleanup:
4175 vnc_free_addresses(&saddr, &nsaddr);
4176 vnc_free_addresses(&wsaddr, &nwsaddr);
4177 return;
4179 fail:
4180 vnc_display_close(vd);
4181 goto cleanup;
4184 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4186 VncDisplay *vd = vnc_display_find(id);
4187 QIOChannelSocket *sioc;
4189 if (!vd) {
4190 return;
4193 sioc = qio_channel_socket_new_fd(csock, NULL);
4194 if (sioc) {
4195 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4196 vnc_connect(vd, sioc, skipauth, false);
4197 object_unref(OBJECT(sioc));
4201 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4203 int i = 2;
4204 char *id;
4206 id = g_strdup("default");
4207 while (qemu_opts_find(olist, id)) {
4208 g_free(id);
4209 id = g_strdup_printf("vnc%d", i++);
4211 qemu_opts_set_id(opts, id);
4214 QemuOpts *vnc_parse(const char *str, Error **errp)
4216 QemuOptsList *olist = qemu_find_opts("vnc");
4217 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
4218 const char *id;
4220 if (!opts) {
4221 return NULL;
4224 id = qemu_opts_id(opts);
4225 if (!id) {
4226 /* auto-assign id if not present */
4227 vnc_auto_assign_id(olist, opts);
4229 return opts;
4232 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4234 Error *local_err = NULL;
4235 char *id = (char *)qemu_opts_id(opts);
4237 assert(id);
4238 vnc_display_init(id, &local_err);
4239 if (local_err) {
4240 error_propagate(errp, local_err);
4241 return -1;
4243 vnc_display_open(id, &local_err);
4244 if (local_err != NULL) {
4245 error_propagate(errp, local_err);
4246 return -1;
4248 return 0;
4251 static void vnc_register_config(void)
4253 qemu_add_opts(&qemu_vnc_opts);
4255 opts_init(vnc_register_config);