Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
[qemu/ar7.git] / ui / vnc.c
blobe0fac2136ea3f4dcb2b7ae4077d2d371a28a65cc
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 "crypto/secret_common.h"
52 #include "qom/object_interfaces.h"
53 #include "qemu/cutils.h"
54 #include "qemu/help_option.h"
55 #include "io/dns-resolver.h"
57 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
58 #define VNC_REFRESH_INTERVAL_INC 50
59 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
60 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
61 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
63 #include "vnc_keysym.h"
64 #include "crypto/cipher.h"
66 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
67 QTAILQ_HEAD_INITIALIZER(vnc_displays);
69 static int vnc_cursor_define(VncState *vs);
70 static void vnc_update_throttle_offset(VncState *vs);
72 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
74 #ifdef _VNC_DEBUG
75 static const char *mn[] = {
76 [0] = "undefined",
77 [VNC_SHARE_MODE_CONNECTING] = "connecting",
78 [VNC_SHARE_MODE_SHARED] = "shared",
79 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
80 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
82 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
83 vs->ioc, mn[vs->share_mode], mn[mode]);
84 #endif
86 switch (vs->share_mode) {
87 case VNC_SHARE_MODE_CONNECTING:
88 vs->vd->num_connecting--;
89 break;
90 case VNC_SHARE_MODE_SHARED:
91 vs->vd->num_shared--;
92 break;
93 case VNC_SHARE_MODE_EXCLUSIVE:
94 vs->vd->num_exclusive--;
95 break;
96 default:
97 break;
100 vs->share_mode = mode;
102 switch (vs->share_mode) {
103 case VNC_SHARE_MODE_CONNECTING:
104 vs->vd->num_connecting++;
105 break;
106 case VNC_SHARE_MODE_SHARED:
107 vs->vd->num_shared++;
108 break;
109 case VNC_SHARE_MODE_EXCLUSIVE:
110 vs->vd->num_exclusive++;
111 break;
112 default:
113 break;
118 static void vnc_init_basic_info(SocketAddress *addr,
119 VncBasicInfo *info,
120 Error **errp)
122 switch (addr->type) {
123 case SOCKET_ADDRESS_TYPE_INET:
124 info->host = g_strdup(addr->u.inet.host);
125 info->service = g_strdup(addr->u.inet.port);
126 if (addr->u.inet.ipv6) {
127 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
128 } else {
129 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
131 break;
133 case SOCKET_ADDRESS_TYPE_UNIX:
134 info->host = g_strdup("");
135 info->service = g_strdup(addr->u.q_unix.path);
136 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
137 break;
139 case SOCKET_ADDRESS_TYPE_VSOCK:
140 case SOCKET_ADDRESS_TYPE_FD:
141 error_setg(errp, "Unsupported socket address type %s",
142 SocketAddressType_str(addr->type));
143 break;
144 default:
145 abort();
148 return;
151 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
152 VncBasicInfo *info,
153 Error **errp)
155 SocketAddress *addr = NULL;
157 if (!ioc) {
158 error_setg(errp, "No listener socket available");
159 return;
162 addr = qio_channel_socket_get_local_address(ioc, errp);
163 if (!addr) {
164 return;
167 vnc_init_basic_info(addr, info, errp);
168 qapi_free_SocketAddress(addr);
171 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
172 VncBasicInfo *info,
173 Error **errp)
175 SocketAddress *addr = NULL;
177 addr = qio_channel_socket_get_remote_address(ioc, errp);
178 if (!addr) {
179 return;
182 vnc_init_basic_info(addr, info, errp);
183 qapi_free_SocketAddress(addr);
186 static const char *vnc_auth_name(VncDisplay *vd) {
187 switch (vd->auth) {
188 case VNC_AUTH_INVALID:
189 return "invalid";
190 case VNC_AUTH_NONE:
191 return "none";
192 case VNC_AUTH_VNC:
193 return "vnc";
194 case VNC_AUTH_RA2:
195 return "ra2";
196 case VNC_AUTH_RA2NE:
197 return "ra2ne";
198 case VNC_AUTH_TIGHT:
199 return "tight";
200 case VNC_AUTH_ULTRA:
201 return "ultra";
202 case VNC_AUTH_TLS:
203 return "tls";
204 case VNC_AUTH_VENCRYPT:
205 switch (vd->subauth) {
206 case VNC_AUTH_VENCRYPT_PLAIN:
207 return "vencrypt+plain";
208 case VNC_AUTH_VENCRYPT_TLSNONE:
209 return "vencrypt+tls+none";
210 case VNC_AUTH_VENCRYPT_TLSVNC:
211 return "vencrypt+tls+vnc";
212 case VNC_AUTH_VENCRYPT_TLSPLAIN:
213 return "vencrypt+tls+plain";
214 case VNC_AUTH_VENCRYPT_X509NONE:
215 return "vencrypt+x509+none";
216 case VNC_AUTH_VENCRYPT_X509VNC:
217 return "vencrypt+x509+vnc";
218 case VNC_AUTH_VENCRYPT_X509PLAIN:
219 return "vencrypt+x509+plain";
220 case VNC_AUTH_VENCRYPT_TLSSASL:
221 return "vencrypt+tls+sasl";
222 case VNC_AUTH_VENCRYPT_X509SASL:
223 return "vencrypt+x509+sasl";
224 default:
225 return "vencrypt";
227 case VNC_AUTH_SASL:
228 return "sasl";
230 return "unknown";
233 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
235 VncServerInfo *info;
236 Error *err = NULL;
238 if (!vd->listener || !vd->listener->nsioc) {
239 return NULL;
242 info = g_malloc0(sizeof(*info));
243 vnc_init_basic_info_from_server_addr(vd->listener->sioc[0],
244 qapi_VncServerInfo_base(info), &err);
245 info->has_auth = true;
246 info->auth = g_strdup(vnc_auth_name(vd));
247 if (err) {
248 qapi_free_VncServerInfo(info);
249 info = NULL;
250 error_free(err);
252 return info;
255 static void vnc_client_cache_auth(VncState *client)
257 if (!client->info) {
258 return;
261 if (client->tls) {
262 client->info->x509_dname =
263 qcrypto_tls_session_get_peer_name(client->tls);
264 client->info->has_x509_dname =
265 client->info->x509_dname != NULL;
267 #ifdef CONFIG_VNC_SASL
268 if (client->sasl.conn &&
269 client->sasl.username) {
270 client->info->has_sasl_username = true;
271 client->info->sasl_username = g_strdup(client->sasl.username);
273 #endif
276 static void vnc_client_cache_addr(VncState *client)
278 Error *err = NULL;
280 client->info = g_malloc0(sizeof(*client->info));
281 vnc_init_basic_info_from_remote_addr(client->sioc,
282 qapi_VncClientInfo_base(client->info),
283 &err);
284 client->info->websocket = client->websocket;
285 if (err) {
286 qapi_free_VncClientInfo(client->info);
287 client->info = NULL;
288 error_free(err);
292 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
294 VncServerInfo *si;
296 if (!vs->info) {
297 return;
300 si = vnc_server_info_get(vs->vd);
301 if (!si) {
302 return;
305 switch (event) {
306 case QAPI_EVENT_VNC_CONNECTED:
307 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info));
308 break;
309 case QAPI_EVENT_VNC_INITIALIZED:
310 qapi_event_send_vnc_initialized(si, vs->info);
311 break;
312 case QAPI_EVENT_VNC_DISCONNECTED:
313 qapi_event_send_vnc_disconnected(si, vs->info);
314 break;
315 default:
316 break;
319 qapi_free_VncServerInfo(si);
322 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
324 VncClientInfo *info;
325 Error *err = NULL;
327 info = g_malloc0(sizeof(*info));
329 vnc_init_basic_info_from_remote_addr(client->sioc,
330 qapi_VncClientInfo_base(info),
331 &err);
332 if (err) {
333 error_free(err);
334 qapi_free_VncClientInfo(info);
335 return NULL;
338 info->websocket = client->websocket;
340 if (client->tls) {
341 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
342 info->has_x509_dname = info->x509_dname != NULL;
344 #ifdef CONFIG_VNC_SASL
345 if (client->sasl.conn && client->sasl.username) {
346 info->has_sasl_username = true;
347 info->sasl_username = g_strdup(client->sasl.username);
349 #endif
351 return info;
354 static VncDisplay *vnc_display_find(const char *id)
356 VncDisplay *vd;
358 if (id == NULL) {
359 return QTAILQ_FIRST(&vnc_displays);
361 QTAILQ_FOREACH(vd, &vnc_displays, next) {
362 if (strcmp(id, vd->id) == 0) {
363 return vd;
366 return NULL;
369 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
371 VncClientInfoList *prev = NULL;
372 VncState *client;
374 QTAILQ_FOREACH(client, &vd->clients, next) {
375 QAPI_LIST_PREPEND(prev, qmp_query_vnc_client(client));
377 return prev;
380 VncInfo *qmp_query_vnc(Error **errp)
382 VncInfo *info = g_malloc0(sizeof(*info));
383 VncDisplay *vd = vnc_display_find(NULL);
384 SocketAddress *addr = NULL;
386 if (vd == NULL || !vd->listener || !vd->listener->nsioc) {
387 info->enabled = false;
388 } else {
389 info->enabled = true;
391 /* for compatibility with the original command */
392 info->has_clients = true;
393 info->clients = qmp_query_client_list(vd);
395 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0],
396 errp);
397 if (!addr) {
398 goto out_error;
401 switch (addr->type) {
402 case SOCKET_ADDRESS_TYPE_INET:
403 info->host = g_strdup(addr->u.inet.host);
404 info->service = g_strdup(addr->u.inet.port);
405 if (addr->u.inet.ipv6) {
406 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
407 } else {
408 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
410 break;
412 case SOCKET_ADDRESS_TYPE_UNIX:
413 info->host = g_strdup("");
414 info->service = g_strdup(addr->u.q_unix.path);
415 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
416 break;
418 case SOCKET_ADDRESS_TYPE_VSOCK:
419 case SOCKET_ADDRESS_TYPE_FD:
420 error_setg(errp, "Unsupported socket address type %s",
421 SocketAddressType_str(addr->type));
422 goto out_error;
423 default:
424 abort();
427 info->has_host = true;
428 info->has_service = true;
429 info->has_family = true;
431 info->has_auth = true;
432 info->auth = g_strdup(vnc_auth_name(vd));
435 qapi_free_SocketAddress(addr);
436 return info;
438 out_error:
439 qapi_free_SocketAddress(addr);
440 qapi_free_VncInfo(info);
441 return NULL;
445 static void qmp_query_auth(int auth, int subauth,
446 VncPrimaryAuth *qmp_auth,
447 VncVencryptSubAuth *qmp_vencrypt,
448 bool *qmp_has_vencrypt);
450 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
451 bool websocket,
452 int auth,
453 int subauth,
454 VncServerInfo2List *prev)
456 VncServerInfo2 *info;
457 Error *err = NULL;
458 SocketAddress *addr;
460 addr = qio_channel_socket_get_local_address(ioc, NULL);
461 if (!addr) {
462 return prev;
465 info = g_new0(VncServerInfo2, 1);
466 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
467 qapi_free_SocketAddress(addr);
468 if (err) {
469 qapi_free_VncServerInfo2(info);
470 error_free(err);
471 return prev;
473 info->websocket = websocket;
475 qmp_query_auth(auth, subauth, &info->auth,
476 &info->vencrypt, &info->has_vencrypt);
478 QAPI_LIST_PREPEND(prev, info);
479 return prev;
482 static void qmp_query_auth(int auth, int subauth,
483 VncPrimaryAuth *qmp_auth,
484 VncVencryptSubAuth *qmp_vencrypt,
485 bool *qmp_has_vencrypt)
487 switch (auth) {
488 case VNC_AUTH_VNC:
489 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
490 break;
491 case VNC_AUTH_RA2:
492 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
493 break;
494 case VNC_AUTH_RA2NE:
495 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
496 break;
497 case VNC_AUTH_TIGHT:
498 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
499 break;
500 case VNC_AUTH_ULTRA:
501 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
502 break;
503 case VNC_AUTH_TLS:
504 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
505 break;
506 case VNC_AUTH_VENCRYPT:
507 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
508 *qmp_has_vencrypt = true;
509 switch (subauth) {
510 case VNC_AUTH_VENCRYPT_PLAIN:
511 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
512 break;
513 case VNC_AUTH_VENCRYPT_TLSNONE:
514 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
515 break;
516 case VNC_AUTH_VENCRYPT_TLSVNC:
517 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
518 break;
519 case VNC_AUTH_VENCRYPT_TLSPLAIN:
520 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
521 break;
522 case VNC_AUTH_VENCRYPT_X509NONE:
523 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
524 break;
525 case VNC_AUTH_VENCRYPT_X509VNC:
526 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
527 break;
528 case VNC_AUTH_VENCRYPT_X509PLAIN:
529 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
530 break;
531 case VNC_AUTH_VENCRYPT_TLSSASL:
532 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
533 break;
534 case VNC_AUTH_VENCRYPT_X509SASL:
535 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
536 break;
537 default:
538 *qmp_has_vencrypt = false;
539 break;
541 break;
542 case VNC_AUTH_SASL:
543 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
544 break;
545 case VNC_AUTH_NONE:
546 default:
547 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
548 break;
552 VncInfo2List *qmp_query_vnc_servers(Error **errp)
554 VncInfo2List *prev = NULL;
555 VncInfo2 *info;
556 VncDisplay *vd;
557 DeviceState *dev;
558 size_t i;
560 QTAILQ_FOREACH(vd, &vnc_displays, next) {
561 info = g_new0(VncInfo2, 1);
562 info->id = g_strdup(vd->id);
563 info->clients = qmp_query_client_list(vd);
564 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
565 &info->vencrypt, &info->has_vencrypt);
566 if (vd->dcl.con) {
567 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
568 "device", &error_abort));
569 info->has_display = true;
570 info->display = g_strdup(dev->id);
572 for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) {
573 info->server = qmp_query_server_entry(
574 vd->listener->sioc[i], false, vd->auth, vd->subauth,
575 info->server);
577 for (i = 0; vd->wslistener != NULL && i < vd->wslistener->nsioc; i++) {
578 info->server = qmp_query_server_entry(
579 vd->wslistener->sioc[i], true, vd->ws_auth,
580 vd->ws_subauth, info->server);
583 QAPI_LIST_PREPEND(prev, info);
585 return prev;
588 /* TODO
589 1) Get the queue working for IO.
590 2) there is some weirdness when using the -S option (the screen is grey
591 and not totally invalidated
592 3) resolutions > 1024
595 static int vnc_update_client(VncState *vs, int has_dirty);
596 static void vnc_disconnect_start(VncState *vs);
598 static void vnc_colordepth(VncState *vs);
599 static void framebuffer_update_request(VncState *vs, int incremental,
600 int x_position, int y_position,
601 int w, int h);
602 static void vnc_refresh(DisplayChangeListener *dcl);
603 static int vnc_refresh_server_surface(VncDisplay *vd);
605 static int vnc_width(VncDisplay *vd)
607 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
608 VNC_DIRTY_PIXELS_PER_BIT));
611 static int vnc_true_width(VncDisplay *vd)
613 return MIN(VNC_MAX_WIDTH, surface_width(vd->ds));
616 static int vnc_height(VncDisplay *vd)
618 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
621 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
622 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
623 VncDisplay *vd,
624 int x, int y, int w, int h)
626 int width = vnc_width(vd);
627 int height = vnc_height(vd);
629 /* this is needed this to ensure we updated all affected
630 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
631 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
632 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
634 x = MIN(x, width);
635 y = MIN(y, height);
636 w = MIN(x + w, width) - x;
637 h = MIN(y + h, height);
639 for (; y < h; y++) {
640 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
641 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
645 static void vnc_dpy_update(DisplayChangeListener *dcl,
646 int x, int y, int w, int h)
648 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
649 struct VncSurface *s = &vd->guest;
651 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
654 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
655 int32_t encoding)
657 vnc_write_u16(vs, x);
658 vnc_write_u16(vs, y);
659 vnc_write_u16(vs, w);
660 vnc_write_u16(vs, h);
662 vnc_write_s32(vs, encoding);
665 static void vnc_desktop_resize_ext(VncState *vs, int reject_reason)
667 trace_vnc_msg_server_ext_desktop_resize(
668 vs, vs->ioc, vs->client_width, vs->client_height, reject_reason);
670 vnc_lock_output(vs);
671 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
672 vnc_write_u8(vs, 0);
673 vnc_write_u16(vs, 1); /* number of rects */
674 vnc_framebuffer_update(vs,
675 reject_reason ? 1 : 0,
676 reject_reason,
677 vs->client_width, vs->client_height,
678 VNC_ENCODING_DESKTOP_RESIZE_EXT);
679 vnc_write_u8(vs, 1); /* number of screens */
680 vnc_write_u8(vs, 0); /* padding */
681 vnc_write_u8(vs, 0); /* padding */
682 vnc_write_u8(vs, 0); /* padding */
683 vnc_write_u32(vs, 0); /* screen id */
684 vnc_write_u16(vs, 0); /* screen x-pos */
685 vnc_write_u16(vs, 0); /* screen y-pos */
686 vnc_write_u16(vs, vs->client_width);
687 vnc_write_u16(vs, vs->client_height);
688 vnc_write_u32(vs, 0); /* screen flags */
689 vnc_unlock_output(vs);
690 vnc_flush(vs);
693 static void vnc_desktop_resize(VncState *vs)
695 if (vs->ioc == NULL || (!vnc_has_feature(vs, VNC_FEATURE_RESIZE) &&
696 !vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT))) {
697 return;
699 if (vs->client_width == vs->vd->true_width &&
700 vs->client_height == pixman_image_get_height(vs->vd->server)) {
701 return;
704 assert(vs->vd->true_width < 65536 &&
705 vs->vd->true_width >= 0);
706 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
707 pixman_image_get_height(vs->vd->server) >= 0);
708 vs->client_width = vs->vd->true_width;
709 vs->client_height = pixman_image_get_height(vs->vd->server);
711 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
712 vnc_desktop_resize_ext(vs, 0);
713 return;
716 trace_vnc_msg_server_desktop_resize(
717 vs, vs->ioc, vs->client_width, vs->client_height);
719 vnc_lock_output(vs);
720 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
721 vnc_write_u8(vs, 0);
722 vnc_write_u16(vs, 1); /* number of rects */
723 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
724 VNC_ENCODING_DESKTOPRESIZE);
725 vnc_unlock_output(vs);
726 vnc_flush(vs);
729 static void vnc_abort_display_jobs(VncDisplay *vd)
731 VncState *vs;
733 QTAILQ_FOREACH(vs, &vd->clients, next) {
734 vnc_lock_output(vs);
735 vs->abort = true;
736 vnc_unlock_output(vs);
738 QTAILQ_FOREACH(vs, &vd->clients, next) {
739 vnc_jobs_join(vs);
741 QTAILQ_FOREACH(vs, &vd->clients, next) {
742 vnc_lock_output(vs);
743 if (vs->update == VNC_STATE_UPDATE_NONE &&
744 vs->job_update != VNC_STATE_UPDATE_NONE) {
745 /* job aborted before completion */
746 vs->update = vs->job_update;
747 vs->job_update = VNC_STATE_UPDATE_NONE;
749 vs->abort = false;
750 vnc_unlock_output(vs);
754 int vnc_server_fb_stride(VncDisplay *vd)
756 return pixman_image_get_stride(vd->server);
759 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
761 uint8_t *ptr;
763 ptr = (uint8_t *)pixman_image_get_data(vd->server);
764 ptr += y * vnc_server_fb_stride(vd);
765 ptr += x * VNC_SERVER_FB_BYTES;
766 return ptr;
769 static void vnc_update_server_surface(VncDisplay *vd)
771 int width, height;
773 qemu_pixman_image_unref(vd->server);
774 vd->server = NULL;
776 if (QTAILQ_EMPTY(&vd->clients)) {
777 return;
780 width = vnc_width(vd);
781 height = vnc_height(vd);
782 vd->true_width = vnc_true_width(vd);
783 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
784 width, height,
785 NULL, 0);
787 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
788 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
789 width, height);
792 static bool vnc_check_pageflip(DisplaySurface *s1,
793 DisplaySurface *s2)
795 return (s1 != NULL &&
796 s2 != NULL &&
797 surface_width(s1) == surface_width(s2) &&
798 surface_height(s1) == surface_height(s2) &&
799 surface_format(s1) == surface_format(s2));
803 static void vnc_dpy_switch(DisplayChangeListener *dcl,
804 DisplaySurface *surface)
806 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
807 bool pageflip = vnc_check_pageflip(vd->ds, surface);
808 VncState *vs;
810 vnc_abort_display_jobs(vd);
811 vd->ds = surface;
813 /* guest surface */
814 qemu_pixman_image_unref(vd->guest.fb);
815 vd->guest.fb = pixman_image_ref(surface->image);
816 vd->guest.format = surface->format;
819 if (pageflip) {
820 trace_vnc_server_dpy_pageflip(vd,
821 surface_width(surface),
822 surface_height(surface),
823 surface_format(surface));
824 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
825 surface_width(surface),
826 surface_height(surface));
827 return;
830 trace_vnc_server_dpy_recreate(vd,
831 surface_width(surface),
832 surface_height(surface),
833 surface_format(surface));
834 /* server surface */
835 vnc_update_server_surface(vd);
837 QTAILQ_FOREACH(vs, &vd->clients, next) {
838 vnc_colordepth(vs);
839 vnc_desktop_resize(vs);
840 vnc_cursor_define(vs);
841 memset(vs->dirty, 0x00, sizeof(vs->dirty));
842 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
843 vnc_width(vd),
844 vnc_height(vd));
845 vnc_update_throttle_offset(vs);
849 /* fastest code */
850 static void vnc_write_pixels_copy(VncState *vs,
851 void *pixels, int size)
853 vnc_write(vs, pixels, size);
856 /* slowest but generic code. */
857 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
859 uint8_t r, g, b;
861 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
862 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
863 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
864 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
865 #else
866 # error need some bits here if you change VNC_SERVER_FB_FORMAT
867 #endif
868 v = (r << vs->client_pf.rshift) |
869 (g << vs->client_pf.gshift) |
870 (b << vs->client_pf.bshift);
871 switch (vs->client_pf.bytes_per_pixel) {
872 case 1:
873 buf[0] = v;
874 break;
875 case 2:
876 if (vs->client_be) {
877 buf[0] = v >> 8;
878 buf[1] = v;
879 } else {
880 buf[1] = v >> 8;
881 buf[0] = v;
883 break;
884 default:
885 case 4:
886 if (vs->client_be) {
887 buf[0] = v >> 24;
888 buf[1] = v >> 16;
889 buf[2] = v >> 8;
890 buf[3] = v;
891 } else {
892 buf[3] = v >> 24;
893 buf[2] = v >> 16;
894 buf[1] = v >> 8;
895 buf[0] = v;
897 break;
901 static void vnc_write_pixels_generic(VncState *vs,
902 void *pixels1, int size)
904 uint8_t buf[4];
906 if (VNC_SERVER_FB_BYTES == 4) {
907 uint32_t *pixels = pixels1;
908 int n, i;
909 n = size >> 2;
910 for (i = 0; i < n; i++) {
911 vnc_convert_pixel(vs, buf, pixels[i]);
912 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
917 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
919 int i;
920 uint8_t *row;
921 VncDisplay *vd = vs->vd;
923 row = vnc_server_fb_ptr(vd, x, y);
924 for (i = 0; i < h; i++) {
925 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
926 row += vnc_server_fb_stride(vd);
928 return 1;
931 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
933 int n = 0;
935 switch(vs->vnc_encoding) {
936 case VNC_ENCODING_ZLIB:
937 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
938 break;
939 case VNC_ENCODING_HEXTILE:
940 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
941 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
942 break;
943 case VNC_ENCODING_TIGHT:
944 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
945 break;
946 case VNC_ENCODING_TIGHT_PNG:
947 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
948 break;
949 case VNC_ENCODING_ZRLE:
950 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
951 break;
952 case VNC_ENCODING_ZYWRLE:
953 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
954 break;
955 default:
956 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
957 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
958 break;
960 return n;
963 static void vnc_mouse_set(DisplayChangeListener *dcl,
964 int x, int y, int visible)
966 /* can we ask the client(s) to move the pointer ??? */
969 static int vnc_cursor_define(VncState *vs)
971 QEMUCursor *c = vs->vd->cursor;
972 int isize;
974 if (!vs->vd->cursor) {
975 return -1;
978 if (vnc_has_feature(vs, VNC_FEATURE_ALPHA_CURSOR)) {
979 vnc_lock_output(vs);
980 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
981 vnc_write_u8(vs, 0); /* padding */
982 vnc_write_u16(vs, 1); /* # of rects */
983 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
984 VNC_ENCODING_ALPHA_CURSOR);
985 vnc_write_s32(vs, VNC_ENCODING_RAW);
986 vnc_write(vs, c->data, c->width * c->height * 4);
987 vnc_unlock_output(vs);
988 return 0;
990 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
991 vnc_lock_output(vs);
992 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
993 vnc_write_u8(vs, 0); /* padding */
994 vnc_write_u16(vs, 1); /* # of rects */
995 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
996 VNC_ENCODING_RICH_CURSOR);
997 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
998 vnc_write_pixels_generic(vs, c->data, isize);
999 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
1000 vnc_unlock_output(vs);
1001 return 0;
1003 return -1;
1006 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1007 QEMUCursor *c)
1009 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1010 VncState *vs;
1012 cursor_put(vd->cursor);
1013 g_free(vd->cursor_mask);
1015 vd->cursor = c;
1016 cursor_get(vd->cursor);
1017 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1018 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1019 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1021 QTAILQ_FOREACH(vs, &vd->clients, next) {
1022 vnc_cursor_define(vs);
1026 static int find_and_clear_dirty_height(VncState *vs,
1027 int y, int last_x, int x, int height)
1029 int h;
1031 for (h = 1; h < (height - y); h++) {
1032 if (!test_bit(last_x, vs->dirty[y + h])) {
1033 break;
1035 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1038 return h;
1042 * Figure out how much pending data we should allow in the output
1043 * buffer before we throttle incremental display updates, and/or
1044 * drop audio samples.
1046 * We allow for equiv of 1 full display's worth of FB updates,
1047 * and 1 second of audio samples. If audio backlog was larger
1048 * than that the client would already suffering awful audio
1049 * glitches, so dropping samples is no worse really).
1051 static void vnc_update_throttle_offset(VncState *vs)
1053 size_t offset =
1054 vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
1056 if (vs->audio_cap) {
1057 int bps;
1058 switch (vs->as.fmt) {
1059 default:
1060 case AUDIO_FORMAT_U8:
1061 case AUDIO_FORMAT_S8:
1062 bps = 1;
1063 break;
1064 case AUDIO_FORMAT_U16:
1065 case AUDIO_FORMAT_S16:
1066 bps = 2;
1067 break;
1068 case AUDIO_FORMAT_U32:
1069 case AUDIO_FORMAT_S32:
1070 bps = 4;
1071 break;
1073 offset += vs->as.freq * bps * vs->as.nchannels;
1076 /* Put a floor of 1MB on offset, so that if we have a large pending
1077 * buffer and the display is resized to a small size & back again
1078 * we don't suddenly apply a tiny send limit
1080 offset = MAX(offset, 1024 * 1024);
1082 if (vs->throttle_output_offset != offset) {
1083 trace_vnc_client_throttle_threshold(
1084 vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
1085 vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
1088 vs->throttle_output_offset = offset;
1091 static bool vnc_should_update(VncState *vs)
1093 switch (vs->update) {
1094 case VNC_STATE_UPDATE_NONE:
1095 break;
1096 case VNC_STATE_UPDATE_INCREMENTAL:
1097 /* Only allow incremental updates if the pending send queue
1098 * is less than the permitted threshold, and the job worker
1099 * is completely idle.
1101 if (vs->output.offset < vs->throttle_output_offset &&
1102 vs->job_update == VNC_STATE_UPDATE_NONE) {
1103 return true;
1105 trace_vnc_client_throttle_incremental(
1106 vs, vs->ioc, vs->job_update, vs->output.offset);
1107 break;
1108 case VNC_STATE_UPDATE_FORCE:
1109 /* Only allow forced updates if the pending send queue
1110 * does not contain a previous forced update, and the
1111 * job worker is completely idle.
1113 * Note this means we'll queue a forced update, even if
1114 * the output buffer size is otherwise over the throttle
1115 * output limit.
1117 if (vs->force_update_offset == 0 &&
1118 vs->job_update == VNC_STATE_UPDATE_NONE) {
1119 return true;
1121 trace_vnc_client_throttle_forced(
1122 vs, vs->ioc, vs->job_update, vs->force_update_offset);
1123 break;
1125 return false;
1128 static int vnc_update_client(VncState *vs, int has_dirty)
1130 VncDisplay *vd = vs->vd;
1131 VncJob *job;
1132 int y;
1133 int height, width;
1134 int n = 0;
1136 if (vs->disconnecting) {
1137 vnc_disconnect_finish(vs);
1138 return 0;
1141 vs->has_dirty += has_dirty;
1142 if (!vnc_should_update(vs)) {
1143 return 0;
1146 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
1147 return 0;
1151 * Send screen updates to the vnc client using the server
1152 * surface and server dirty map. guest surface updates
1153 * happening in parallel don't disturb us, the next pass will
1154 * send them to the client.
1156 job = vnc_job_new(vs);
1158 height = pixman_image_get_height(vd->server);
1159 width = pixman_image_get_width(vd->server);
1161 y = 0;
1162 for (;;) {
1163 int x, h;
1164 unsigned long x2;
1165 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1166 height * VNC_DIRTY_BPL(vs),
1167 y * VNC_DIRTY_BPL(vs));
1168 if (offset == height * VNC_DIRTY_BPL(vs)) {
1169 /* no more dirty bits */
1170 break;
1172 y = offset / VNC_DIRTY_BPL(vs);
1173 x = offset % VNC_DIRTY_BPL(vs);
1174 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1175 VNC_DIRTY_BPL(vs), x);
1176 bitmap_clear(vs->dirty[y], x, x2 - x);
1177 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1178 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1179 if (x2 > x) {
1180 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1181 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1183 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1184 y += h;
1185 if (y == height) {
1186 break;
1191 vs->job_update = vs->update;
1192 vs->update = VNC_STATE_UPDATE_NONE;
1193 vnc_job_push(job);
1194 vs->has_dirty = 0;
1195 return n;
1198 /* audio */
1199 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1201 VncState *vs = opaque;
1203 assert(vs->magic == VNC_MAGIC);
1204 switch (cmd) {
1205 case AUD_CNOTIFY_DISABLE:
1206 trace_vnc_msg_server_audio_end(vs, vs->ioc);
1207 vnc_lock_output(vs);
1208 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1209 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1210 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1211 vnc_unlock_output(vs);
1212 vnc_flush(vs);
1213 break;
1215 case AUD_CNOTIFY_ENABLE:
1216 trace_vnc_msg_server_audio_begin(vs, vs->ioc);
1217 vnc_lock_output(vs);
1218 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1219 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1220 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1221 vnc_unlock_output(vs);
1222 vnc_flush(vs);
1223 break;
1227 static void audio_capture_destroy(void *opaque)
1231 static void audio_capture(void *opaque, const void *buf, int size)
1233 VncState *vs = opaque;
1235 assert(vs->magic == VNC_MAGIC);
1236 trace_vnc_msg_server_audio_data(vs, vs->ioc, buf, size);
1237 vnc_lock_output(vs);
1238 if (vs->output.offset < vs->throttle_output_offset) {
1239 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1240 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1241 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1242 vnc_write_u32(vs, size);
1243 vnc_write(vs, buf, size);
1244 } else {
1245 trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
1247 vnc_unlock_output(vs);
1248 vnc_flush(vs);
1251 static void audio_add(VncState *vs)
1253 struct audio_capture_ops ops;
1255 if (vs->audio_cap) {
1256 error_report("audio already running");
1257 return;
1260 ops.notify = audio_capture_notify;
1261 ops.destroy = audio_capture_destroy;
1262 ops.capture = audio_capture;
1264 vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs);
1265 if (!vs->audio_cap) {
1266 error_report("Failed to add audio capture");
1270 static void audio_del(VncState *vs)
1272 if (vs->audio_cap) {
1273 AUD_del_capture(vs->audio_cap, vs);
1274 vs->audio_cap = NULL;
1278 static void vnc_disconnect_start(VncState *vs)
1280 if (vs->disconnecting) {
1281 return;
1283 trace_vnc_client_disconnect_start(vs, vs->ioc);
1284 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1285 if (vs->ioc_tag) {
1286 g_source_remove(vs->ioc_tag);
1287 vs->ioc_tag = 0;
1289 qio_channel_close(vs->ioc, NULL);
1290 vs->disconnecting = TRUE;
1293 void vnc_disconnect_finish(VncState *vs)
1295 int i;
1297 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1299 vnc_jobs_join(vs); /* Wait encoding jobs */
1301 vnc_lock_output(vs);
1302 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1304 buffer_free(&vs->input);
1305 buffer_free(&vs->output);
1307 qapi_free_VncClientInfo(vs->info);
1309 vnc_zlib_clear(vs);
1310 vnc_tight_clear(vs);
1311 vnc_zrle_clear(vs);
1313 #ifdef CONFIG_VNC_SASL
1314 vnc_sasl_client_cleanup(vs);
1315 #endif /* CONFIG_VNC_SASL */
1316 audio_del(vs);
1317 qkbd_state_lift_all_keys(vs->vd->kbd);
1319 if (vs->mouse_mode_notifier.notify != NULL) {
1320 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1322 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1323 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1324 /* last client gone */
1325 vnc_update_server_surface(vs->vd);
1328 vnc_unlock_output(vs);
1330 qemu_mutex_destroy(&vs->output_mutex);
1331 if (vs->bh != NULL) {
1332 qemu_bh_delete(vs->bh);
1334 buffer_free(&vs->jobs_buffer);
1336 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1337 g_free(vs->lossy_rect[i]);
1339 g_free(vs->lossy_rect);
1341 object_unref(OBJECT(vs->ioc));
1342 vs->ioc = NULL;
1343 object_unref(OBJECT(vs->sioc));
1344 vs->sioc = NULL;
1345 vs->magic = 0;
1346 g_free(vs->zrle);
1347 g_free(vs->tight);
1348 g_free(vs);
1351 size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err)
1353 if (ret <= 0) {
1354 if (ret == 0) {
1355 trace_vnc_client_eof(vs, vs->ioc);
1356 vnc_disconnect_start(vs);
1357 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1358 trace_vnc_client_io_error(vs, vs->ioc,
1359 err ? error_get_pretty(err) : "Unknown");
1360 vnc_disconnect_start(vs);
1363 error_free(err);
1364 return 0;
1366 return ret;
1370 void vnc_client_error(VncState *vs)
1372 VNC_DEBUG("Closing down client sock: protocol error\n");
1373 vnc_disconnect_start(vs);
1378 * Called to write a chunk of data to the client socket. The data may
1379 * be the raw data, or may have already been encoded by SASL.
1380 * The data will be written either straight onto the socket, or
1381 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1383 * NB, it is theoretically possible to have 2 layers of encryption,
1384 * both SASL, and this TLS layer. It is highly unlikely in practice
1385 * though, since SASL encryption will typically be a no-op if TLS
1386 * is active
1388 * Returns the number of bytes written, which may be less than
1389 * the requested 'datalen' if the socket would block. Returns
1390 * 0 on I/O error, and disconnects the client socket.
1392 size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1394 Error *err = NULL;
1395 ssize_t ret;
1396 ret = qio_channel_write(vs->ioc, (const char *)data, datalen, &err);
1397 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1398 return vnc_client_io_error(vs, ret, err);
1403 * Called to write buffered data to the client socket, when not
1404 * using any SASL SSF encryption layers. Will write as much data
1405 * as possible without blocking. If all buffered data is written,
1406 * will switch the FD poll() handler back to read monitoring.
1408 * Returns the number of bytes written, which may be less than
1409 * the buffered output data if the socket would block. Returns
1410 * 0 on I/O error, and disconnects the client socket.
1412 static size_t vnc_client_write_plain(VncState *vs)
1414 size_t offset;
1415 size_t ret;
1417 #ifdef CONFIG_VNC_SASL
1418 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1419 vs->output.buffer, vs->output.capacity, vs->output.offset,
1420 vs->sasl.waitWriteSSF);
1422 if (vs->sasl.conn &&
1423 vs->sasl.runSSF &&
1424 vs->sasl.waitWriteSSF) {
1425 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1426 if (ret)
1427 vs->sasl.waitWriteSSF -= ret;
1428 } else
1429 #endif /* CONFIG_VNC_SASL */
1430 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1431 if (!ret)
1432 return 0;
1434 if (ret >= vs->force_update_offset) {
1435 if (vs->force_update_offset != 0) {
1436 trace_vnc_client_unthrottle_forced(vs, vs->ioc);
1438 vs->force_update_offset = 0;
1439 } else {
1440 vs->force_update_offset -= ret;
1442 offset = vs->output.offset;
1443 buffer_advance(&vs->output, ret);
1444 if (offset >= vs->throttle_output_offset &&
1445 vs->output.offset < vs->throttle_output_offset) {
1446 trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
1449 if (vs->output.offset == 0) {
1450 if (vs->ioc_tag) {
1451 g_source_remove(vs->ioc_tag);
1453 vs->ioc_tag = qio_channel_add_watch(
1454 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1455 vnc_client_io, vs, NULL);
1458 return ret;
1463 * First function called whenever there is data to be written to
1464 * the client socket. Will delegate actual work according to whether
1465 * SASL SSF layers are enabled (thus requiring encryption calls)
1467 static void vnc_client_write_locked(VncState *vs)
1469 #ifdef CONFIG_VNC_SASL
1470 if (vs->sasl.conn &&
1471 vs->sasl.runSSF &&
1472 !vs->sasl.waitWriteSSF) {
1473 vnc_client_write_sasl(vs);
1474 } else
1475 #endif /* CONFIG_VNC_SASL */
1477 vnc_client_write_plain(vs);
1481 static void vnc_client_write(VncState *vs)
1483 assert(vs->magic == VNC_MAGIC);
1484 vnc_lock_output(vs);
1485 if (vs->output.offset) {
1486 vnc_client_write_locked(vs);
1487 } else if (vs->ioc != NULL) {
1488 if (vs->ioc_tag) {
1489 g_source_remove(vs->ioc_tag);
1491 vs->ioc_tag = qio_channel_add_watch(
1492 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1493 vnc_client_io, vs, NULL);
1495 vnc_unlock_output(vs);
1498 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1500 vs->read_handler = func;
1501 vs->read_handler_expect = expecting;
1506 * Called to read a chunk of data from the client socket. The data may
1507 * be the raw data, or may need to be further decoded by SASL.
1508 * The data will be read either straight from to the socket, or
1509 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1511 * NB, it is theoretically possible to have 2 layers of encryption,
1512 * both SASL, and this TLS layer. It is highly unlikely in practice
1513 * though, since SASL encryption will typically be a no-op if TLS
1514 * is active
1516 * Returns the number of bytes read, which may be less than
1517 * the requested 'datalen' if the socket would block. Returns
1518 * 0 on I/O error or EOF, and disconnects the client socket.
1520 size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1522 ssize_t ret;
1523 Error *err = NULL;
1524 ret = qio_channel_read(vs->ioc, (char *)data, datalen, &err);
1525 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1526 return vnc_client_io_error(vs, ret, err);
1531 * Called to read data from the client socket to the input buffer,
1532 * when not using any SASL SSF encryption layers. Will read as much
1533 * data as possible without blocking.
1535 * Returns the number of bytes read, which may be less than
1536 * the requested 'datalen' if the socket would block. Returns
1537 * 0 on I/O error or EOF, and disconnects the client socket.
1539 static size_t vnc_client_read_plain(VncState *vs)
1541 size_t ret;
1542 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1543 vs->input.buffer, vs->input.capacity, vs->input.offset);
1544 buffer_reserve(&vs->input, 4096);
1545 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1546 if (!ret)
1547 return 0;
1548 vs->input.offset += ret;
1549 return ret;
1552 static void vnc_jobs_bh(void *opaque)
1554 VncState *vs = opaque;
1556 assert(vs->magic == VNC_MAGIC);
1557 vnc_jobs_consume_buffer(vs);
1561 * First function called whenever there is more data to be read from
1562 * the client socket. Will delegate actual work according to whether
1563 * SASL SSF layers are enabled (thus requiring decryption calls)
1564 * Returns 0 on success, -1 if client disconnected
1566 static int vnc_client_read(VncState *vs)
1568 size_t ret;
1570 #ifdef CONFIG_VNC_SASL
1571 if (vs->sasl.conn && vs->sasl.runSSF)
1572 ret = vnc_client_read_sasl(vs);
1573 else
1574 #endif /* CONFIG_VNC_SASL */
1575 ret = vnc_client_read_plain(vs);
1576 if (!ret) {
1577 if (vs->disconnecting) {
1578 vnc_disconnect_finish(vs);
1579 return -1;
1581 return 0;
1584 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1585 size_t len = vs->read_handler_expect;
1586 int ret;
1588 ret = vs->read_handler(vs, vs->input.buffer, len);
1589 if (vs->disconnecting) {
1590 vnc_disconnect_finish(vs);
1591 return -1;
1594 if (!ret) {
1595 buffer_advance(&vs->input, len);
1596 } else {
1597 vs->read_handler_expect = ret;
1600 return 0;
1603 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1604 GIOCondition condition, void *opaque)
1606 VncState *vs = opaque;
1608 assert(vs->magic == VNC_MAGIC);
1610 if (condition & (G_IO_HUP | G_IO_ERR)) {
1611 vnc_disconnect_start(vs);
1612 return TRUE;
1615 if (condition & G_IO_IN) {
1616 if (vnc_client_read(vs) < 0) {
1617 /* vs is free()ed here */
1618 return TRUE;
1621 if (condition & G_IO_OUT) {
1622 vnc_client_write(vs);
1625 if (vs->disconnecting) {
1626 if (vs->ioc_tag != 0) {
1627 g_source_remove(vs->ioc_tag);
1629 vs->ioc_tag = 0;
1631 return TRUE;
1636 * Scale factor to apply to vs->throttle_output_offset when checking for
1637 * hard limit. Worst case normal usage could be x2, if we have a complete
1638 * incremental update and complete forced update in the output buffer.
1639 * So x3 should be good enough, but we pick x5 to be conservative and thus
1640 * (hopefully) never trigger incorrectly.
1642 #define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1644 void vnc_write(VncState *vs, const void *data, size_t len)
1646 assert(vs->magic == VNC_MAGIC);
1647 if (vs->disconnecting) {
1648 return;
1650 /* Protection against malicious client/guest to prevent our output
1651 * buffer growing without bound if client stops reading data. This
1652 * should rarely trigger, because we have earlier throttling code
1653 * which stops issuing framebuffer updates and drops audio data
1654 * if the throttle_output_offset value is exceeded. So we only reach
1655 * this higher level if a huge number of pseudo-encodings get
1656 * triggered while data can't be sent on the socket.
1658 * NB throttle_output_offset can be zero during early protocol
1659 * handshake, or from the job thread's VncState clone
1661 if (vs->throttle_output_offset != 0 &&
1662 (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
1663 vs->throttle_output_offset) {
1664 trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
1665 vs->throttle_output_offset);
1666 vnc_disconnect_start(vs);
1667 return;
1669 buffer_reserve(&vs->output, len);
1671 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1672 if (vs->ioc_tag) {
1673 g_source_remove(vs->ioc_tag);
1675 vs->ioc_tag = qio_channel_add_watch(
1676 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT,
1677 vnc_client_io, vs, NULL);
1680 buffer_append(&vs->output, data, len);
1683 void vnc_write_s32(VncState *vs, int32_t value)
1685 vnc_write_u32(vs, *(uint32_t *)&value);
1688 void vnc_write_u32(VncState *vs, uint32_t value)
1690 uint8_t buf[4];
1692 buf[0] = (value >> 24) & 0xFF;
1693 buf[1] = (value >> 16) & 0xFF;
1694 buf[2] = (value >> 8) & 0xFF;
1695 buf[3] = value & 0xFF;
1697 vnc_write(vs, buf, 4);
1700 void vnc_write_u16(VncState *vs, uint16_t value)
1702 uint8_t buf[2];
1704 buf[0] = (value >> 8) & 0xFF;
1705 buf[1] = value & 0xFF;
1707 vnc_write(vs, buf, 2);
1710 void vnc_write_u8(VncState *vs, uint8_t value)
1712 vnc_write(vs, (char *)&value, 1);
1715 void vnc_flush(VncState *vs)
1717 vnc_lock_output(vs);
1718 if (vs->ioc != NULL && vs->output.offset) {
1719 vnc_client_write_locked(vs);
1721 if (vs->disconnecting) {
1722 if (vs->ioc_tag != 0) {
1723 g_source_remove(vs->ioc_tag);
1725 vs->ioc_tag = 0;
1727 vnc_unlock_output(vs);
1730 static uint8_t read_u8(uint8_t *data, size_t offset)
1732 return data[offset];
1735 static uint16_t read_u16(uint8_t *data, size_t offset)
1737 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1740 static int32_t read_s32(uint8_t *data, size_t offset)
1742 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1743 (data[offset + 2] << 8) | data[offset + 3]);
1746 uint32_t read_u32(uint8_t *data, size_t offset)
1748 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1749 (data[offset + 2] << 8) | data[offset + 3]);
1752 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1756 static void check_pointer_type_change(Notifier *notifier, void *data)
1758 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1759 int absolute = qemu_input_is_absolute();
1761 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1762 vnc_lock_output(vs);
1763 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1764 vnc_write_u8(vs, 0);
1765 vnc_write_u16(vs, 1);
1766 vnc_framebuffer_update(vs, absolute, 0,
1767 pixman_image_get_width(vs->vd->server),
1768 pixman_image_get_height(vs->vd->server),
1769 VNC_ENCODING_POINTER_TYPE_CHANGE);
1770 vnc_unlock_output(vs);
1771 vnc_flush(vs);
1773 vs->absolute = absolute;
1776 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1778 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1779 [INPUT_BUTTON_LEFT] = 0x01,
1780 [INPUT_BUTTON_MIDDLE] = 0x02,
1781 [INPUT_BUTTON_RIGHT] = 0x04,
1782 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1783 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1785 QemuConsole *con = vs->vd->dcl.con;
1786 int width = pixman_image_get_width(vs->vd->server);
1787 int height = pixman_image_get_height(vs->vd->server);
1789 if (vs->last_bmask != button_mask) {
1790 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1791 vs->last_bmask = button_mask;
1794 if (vs->absolute) {
1795 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1796 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1797 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1798 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1799 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1800 } else {
1801 if (vs->last_x != -1) {
1802 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1803 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1805 vs->last_x = x;
1806 vs->last_y = y;
1808 qemu_input_event_sync();
1811 static void press_key(VncState *vs, QKeyCode qcode)
1813 qkbd_state_key_event(vs->vd->kbd, qcode, true);
1814 qkbd_state_key_event(vs->vd->kbd, qcode, false);
1817 static void vnc_led_state_change(VncState *vs)
1819 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1820 return;
1823 vnc_lock_output(vs);
1824 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1825 vnc_write_u8(vs, 0);
1826 vnc_write_u16(vs, 1);
1827 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1828 vnc_write_u8(vs, vs->vd->ledstate);
1829 vnc_unlock_output(vs);
1830 vnc_flush(vs);
1833 static void kbd_leds(void *opaque, int ledstate)
1835 VncDisplay *vd = opaque;
1836 VncState *client;
1838 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1839 (ledstate & QEMU_NUM_LOCK_LED),
1840 (ledstate & QEMU_SCROLL_LOCK_LED));
1842 if (ledstate == vd->ledstate) {
1843 return;
1846 vd->ledstate = ledstate;
1848 QTAILQ_FOREACH(client, &vd->clients, next) {
1849 vnc_led_state_change(client);
1853 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1855 QKeyCode qcode = qemu_input_key_number_to_qcode(keycode);
1857 /* QEMU console switch */
1858 switch (qcode) {
1859 case Q_KEY_CODE_1 ... Q_KEY_CODE_9: /* '1' to '9' keys */
1860 if (vs->vd->dcl.con == NULL && down &&
1861 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) &&
1862 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {
1863 /* Reset the modifiers sent to the current console */
1864 qkbd_state_lift_all_keys(vs->vd->kbd);
1865 console_select(qcode - Q_KEY_CODE_1);
1866 return;
1868 default:
1869 break;
1872 /* Turn off the lock state sync logic if the client support the led
1873 state extension.
1875 if (down && vs->vd->lock_key_sync &&
1876 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1877 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1878 /* If the numlock state needs to change then simulate an additional
1879 keypress before sending this one. This will happen if the user
1880 toggles numlock away from the VNC window.
1882 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1883 if (!qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1884 trace_vnc_key_sync_numlock(true);
1885 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1887 } else {
1888 if (qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1889 trace_vnc_key_sync_numlock(false);
1890 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1895 if (down && vs->vd->lock_key_sync &&
1896 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1897 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1898 /* If the capslock state needs to change then simulate an additional
1899 keypress before sending this one. This will happen if the user
1900 toggles capslock away from the VNC window.
1902 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1903 bool shift = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_SHIFT);
1904 bool capslock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CAPSLOCK);
1905 if (capslock) {
1906 if (uppercase == shift) {
1907 trace_vnc_key_sync_capslock(false);
1908 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1910 } else {
1911 if (uppercase != shift) {
1912 trace_vnc_key_sync_capslock(true);
1913 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1918 qkbd_state_key_event(vs->vd->kbd, qcode, down);
1919 if (!qemu_console_is_graphic(NULL)) {
1920 bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK);
1921 bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL);
1922 /* QEMU console emulation */
1923 if (down) {
1924 switch (keycode) {
1925 case 0x2a: /* Left Shift */
1926 case 0x36: /* Right Shift */
1927 case 0x1d: /* Left CTRL */
1928 case 0x9d: /* Right CTRL */
1929 case 0x38: /* Left ALT */
1930 case 0xb8: /* Right ALT */
1931 break;
1932 case 0xc8:
1933 kbd_put_keysym(QEMU_KEY_UP);
1934 break;
1935 case 0xd0:
1936 kbd_put_keysym(QEMU_KEY_DOWN);
1937 break;
1938 case 0xcb:
1939 kbd_put_keysym(QEMU_KEY_LEFT);
1940 break;
1941 case 0xcd:
1942 kbd_put_keysym(QEMU_KEY_RIGHT);
1943 break;
1944 case 0xd3:
1945 kbd_put_keysym(QEMU_KEY_DELETE);
1946 break;
1947 case 0xc7:
1948 kbd_put_keysym(QEMU_KEY_HOME);
1949 break;
1950 case 0xcf:
1951 kbd_put_keysym(QEMU_KEY_END);
1952 break;
1953 case 0xc9:
1954 kbd_put_keysym(QEMU_KEY_PAGEUP);
1955 break;
1956 case 0xd1:
1957 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1958 break;
1960 case 0x47:
1961 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1962 break;
1963 case 0x48:
1964 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1965 break;
1966 case 0x49:
1967 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1968 break;
1969 case 0x4b:
1970 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1971 break;
1972 case 0x4c:
1973 kbd_put_keysym('5');
1974 break;
1975 case 0x4d:
1976 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1977 break;
1978 case 0x4f:
1979 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1980 break;
1981 case 0x50:
1982 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1983 break;
1984 case 0x51:
1985 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1986 break;
1987 case 0x52:
1988 kbd_put_keysym('0');
1989 break;
1990 case 0x53:
1991 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1992 break;
1994 case 0xb5:
1995 kbd_put_keysym('/');
1996 break;
1997 case 0x37:
1998 kbd_put_keysym('*');
1999 break;
2000 case 0x4a:
2001 kbd_put_keysym('-');
2002 break;
2003 case 0x4e:
2004 kbd_put_keysym('+');
2005 break;
2006 case 0x9c:
2007 kbd_put_keysym('\n');
2008 break;
2010 default:
2011 if (control) {
2012 kbd_put_keysym(sym & 0x1f);
2013 } else {
2014 kbd_put_keysym(sym);
2016 break;
2022 static const char *code2name(int keycode)
2024 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
2027 static void key_event(VncState *vs, int down, uint32_t sym)
2029 int keycode;
2030 int lsym = sym;
2032 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2033 lsym = lsym - 'A' + 'a';
2036 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
2037 vs->vd->kbd, down) & SCANCODE_KEYMASK;
2038 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2039 do_key_event(vs, down, keycode, sym);
2042 static void ext_key_event(VncState *vs, int down,
2043 uint32_t sym, uint16_t keycode)
2045 /* if the user specifies a keyboard layout, always use it */
2046 if (keyboard_layout) {
2047 key_event(vs, down, sym);
2048 } else {
2049 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2050 do_key_event(vs, down, keycode, sym);
2054 static void framebuffer_update_request(VncState *vs, int incremental,
2055 int x, int y, int w, int h)
2057 if (incremental) {
2058 if (vs->update != VNC_STATE_UPDATE_FORCE) {
2059 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
2061 } else {
2062 vs->update = VNC_STATE_UPDATE_FORCE;
2063 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2064 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
2065 vnc_desktop_resize_ext(vs, 0);
2070 static void send_ext_key_event_ack(VncState *vs)
2072 vnc_lock_output(vs);
2073 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2074 vnc_write_u8(vs, 0);
2075 vnc_write_u16(vs, 1);
2076 vnc_framebuffer_update(vs, 0, 0,
2077 pixman_image_get_width(vs->vd->server),
2078 pixman_image_get_height(vs->vd->server),
2079 VNC_ENCODING_EXT_KEY_EVENT);
2080 vnc_unlock_output(vs);
2081 vnc_flush(vs);
2084 static void send_ext_audio_ack(VncState *vs)
2086 vnc_lock_output(vs);
2087 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2088 vnc_write_u8(vs, 0);
2089 vnc_write_u16(vs, 1);
2090 vnc_framebuffer_update(vs, 0, 0,
2091 pixman_image_get_width(vs->vd->server),
2092 pixman_image_get_height(vs->vd->server),
2093 VNC_ENCODING_AUDIO);
2094 vnc_unlock_output(vs);
2095 vnc_flush(vs);
2098 static void send_xvp_message(VncState *vs, int code)
2100 vnc_lock_output(vs);
2101 vnc_write_u8(vs, VNC_MSG_SERVER_XVP);
2102 vnc_write_u8(vs, 0); /* pad */
2103 vnc_write_u8(vs, 1); /* version */
2104 vnc_write_u8(vs, code);
2105 vnc_unlock_output(vs);
2106 vnc_flush(vs);
2109 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2111 int i;
2112 unsigned int enc = 0;
2114 vs->features = 0;
2115 vs->vnc_encoding = 0;
2116 vs->tight->compression = 9;
2117 vs->tight->quality = -1; /* Lossless by default */
2118 vs->absolute = -1;
2121 * Start from the end because the encodings are sent in order of preference.
2122 * This way the preferred encoding (first encoding defined in the array)
2123 * will be set at the end of the loop.
2125 for (i = n_encodings - 1; i >= 0; i--) {
2126 enc = encodings[i];
2127 switch (enc) {
2128 case VNC_ENCODING_RAW:
2129 vs->vnc_encoding = enc;
2130 break;
2131 case VNC_ENCODING_HEXTILE:
2132 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2133 vs->vnc_encoding = enc;
2134 break;
2135 case VNC_ENCODING_TIGHT:
2136 vs->features |= VNC_FEATURE_TIGHT_MASK;
2137 vs->vnc_encoding = enc;
2138 break;
2139 #ifdef CONFIG_VNC_PNG
2140 case VNC_ENCODING_TIGHT_PNG:
2141 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2142 vs->vnc_encoding = enc;
2143 break;
2144 #endif
2145 case VNC_ENCODING_ZLIB:
2147 * VNC_ENCODING_ZRLE compresses better than VNC_ENCODING_ZLIB.
2148 * So prioritize ZRLE, even if the client hints that it prefers
2149 * ZLIB.
2151 if ((vs->features & VNC_FEATURE_ZRLE_MASK) == 0) {
2152 vs->features |= VNC_FEATURE_ZLIB_MASK;
2153 vs->vnc_encoding = enc;
2155 break;
2156 case VNC_ENCODING_ZRLE:
2157 vs->features |= VNC_FEATURE_ZRLE_MASK;
2158 vs->vnc_encoding = enc;
2159 break;
2160 case VNC_ENCODING_ZYWRLE:
2161 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2162 vs->vnc_encoding = enc;
2163 break;
2164 case VNC_ENCODING_DESKTOPRESIZE:
2165 vs->features |= VNC_FEATURE_RESIZE_MASK;
2166 break;
2167 case VNC_ENCODING_DESKTOP_RESIZE_EXT:
2168 vs->features |= VNC_FEATURE_RESIZE_EXT_MASK;
2169 break;
2170 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2171 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2172 break;
2173 case VNC_ENCODING_RICH_CURSOR:
2174 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2175 break;
2176 case VNC_ENCODING_ALPHA_CURSOR:
2177 vs->features |= VNC_FEATURE_ALPHA_CURSOR_MASK;
2178 break;
2179 case VNC_ENCODING_EXT_KEY_EVENT:
2180 send_ext_key_event_ack(vs);
2181 break;
2182 case VNC_ENCODING_AUDIO:
2183 send_ext_audio_ack(vs);
2184 break;
2185 case VNC_ENCODING_WMVi:
2186 vs->features |= VNC_FEATURE_WMVI_MASK;
2187 break;
2188 case VNC_ENCODING_LED_STATE:
2189 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2190 break;
2191 case VNC_ENCODING_XVP:
2192 if (vs->vd->power_control) {
2193 vs->features |= VNC_FEATURE_XVP;
2194 send_xvp_message(vs, VNC_XVP_CODE_INIT);
2196 break;
2197 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2198 vs->tight->compression = (enc & 0x0F);
2199 break;
2200 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2201 if (vs->vd->lossy) {
2202 vs->tight->quality = (enc & 0x0F);
2204 break;
2205 default:
2206 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2207 break;
2210 vnc_desktop_resize(vs);
2211 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2212 vnc_led_state_change(vs);
2213 vnc_cursor_define(vs);
2216 static void set_pixel_conversion(VncState *vs)
2218 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2220 if (fmt == VNC_SERVER_FB_FORMAT) {
2221 vs->write_pixels = vnc_write_pixels_copy;
2222 vnc_hextile_set_pixel_conversion(vs, 0);
2223 } else {
2224 vs->write_pixels = vnc_write_pixels_generic;
2225 vnc_hextile_set_pixel_conversion(vs, 1);
2229 static void send_color_map(VncState *vs)
2231 int i;
2233 vnc_lock_output(vs);
2234 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2235 vnc_write_u8(vs, 0); /* padding */
2236 vnc_write_u16(vs, 0); /* first color */
2237 vnc_write_u16(vs, 256); /* # of colors */
2239 for (i = 0; i < 256; i++) {
2240 PixelFormat *pf = &vs->client_pf;
2242 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2243 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2244 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2246 vnc_unlock_output(vs);
2249 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2250 int big_endian_flag, int true_color_flag,
2251 int red_max, int green_max, int blue_max,
2252 int red_shift, int green_shift, int blue_shift)
2254 if (!true_color_flag) {
2255 /* Expose a reasonable default 256 color map */
2256 bits_per_pixel = 8;
2257 red_max = 7;
2258 green_max = 7;
2259 blue_max = 3;
2260 red_shift = 0;
2261 green_shift = 3;
2262 blue_shift = 6;
2265 switch (bits_per_pixel) {
2266 case 8:
2267 case 16:
2268 case 32:
2269 break;
2270 default:
2271 vnc_client_error(vs);
2272 return;
2275 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2276 vs->client_pf.rbits = ctpopl(red_max);
2277 vs->client_pf.rshift = red_shift;
2278 vs->client_pf.rmask = red_max << red_shift;
2279 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2280 vs->client_pf.gbits = ctpopl(green_max);
2281 vs->client_pf.gshift = green_shift;
2282 vs->client_pf.gmask = green_max << green_shift;
2283 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2284 vs->client_pf.bbits = ctpopl(blue_max);
2285 vs->client_pf.bshift = blue_shift;
2286 vs->client_pf.bmask = blue_max << blue_shift;
2287 vs->client_pf.bits_per_pixel = bits_per_pixel;
2288 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2289 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2290 vs->client_be = big_endian_flag;
2292 if (!true_color_flag) {
2293 send_color_map(vs);
2296 set_pixel_conversion(vs);
2298 graphic_hw_invalidate(vs->vd->dcl.con);
2299 graphic_hw_update(vs->vd->dcl.con);
2302 static void pixel_format_message (VncState *vs) {
2303 char pad[3] = { 0, 0, 0 };
2305 vs->client_pf = qemu_default_pixelformat(32);
2307 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2308 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2310 #ifdef HOST_WORDS_BIGENDIAN
2311 vnc_write_u8(vs, 1); /* big-endian-flag */
2312 #else
2313 vnc_write_u8(vs, 0); /* big-endian-flag */
2314 #endif
2315 vnc_write_u8(vs, 1); /* true-color-flag */
2316 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2317 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2318 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2319 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2320 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2321 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2322 vnc_write(vs, pad, 3); /* padding */
2324 vnc_hextile_set_pixel_conversion(vs, 0);
2325 vs->write_pixels = vnc_write_pixels_copy;
2328 static void vnc_colordepth(VncState *vs)
2330 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2331 /* Sending a WMVi message to notify the client*/
2332 vnc_lock_output(vs);
2333 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2334 vnc_write_u8(vs, 0);
2335 vnc_write_u16(vs, 1); /* number of rects */
2336 vnc_framebuffer_update(vs, 0, 0,
2337 vs->client_width,
2338 vs->client_height,
2339 VNC_ENCODING_WMVi);
2340 pixel_format_message(vs);
2341 vnc_unlock_output(vs);
2342 vnc_flush(vs);
2343 } else {
2344 set_pixel_conversion(vs);
2348 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2350 int i;
2351 uint16_t limit;
2352 uint32_t freq;
2353 VncDisplay *vd = vs->vd;
2355 if (data[0] > 3) {
2356 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2359 switch (data[0]) {
2360 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2361 if (len == 1)
2362 return 20;
2364 set_pixel_format(vs, read_u8(data, 4),
2365 read_u8(data, 6), read_u8(data, 7),
2366 read_u16(data, 8), read_u16(data, 10),
2367 read_u16(data, 12), read_u8(data, 14),
2368 read_u8(data, 15), read_u8(data, 16));
2369 break;
2370 case VNC_MSG_CLIENT_SET_ENCODINGS:
2371 if (len == 1)
2372 return 4;
2374 if (len == 4) {
2375 limit = read_u16(data, 2);
2376 if (limit > 0)
2377 return 4 + (limit * 4);
2378 } else
2379 limit = read_u16(data, 2);
2381 for (i = 0; i < limit; i++) {
2382 int32_t val = read_s32(data, 4 + (i * 4));
2383 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2386 set_encodings(vs, (int32_t *)(data + 4), limit);
2387 break;
2388 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2389 if (len == 1)
2390 return 10;
2392 framebuffer_update_request(vs,
2393 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2394 read_u16(data, 6), read_u16(data, 8));
2395 break;
2396 case VNC_MSG_CLIENT_KEY_EVENT:
2397 if (len == 1)
2398 return 8;
2400 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2401 break;
2402 case VNC_MSG_CLIENT_POINTER_EVENT:
2403 if (len == 1)
2404 return 6;
2406 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2407 break;
2408 case VNC_MSG_CLIENT_CUT_TEXT:
2409 if (len == 1) {
2410 return 8;
2412 if (len == 8) {
2413 uint32_t dlen = read_u32(data, 4);
2414 if (dlen > (1 << 20)) {
2415 error_report("vnc: client_cut_text msg payload has %u bytes"
2416 " which exceeds our limit of 1MB.", dlen);
2417 vnc_client_error(vs);
2418 break;
2420 if (dlen > 0) {
2421 return 8 + dlen;
2425 client_cut_text(vs, read_u32(data, 4), data + 8);
2426 break;
2427 case VNC_MSG_CLIENT_XVP:
2428 if (!(vs->features & VNC_FEATURE_XVP)) {
2429 error_report("vnc: xvp client message while disabled");
2430 vnc_client_error(vs);
2431 break;
2433 if (len == 1) {
2434 return 4;
2436 if (len == 4) {
2437 uint8_t version = read_u8(data, 2);
2438 uint8_t action = read_u8(data, 3);
2440 if (version != 1) {
2441 error_report("vnc: xvp client message version %d != 1",
2442 version);
2443 vnc_client_error(vs);
2444 break;
2447 switch (action) {
2448 case VNC_XVP_ACTION_SHUTDOWN:
2449 qemu_system_powerdown_request();
2450 break;
2451 case VNC_XVP_ACTION_REBOOT:
2452 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2453 break;
2454 case VNC_XVP_ACTION_RESET:
2455 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
2456 break;
2457 default:
2458 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2459 break;
2462 break;
2463 case VNC_MSG_CLIENT_QEMU:
2464 if (len == 1)
2465 return 2;
2467 switch (read_u8(data, 1)) {
2468 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2469 if (len == 2)
2470 return 12;
2472 ext_key_event(vs, read_u16(data, 2),
2473 read_u32(data, 4), read_u32(data, 8));
2474 break;
2475 case VNC_MSG_CLIENT_QEMU_AUDIO:
2476 if (len == 2)
2477 return 4;
2479 switch (read_u16 (data, 2)) {
2480 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2481 trace_vnc_msg_client_audio_enable(vs, vs->ioc);
2482 audio_add(vs);
2483 break;
2484 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2485 trace_vnc_msg_client_audio_disable(vs, vs->ioc);
2486 audio_del(vs);
2487 break;
2488 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2489 if (len == 4)
2490 return 10;
2491 switch (read_u8(data, 4)) {
2492 case 0: vs->as.fmt = AUDIO_FORMAT_U8; break;
2493 case 1: vs->as.fmt = AUDIO_FORMAT_S8; break;
2494 case 2: vs->as.fmt = AUDIO_FORMAT_U16; break;
2495 case 3: vs->as.fmt = AUDIO_FORMAT_S16; break;
2496 case 4: vs->as.fmt = AUDIO_FORMAT_U32; break;
2497 case 5: vs->as.fmt = AUDIO_FORMAT_S32; break;
2498 default:
2499 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2500 vnc_client_error(vs);
2501 break;
2503 vs->as.nchannels = read_u8(data, 5);
2504 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2505 VNC_DEBUG("Invalid audio channel count %d\n",
2506 read_u8(data, 5));
2507 vnc_client_error(vs);
2508 break;
2510 freq = read_u32(data, 6);
2511 /* No official limit for protocol, but 48khz is a sensible
2512 * upper bound for trustworthy clients, and this limit
2513 * protects calculations involving 'vs->as.freq' later.
2515 if (freq > 48000) {
2516 VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
2517 vnc_client_error(vs);
2518 break;
2520 vs->as.freq = freq;
2521 trace_vnc_msg_client_audio_format(
2522 vs, vs->ioc, vs->as.fmt, vs->as.nchannels, vs->as.freq);
2523 break;
2524 default:
2525 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2526 vnc_client_error(vs);
2527 break;
2529 break;
2531 default:
2532 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2533 vnc_client_error(vs);
2534 break;
2536 break;
2537 case VNC_MSG_CLIENT_SET_DESKTOP_SIZE:
2539 size_t size;
2540 uint8_t screens;
2541 int w, h;
2543 if (len < 8) {
2544 return 8;
2547 screens = read_u8(data, 6);
2548 size = 8 + screens * 16;
2549 if (len < size) {
2550 return size;
2552 w = read_u16(data, 2);
2553 h = read_u16(data, 4);
2555 trace_vnc_msg_client_set_desktop_size(vs, vs->ioc, w, h, screens);
2556 if (dpy_ui_info_supported(vs->vd->dcl.con)) {
2557 QemuUIInfo info;
2558 memset(&info, 0, sizeof(info));
2559 info.width = w;
2560 info.height = h;
2561 dpy_set_ui_info(vs->vd->dcl.con, &info);
2562 vnc_desktop_resize_ext(vs, 4 /* Request forwarded */);
2563 } else {
2564 vnc_desktop_resize_ext(vs, 3 /* Invalid screen layout */);
2567 break;
2569 default:
2570 VNC_DEBUG("Msg: %d\n", data[0]);
2571 vnc_client_error(vs);
2572 break;
2575 vnc_update_throttle_offset(vs);
2576 vnc_read_when(vs, protocol_client_msg, 1);
2577 return 0;
2580 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2582 char buf[1024];
2583 VncShareMode mode;
2584 int size;
2586 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2587 switch (vs->vd->share_policy) {
2588 case VNC_SHARE_POLICY_IGNORE:
2590 * Ignore the shared flag. Nothing to do here.
2592 * Doesn't conform to the rfb spec but is traditional qemu
2593 * behavior, thus left here as option for compatibility
2594 * reasons.
2596 break;
2597 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2599 * Policy: Allow clients ask for exclusive access.
2601 * Implementation: When a client asks for exclusive access,
2602 * disconnect all others. Shared connects are allowed as long
2603 * as no exclusive connection exists.
2605 * This is how the rfb spec suggests to handle the shared flag.
2607 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2608 VncState *client;
2609 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2610 if (vs == client) {
2611 continue;
2613 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2614 client->share_mode != VNC_SHARE_MODE_SHARED) {
2615 continue;
2617 vnc_disconnect_start(client);
2620 if (mode == VNC_SHARE_MODE_SHARED) {
2621 if (vs->vd->num_exclusive > 0) {
2622 vnc_disconnect_start(vs);
2623 return 0;
2626 break;
2627 case VNC_SHARE_POLICY_FORCE_SHARED:
2629 * Policy: Shared connects only.
2630 * Implementation: Disallow clients asking for exclusive access.
2632 * Useful for shared desktop sessions where you don't want
2633 * someone forgetting to say -shared when running the vnc
2634 * client disconnect everybody else.
2636 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2637 vnc_disconnect_start(vs);
2638 return 0;
2640 break;
2642 vnc_set_share_mode(vs, mode);
2644 if (vs->vd->num_shared > vs->vd->connections_limit) {
2645 vnc_disconnect_start(vs);
2646 return 0;
2649 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
2650 pixman_image_get_width(vs->vd->server) >= 0);
2651 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
2652 pixman_image_get_height(vs->vd->server) >= 0);
2653 vs->client_width = pixman_image_get_width(vs->vd->server);
2654 vs->client_height = pixman_image_get_height(vs->vd->server);
2655 vnc_write_u16(vs, vs->client_width);
2656 vnc_write_u16(vs, vs->client_height);
2658 pixel_format_message(vs);
2660 if (qemu_name) {
2661 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2662 if (size > sizeof(buf)) {
2663 size = sizeof(buf);
2665 } else {
2666 size = snprintf(buf, sizeof(buf), "QEMU");
2669 vnc_write_u32(vs, size);
2670 vnc_write(vs, buf, size);
2671 vnc_flush(vs);
2673 vnc_client_cache_auth(vs);
2674 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2676 vnc_read_when(vs, protocol_client_msg, 1);
2678 return 0;
2681 void start_client_init(VncState *vs)
2683 vnc_read_when(vs, protocol_client_init, 1);
2686 static void authentication_failed(VncState *vs)
2688 vnc_write_u32(vs, 1); /* Reject auth */
2689 if (vs->minor >= 8) {
2690 static const char err[] = "Authentication failed";
2691 vnc_write_u32(vs, sizeof(err));
2692 vnc_write(vs, err, sizeof(err));
2694 vnc_flush(vs);
2695 vnc_client_error(vs);
2698 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2700 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2701 size_t i, pwlen;
2702 unsigned char key[8];
2703 time_t now = time(NULL);
2704 QCryptoCipher *cipher = NULL;
2705 Error *err = NULL;
2707 if (!vs->vd->password) {
2708 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2709 goto reject;
2711 if (vs->vd->expires < now) {
2712 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2713 goto reject;
2716 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2718 /* Calculate the expected challenge response */
2719 pwlen = strlen(vs->vd->password);
2720 for (i=0; i<sizeof(key); i++)
2721 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2723 cipher = qcrypto_cipher_new(
2724 QCRYPTO_CIPHER_ALG_DES_RFB,
2725 QCRYPTO_CIPHER_MODE_ECB,
2726 key, G_N_ELEMENTS(key),
2727 &err);
2728 if (!cipher) {
2729 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2730 error_get_pretty(err));
2731 error_free(err);
2732 goto reject;
2735 if (qcrypto_cipher_encrypt(cipher,
2736 vs->challenge,
2737 response,
2738 VNC_AUTH_CHALLENGE_SIZE,
2739 &err) < 0) {
2740 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2741 error_get_pretty(err));
2742 error_free(err);
2743 goto reject;
2746 /* Compare expected vs actual challenge response */
2747 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2748 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2749 goto reject;
2750 } else {
2751 trace_vnc_auth_pass(vs, vs->auth);
2752 vnc_write_u32(vs, 0); /* Accept auth */
2753 vnc_flush(vs);
2755 start_client_init(vs);
2758 qcrypto_cipher_free(cipher);
2759 return 0;
2761 reject:
2762 authentication_failed(vs);
2763 qcrypto_cipher_free(cipher);
2764 return 0;
2767 void start_auth_vnc(VncState *vs)
2769 Error *err = NULL;
2771 if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) {
2772 trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
2773 error_get_pretty(err));
2774 error_free(err);
2775 authentication_failed(vs);
2776 return;
2779 /* Send client a 'random' challenge */
2780 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2781 vnc_flush(vs);
2783 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2787 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2789 /* We only advertise 1 auth scheme at a time, so client
2790 * must pick the one we sent. Verify this */
2791 if (data[0] != vs->auth) { /* Reject auth */
2792 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2793 authentication_failed(vs);
2794 } else { /* Accept requested auth */
2795 trace_vnc_auth_start(vs, vs->auth);
2796 switch (vs->auth) {
2797 case VNC_AUTH_NONE:
2798 if (vs->minor >= 8) {
2799 vnc_write_u32(vs, 0); /* Accept auth completion */
2800 vnc_flush(vs);
2802 trace_vnc_auth_pass(vs, vs->auth);
2803 start_client_init(vs);
2804 break;
2806 case VNC_AUTH_VNC:
2807 start_auth_vnc(vs);
2808 break;
2810 case VNC_AUTH_VENCRYPT:
2811 start_auth_vencrypt(vs);
2812 break;
2814 #ifdef CONFIG_VNC_SASL
2815 case VNC_AUTH_SASL:
2816 start_auth_sasl(vs);
2817 break;
2818 #endif /* CONFIG_VNC_SASL */
2820 default: /* Should not be possible, but just in case */
2821 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2822 authentication_failed(vs);
2825 return 0;
2828 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2830 char local[13];
2832 memcpy(local, version, 12);
2833 local[12] = 0;
2835 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2836 VNC_DEBUG("Malformed protocol version %s\n", local);
2837 vnc_client_error(vs);
2838 return 0;
2840 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2841 if (vs->major != 3 ||
2842 (vs->minor != 3 &&
2843 vs->minor != 4 &&
2844 vs->minor != 5 &&
2845 vs->minor != 7 &&
2846 vs->minor != 8)) {
2847 VNC_DEBUG("Unsupported client version\n");
2848 vnc_write_u32(vs, VNC_AUTH_INVALID);
2849 vnc_flush(vs);
2850 vnc_client_error(vs);
2851 return 0;
2853 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2854 * as equivalent to v3.3 by servers
2856 if (vs->minor == 4 || vs->minor == 5)
2857 vs->minor = 3;
2859 if (vs->minor == 3) {
2860 trace_vnc_auth_start(vs, vs->auth);
2861 if (vs->auth == VNC_AUTH_NONE) {
2862 vnc_write_u32(vs, vs->auth);
2863 vnc_flush(vs);
2864 trace_vnc_auth_pass(vs, vs->auth);
2865 start_client_init(vs);
2866 } else if (vs->auth == VNC_AUTH_VNC) {
2867 VNC_DEBUG("Tell client VNC auth\n");
2868 vnc_write_u32(vs, vs->auth);
2869 vnc_flush(vs);
2870 start_auth_vnc(vs);
2871 } else {
2872 trace_vnc_auth_fail(vs, vs->auth,
2873 "Unsupported auth method for v3.3", "");
2874 vnc_write_u32(vs, VNC_AUTH_INVALID);
2875 vnc_flush(vs);
2876 vnc_client_error(vs);
2878 } else {
2879 vnc_write_u8(vs, 1); /* num auth */
2880 vnc_write_u8(vs, vs->auth);
2881 vnc_read_when(vs, protocol_client_auth, 1);
2882 vnc_flush(vs);
2885 return 0;
2888 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2890 struct VncSurface *vs = &vd->guest;
2892 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2895 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2897 int i, j;
2899 w = (x + w) / VNC_STAT_RECT;
2900 h = (y + h) / VNC_STAT_RECT;
2901 x /= VNC_STAT_RECT;
2902 y /= VNC_STAT_RECT;
2904 for (j = y; j <= h; j++) {
2905 for (i = x; i <= w; i++) {
2906 vs->lossy_rect[j][i] = 1;
2911 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2913 VncState *vs;
2914 int sty = y / VNC_STAT_RECT;
2915 int stx = x / VNC_STAT_RECT;
2916 int has_dirty = 0;
2918 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2919 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2921 QTAILQ_FOREACH(vs, &vd->clients, next) {
2922 int j;
2924 /* kernel send buffers are full -> refresh later */
2925 if (vs->output.offset) {
2926 continue;
2929 if (!vs->lossy_rect[sty][stx]) {
2930 continue;
2933 vs->lossy_rect[sty][stx] = 0;
2934 for (j = 0; j < VNC_STAT_RECT; ++j) {
2935 bitmap_set(vs->dirty[y + j],
2936 x / VNC_DIRTY_PIXELS_PER_BIT,
2937 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2939 has_dirty++;
2942 return has_dirty;
2945 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2947 int width = MIN(pixman_image_get_width(vd->guest.fb),
2948 pixman_image_get_width(vd->server));
2949 int height = MIN(pixman_image_get_height(vd->guest.fb),
2950 pixman_image_get_height(vd->server));
2951 int x, y;
2952 struct timeval res;
2953 int has_dirty = 0;
2955 for (y = 0; y < height; y += VNC_STAT_RECT) {
2956 for (x = 0; x < width; x += VNC_STAT_RECT) {
2957 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2959 rect->updated = false;
2963 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2965 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2966 return has_dirty;
2968 vd->guest.last_freq_check = *tv;
2970 for (y = 0; y < height; y += VNC_STAT_RECT) {
2971 for (x = 0; x < width; x += VNC_STAT_RECT) {
2972 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2973 int count = ARRAY_SIZE(rect->times);
2974 struct timeval min, max;
2976 if (!timerisset(&rect->times[count - 1])) {
2977 continue ;
2980 max = rect->times[(rect->idx + count - 1) % count];
2981 qemu_timersub(tv, &max, &res);
2983 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2984 rect->freq = 0;
2985 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2986 memset(rect->times, 0, sizeof (rect->times));
2987 continue ;
2990 min = rect->times[rect->idx];
2991 max = rect->times[(rect->idx + count - 1) % count];
2992 qemu_timersub(&max, &min, &res);
2994 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2995 rect->freq /= count;
2996 rect->freq = 1. / rect->freq;
2999 return has_dirty;
3002 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
3004 int i, j;
3005 double total = 0;
3006 int num = 0;
3008 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
3009 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
3011 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
3012 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
3013 total += vnc_stat_rect(vs->vd, i, j)->freq;
3014 num++;
3018 if (num) {
3019 return total / num;
3020 } else {
3021 return 0;
3025 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
3027 VncRectStat *rect;
3029 rect = vnc_stat_rect(vd, x, y);
3030 if (rect->updated) {
3031 return ;
3033 rect->times[rect->idx] = *tv;
3034 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
3035 rect->updated = true;
3038 static int vnc_refresh_server_surface(VncDisplay *vd)
3040 int width = MIN(pixman_image_get_width(vd->guest.fb),
3041 pixman_image_get_width(vd->server));
3042 int height = MIN(pixman_image_get_height(vd->guest.fb),
3043 pixman_image_get_height(vd->server));
3044 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
3045 uint8_t *guest_row0 = NULL, *server_row0;
3046 VncState *vs;
3047 int has_dirty = 0;
3048 pixman_image_t *tmpbuf = NULL;
3050 struct timeval tv = { 0, 0 };
3052 if (!vd->non_adaptive) {
3053 gettimeofday(&tv, NULL);
3054 has_dirty = vnc_update_stats(vd, &tv);
3058 * Walk through the guest dirty map.
3059 * Check and copy modified bits from guest to server surface.
3060 * Update server dirty map.
3062 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
3063 server_stride = guest_stride = guest_ll =
3064 pixman_image_get_stride(vd->server);
3065 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
3066 server_stride);
3067 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3068 int width = pixman_image_get_width(vd->server);
3069 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
3070 } else {
3071 int guest_bpp =
3072 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
3073 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
3074 guest_stride = pixman_image_get_stride(vd->guest.fb);
3075 guest_ll = pixman_image_get_width(vd->guest.fb)
3076 * DIV_ROUND_UP(guest_bpp, 8);
3078 line_bytes = MIN(server_stride, guest_ll);
3080 for (;;) {
3081 int x;
3082 uint8_t *guest_ptr, *server_ptr;
3083 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3084 height * VNC_DIRTY_BPL(&vd->guest),
3085 y * VNC_DIRTY_BPL(&vd->guest));
3086 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3087 /* no more dirty bits */
3088 break;
3090 y = offset / VNC_DIRTY_BPL(&vd->guest);
3091 x = offset % VNC_DIRTY_BPL(&vd->guest);
3093 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
3095 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3096 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
3097 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
3098 } else {
3099 guest_ptr = guest_row0 + y * guest_stride;
3101 guest_ptr += x * cmp_bytes;
3103 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
3104 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
3105 int _cmp_bytes = cmp_bytes;
3106 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
3107 continue;
3109 if ((x + 1) * cmp_bytes > line_bytes) {
3110 _cmp_bytes = line_bytes - x * cmp_bytes;
3112 assert(_cmp_bytes >= 0);
3113 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
3114 continue;
3116 memcpy(server_ptr, guest_ptr, _cmp_bytes);
3117 if (!vd->non_adaptive) {
3118 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
3119 y, &tv);
3121 QTAILQ_FOREACH(vs, &vd->clients, next) {
3122 set_bit(x, vs->dirty[y]);
3124 has_dirty++;
3127 y++;
3129 qemu_pixman_image_unref(tmpbuf);
3130 return has_dirty;
3133 static void vnc_refresh(DisplayChangeListener *dcl)
3135 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
3136 VncState *vs, *vn;
3137 int has_dirty, rects = 0;
3139 if (QTAILQ_EMPTY(&vd->clients)) {
3140 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
3141 return;
3144 graphic_hw_update(vd->dcl.con);
3146 if (vnc_trylock_display(vd)) {
3147 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3148 return;
3151 has_dirty = vnc_refresh_server_surface(vd);
3152 vnc_unlock_display(vd);
3154 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
3155 rects += vnc_update_client(vs, has_dirty);
3156 /* vs might be free()ed here */
3159 if (has_dirty && rects) {
3160 vd->dcl.update_interval /= 2;
3161 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3162 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3164 } else {
3165 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3166 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3167 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3172 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
3173 bool skipauth, bool websocket)
3175 VncState *vs = g_new0(VncState, 1);
3176 bool first_client = QTAILQ_EMPTY(&vd->clients);
3177 int i;
3179 trace_vnc_client_connect(vs, sioc);
3180 vs->zrle = g_new0(VncZrle, 1);
3181 vs->tight = g_new0(VncTight, 1);
3182 vs->magic = VNC_MAGIC;
3183 vs->sioc = sioc;
3184 object_ref(OBJECT(vs->sioc));
3185 vs->ioc = QIO_CHANNEL(sioc);
3186 object_ref(OBJECT(vs->ioc));
3187 vs->vd = vd;
3189 buffer_init(&vs->input, "vnc-input/%p", sioc);
3190 buffer_init(&vs->output, "vnc-output/%p", sioc);
3191 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
3193 buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc);
3194 buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc);
3195 buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc);
3196 #ifdef CONFIG_VNC_JPEG
3197 buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc);
3198 #endif
3199 #ifdef CONFIG_VNC_PNG
3200 buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc);
3201 #endif
3202 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3203 buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc);
3204 buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc);
3205 buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc);
3207 if (skipauth) {
3208 vs->auth = VNC_AUTH_NONE;
3209 vs->subauth = VNC_AUTH_INVALID;
3210 } else {
3211 if (websocket) {
3212 vs->auth = vd->ws_auth;
3213 vs->subauth = VNC_AUTH_INVALID;
3214 } else {
3215 vs->auth = vd->auth;
3216 vs->subauth = vd->subauth;
3219 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3220 sioc, websocket, vs->auth, vs->subauth);
3222 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3223 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3224 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3227 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3228 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3229 qio_channel_set_blocking(vs->ioc, false, NULL);
3230 if (vs->ioc_tag) {
3231 g_source_remove(vs->ioc_tag);
3233 if (websocket) {
3234 vs->websocket = 1;
3235 if (vd->tlscreds) {
3236 vs->ioc_tag = qio_channel_add_watch(
3237 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3238 vncws_tls_handshake_io, vs, NULL);
3239 } else {
3240 vs->ioc_tag = qio_channel_add_watch(
3241 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3242 vncws_handshake_io, vs, NULL);
3244 } else {
3245 vs->ioc_tag = qio_channel_add_watch(
3246 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3247 vnc_client_io, vs, NULL);
3250 vnc_client_cache_addr(vs);
3251 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3252 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3254 vs->last_x = -1;
3255 vs->last_y = -1;
3257 vs->as.freq = 44100;
3258 vs->as.nchannels = 2;
3259 vs->as.fmt = AUDIO_FORMAT_S16;
3260 vs->as.endianness = 0;
3262 qemu_mutex_init(&vs->output_mutex);
3263 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3265 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3266 if (first_client) {
3267 vnc_update_server_surface(vd);
3270 graphic_hw_update(vd->dcl.con);
3272 if (!vs->websocket) {
3273 vnc_start_protocol(vs);
3276 if (vd->num_connecting > vd->connections_limit) {
3277 QTAILQ_FOREACH(vs, &vd->clients, next) {
3278 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3279 vnc_disconnect_start(vs);
3280 return;
3286 void vnc_start_protocol(VncState *vs)
3288 vnc_write(vs, "RFB 003.008\n", 12);
3289 vnc_flush(vs);
3290 vnc_read_when(vs, protocol_version, 12);
3292 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3293 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3296 static void vnc_listen_io(QIONetListener *listener,
3297 QIOChannelSocket *cioc,
3298 void *opaque)
3300 VncDisplay *vd = opaque;
3301 bool isWebsock = listener == vd->wslistener;
3303 qio_channel_set_name(QIO_CHANNEL(cioc),
3304 isWebsock ? "vnc-ws-server" : "vnc-server");
3305 qio_channel_set_delay(QIO_CHANNEL(cioc), false);
3306 vnc_connect(vd, cioc, false, isWebsock);
3309 static const DisplayChangeListenerOps dcl_ops = {
3310 .dpy_name = "vnc",
3311 .dpy_refresh = vnc_refresh,
3312 .dpy_gfx_update = vnc_dpy_update,
3313 .dpy_gfx_switch = vnc_dpy_switch,
3314 .dpy_gfx_check_format = qemu_pixman_check_format,
3315 .dpy_mouse_set = vnc_mouse_set,
3316 .dpy_cursor_define = vnc_dpy_cursor_define,
3319 void vnc_display_init(const char *id, Error **errp)
3321 VncDisplay *vd;
3323 if (vnc_display_find(id) != NULL) {
3324 return;
3326 vd = g_malloc0(sizeof(*vd));
3328 vd->id = strdup(id);
3329 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3331 QTAILQ_INIT(&vd->clients);
3332 vd->expires = TIME_MAX;
3334 if (keyboard_layout) {
3335 trace_vnc_key_map_init(keyboard_layout);
3336 vd->kbd_layout = init_keyboard_layout(name2keysym,
3337 keyboard_layout, errp);
3338 } else {
3339 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
3342 if (!vd->kbd_layout) {
3343 return;
3346 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3347 vd->connections_limit = 32;
3349 qemu_mutex_init(&vd->mutex);
3350 vnc_start_worker_thread();
3352 vd->dcl.ops = &dcl_ops;
3353 register_displaychangelistener(&vd->dcl);
3354 vd->kbd = qkbd_state_init(vd->dcl.con);
3358 static void vnc_display_close(VncDisplay *vd)
3360 if (!vd) {
3361 return;
3363 vd->is_unix = false;
3365 if (vd->listener) {
3366 qio_net_listener_disconnect(vd->listener);
3367 object_unref(OBJECT(vd->listener));
3369 vd->listener = NULL;
3371 if (vd->wslistener) {
3372 qio_net_listener_disconnect(vd->wslistener);
3373 object_unref(OBJECT(vd->wslistener));
3375 vd->wslistener = NULL;
3377 vd->auth = VNC_AUTH_INVALID;
3378 vd->subauth = VNC_AUTH_INVALID;
3379 if (vd->tlscreds) {
3380 object_unref(OBJECT(vd->tlscreds));
3381 vd->tlscreds = NULL;
3383 if (vd->tlsauthz) {
3384 object_unparent(OBJECT(vd->tlsauthz));
3385 vd->tlsauthz = NULL;
3387 g_free(vd->tlsauthzid);
3388 vd->tlsauthzid = NULL;
3389 if (vd->lock_key_sync) {
3390 qemu_remove_led_event_handler(vd->led);
3391 vd->led = NULL;
3393 #ifdef CONFIG_VNC_SASL
3394 if (vd->sasl.authz) {
3395 object_unparent(OBJECT(vd->sasl.authz));
3396 vd->sasl.authz = NULL;
3398 g_free(vd->sasl.authzid);
3399 vd->sasl.authzid = NULL;
3400 #endif
3403 int vnc_display_password(const char *id, const char *password)
3405 VncDisplay *vd = vnc_display_find(id);
3407 if (!vd) {
3408 return -EINVAL;
3410 if (vd->auth == VNC_AUTH_NONE) {
3411 error_printf_unless_qmp("If you want use passwords please enable "
3412 "password auth using '-vnc ${dpy},password'.\n");
3413 return -EINVAL;
3416 g_free(vd->password);
3417 vd->password = g_strdup(password);
3419 return 0;
3422 int vnc_display_pw_expire(const char *id, time_t expires)
3424 VncDisplay *vd = vnc_display_find(id);
3426 if (!vd) {
3427 return -EINVAL;
3430 vd->expires = expires;
3431 return 0;
3434 static void vnc_display_print_local_addr(VncDisplay *vd)
3436 SocketAddress *addr;
3438 if (!vd->listener || !vd->listener->nsioc) {
3439 return;
3442 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], NULL);
3443 if (!addr) {
3444 return;
3447 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3448 qapi_free_SocketAddress(addr);
3449 return;
3451 error_printf_unless_qmp("VNC server running on %s:%s\n",
3452 addr->u.inet.host,
3453 addr->u.inet.port);
3454 qapi_free_SocketAddress(addr);
3457 static QemuOptsList qemu_vnc_opts = {
3458 .name = "vnc",
3459 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3460 .implied_opt_name = "vnc",
3461 .desc = {
3463 .name = "vnc",
3464 .type = QEMU_OPT_STRING,
3466 .name = "websocket",
3467 .type = QEMU_OPT_STRING,
3469 .name = "tls-creds",
3470 .type = QEMU_OPT_STRING,
3472 .name = "share",
3473 .type = QEMU_OPT_STRING,
3475 .name = "display",
3476 .type = QEMU_OPT_STRING,
3478 .name = "head",
3479 .type = QEMU_OPT_NUMBER,
3481 .name = "connections",
3482 .type = QEMU_OPT_NUMBER,
3484 .name = "to",
3485 .type = QEMU_OPT_NUMBER,
3487 .name = "ipv4",
3488 .type = QEMU_OPT_BOOL,
3490 .name = "ipv6",
3491 .type = QEMU_OPT_BOOL,
3493 .name = "password",
3494 .type = QEMU_OPT_BOOL,
3496 .name = "password-secret",
3497 .type = QEMU_OPT_STRING,
3499 .name = "reverse",
3500 .type = QEMU_OPT_BOOL,
3502 .name = "lock-key-sync",
3503 .type = QEMU_OPT_BOOL,
3505 .name = "key-delay-ms",
3506 .type = QEMU_OPT_NUMBER,
3508 .name = "sasl",
3509 .type = QEMU_OPT_BOOL,
3511 .name = "tls-authz",
3512 .type = QEMU_OPT_STRING,
3514 .name = "sasl-authz",
3515 .type = QEMU_OPT_STRING,
3517 .name = "lossy",
3518 .type = QEMU_OPT_BOOL,
3520 .name = "non-adaptive",
3521 .type = QEMU_OPT_BOOL,
3523 .name = "audiodev",
3524 .type = QEMU_OPT_STRING,
3526 .name = "power-control",
3527 .type = QEMU_OPT_BOOL,
3529 { /* end of list */ }
3534 static int
3535 vnc_display_setup_auth(int *auth,
3536 int *subauth,
3537 QCryptoTLSCreds *tlscreds,
3538 bool password,
3539 bool sasl,
3540 bool websocket,
3541 Error **errp)
3544 * We have a choice of 3 authentication options
3546 * 1. none
3547 * 2. vnc
3548 * 3. sasl
3550 * The channel can be run in 2 modes
3552 * 1. clear
3553 * 2. tls
3555 * And TLS can use 2 types of credentials
3557 * 1. anon
3558 * 2. x509
3560 * We thus have 9 possible logical combinations
3562 * 1. clear + none
3563 * 2. clear + vnc
3564 * 3. clear + sasl
3565 * 4. tls + anon + none
3566 * 5. tls + anon + vnc
3567 * 6. tls + anon + sasl
3568 * 7. tls + x509 + none
3569 * 8. tls + x509 + vnc
3570 * 9. tls + x509 + sasl
3572 * These need to be mapped into the VNC auth schemes
3573 * in an appropriate manner. In regular VNC, all the
3574 * TLS options get mapped into VNC_AUTH_VENCRYPT
3575 * sub-auth types.
3577 * In websockets, the https:// protocol already provides
3578 * TLS support, so there is no need to make use of the
3579 * VeNCrypt extension. Furthermore, websockets browser
3580 * clients could not use VeNCrypt even if they wanted to,
3581 * as they cannot control when the TLS handshake takes
3582 * place. Thus there is no option but to rely on https://,
3583 * meaning combinations 4->6 and 7->9 will be mapped to
3584 * VNC auth schemes in the same way as combos 1->3.
3586 * Regardless of fact that we have a different mapping to
3587 * VNC auth mechs for plain VNC vs websockets VNC, the end
3588 * result has the same security characteristics.
3590 if (websocket || !tlscreds) {
3591 if (password) {
3592 VNC_DEBUG("Initializing VNC server with password auth\n");
3593 *auth = VNC_AUTH_VNC;
3594 } else if (sasl) {
3595 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3596 *auth = VNC_AUTH_SASL;
3597 } else {
3598 VNC_DEBUG("Initializing VNC server with no auth\n");
3599 *auth = VNC_AUTH_NONE;
3601 *subauth = VNC_AUTH_INVALID;
3602 } else {
3603 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3604 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3605 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3606 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3608 if (!is_x509 && !is_anon) {
3609 error_setg(errp,
3610 "Unsupported TLS cred type %s",
3611 object_get_typename(OBJECT(tlscreds)));
3612 return -1;
3614 *auth = VNC_AUTH_VENCRYPT;
3615 if (password) {
3616 if (is_x509) {
3617 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3618 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3619 } else {
3620 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3621 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3624 } else if (sasl) {
3625 if (is_x509) {
3626 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3627 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3628 } else {
3629 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3630 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3632 } else {
3633 if (is_x509) {
3634 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3635 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3636 } else {
3637 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3638 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3642 return 0;
3646 static int vnc_display_get_address(const char *addrstr,
3647 bool websocket,
3648 bool reverse,
3649 int displaynum,
3650 int to,
3651 bool has_ipv4,
3652 bool has_ipv6,
3653 bool ipv4,
3654 bool ipv6,
3655 SocketAddress **retaddr,
3656 Error **errp)
3658 int ret = -1;
3659 SocketAddress *addr = NULL;
3661 addr = g_new0(SocketAddress, 1);
3663 if (strncmp(addrstr, "unix:", 5) == 0) {
3664 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3665 addr->u.q_unix.path = g_strdup(addrstr + 5);
3667 if (websocket) {
3668 error_setg(errp, "UNIX sockets not supported with websock");
3669 goto cleanup;
3672 if (to) {
3673 error_setg(errp, "Port range not support with UNIX socket");
3674 goto cleanup;
3676 ret = 0;
3677 } else {
3678 const char *port;
3679 size_t hostlen;
3680 unsigned long long baseport = 0;
3681 InetSocketAddress *inet;
3683 port = strrchr(addrstr, ':');
3684 if (!port) {
3685 if (websocket) {
3686 hostlen = 0;
3687 port = addrstr;
3688 } else {
3689 error_setg(errp, "no vnc port specified");
3690 goto cleanup;
3692 } else {
3693 hostlen = port - addrstr;
3694 port++;
3695 if (*port == '\0') {
3696 error_setg(errp, "vnc port cannot be empty");
3697 goto cleanup;
3701 addr->type = SOCKET_ADDRESS_TYPE_INET;
3702 inet = &addr->u.inet;
3703 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3704 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3705 } else {
3706 inet->host = g_strndup(addrstr, hostlen);
3708 /* plain VNC port is just an offset, for websocket
3709 * port is absolute */
3710 if (websocket) {
3711 if (g_str_equal(addrstr, "") ||
3712 g_str_equal(addrstr, "on")) {
3713 if (displaynum == -1) {
3714 error_setg(errp, "explicit websocket port is required");
3715 goto cleanup;
3717 inet->port = g_strdup_printf(
3718 "%d", displaynum + 5700);
3719 if (to) {
3720 inet->has_to = true;
3721 inet->to = to + 5700;
3723 } else {
3724 inet->port = g_strdup(port);
3726 } else {
3727 int offset = reverse ? 0 : 5900;
3728 if (parse_uint_full(port, &baseport, 10) < 0) {
3729 error_setg(errp, "can't convert to a number: %s", port);
3730 goto cleanup;
3732 if (baseport > 65535 ||
3733 baseport + offset > 65535) {
3734 error_setg(errp, "port %s out of range", port);
3735 goto cleanup;
3737 inet->port = g_strdup_printf(
3738 "%d", (int)baseport + offset);
3740 if (to) {
3741 inet->has_to = true;
3742 inet->to = to + offset;
3746 inet->ipv4 = ipv4;
3747 inet->has_ipv4 = has_ipv4;
3748 inet->ipv6 = ipv6;
3749 inet->has_ipv6 = has_ipv6;
3751 ret = baseport;
3754 *retaddr = addr;
3756 cleanup:
3757 if (ret < 0) {
3758 qapi_free_SocketAddress(addr);
3760 return ret;
3763 static void vnc_free_addresses(SocketAddress ***retsaddr,
3764 size_t *retnsaddr)
3766 size_t i;
3768 for (i = 0; i < *retnsaddr; i++) {
3769 qapi_free_SocketAddress((*retsaddr)[i]);
3771 g_free(*retsaddr);
3773 *retsaddr = NULL;
3774 *retnsaddr = 0;
3777 static int vnc_display_get_addresses(QemuOpts *opts,
3778 bool reverse,
3779 SocketAddress ***retsaddr,
3780 size_t *retnsaddr,
3781 SocketAddress ***retwsaddr,
3782 size_t *retnwsaddr,
3783 Error **errp)
3785 SocketAddress *saddr = NULL;
3786 SocketAddress *wsaddr = NULL;
3787 QemuOptsIter addriter;
3788 const char *addr;
3789 int to = qemu_opt_get_number(opts, "to", 0);
3790 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3791 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3792 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3793 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3794 int displaynum = -1;
3795 int ret = -1;
3797 *retsaddr = NULL;
3798 *retnsaddr = 0;
3799 *retwsaddr = NULL;
3800 *retnwsaddr = 0;
3802 addr = qemu_opt_get(opts, "vnc");
3803 if (addr == NULL || g_str_equal(addr, "none")) {
3804 ret = 0;
3805 goto cleanup;
3807 if (qemu_opt_get(opts, "websocket") &&
3808 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3809 error_setg(errp,
3810 "SHA1 hash support is required for websockets");
3811 goto cleanup;
3814 qemu_opt_iter_init(&addriter, opts, "vnc");
3815 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3816 int rv;
3817 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3818 has_ipv4, has_ipv6,
3819 ipv4, ipv6,
3820 &saddr, errp);
3821 if (rv < 0) {
3822 goto cleanup;
3824 /* Historical compat - first listen address can be used
3825 * to set the default websocket port
3827 if (displaynum == -1) {
3828 displaynum = rv;
3830 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3831 (*retsaddr)[(*retnsaddr)++] = saddr;
3834 /* If we had multiple primary displays, we don't do defaults
3835 * for websocket, and require explicit config instead. */
3836 if (*retnsaddr > 1) {
3837 displaynum = -1;
3840 qemu_opt_iter_init(&addriter, opts, "websocket");
3841 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3842 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3843 has_ipv4, has_ipv6,
3844 ipv4, ipv6,
3845 &wsaddr, errp) < 0) {
3846 goto cleanup;
3849 /* Historical compat - if only a single listen address was
3850 * provided, then this is used to set the default listen
3851 * address for websocket too
3853 if (*retnsaddr == 1 &&
3854 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3855 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3856 g_str_equal(wsaddr->u.inet.host, "") &&
3857 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3858 g_free(wsaddr->u.inet.host);
3859 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3862 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3863 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3866 ret = 0;
3867 cleanup:
3868 if (ret < 0) {
3869 vnc_free_addresses(retsaddr, retnsaddr);
3870 vnc_free_addresses(retwsaddr, retnwsaddr);
3872 return ret;
3875 static int vnc_display_connect(VncDisplay *vd,
3876 SocketAddress **saddr,
3877 size_t nsaddr,
3878 SocketAddress **wsaddr,
3879 size_t nwsaddr,
3880 Error **errp)
3882 /* connect to viewer */
3883 QIOChannelSocket *sioc = NULL;
3884 if (nwsaddr != 0) {
3885 error_setg(errp, "Cannot use websockets in reverse mode");
3886 return -1;
3888 if (nsaddr != 1) {
3889 error_setg(errp, "Expected a single address in reverse mode");
3890 return -1;
3892 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3893 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3894 sioc = qio_channel_socket_new();
3895 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3896 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3897 object_unref(OBJECT(sioc));
3898 return -1;
3900 vnc_connect(vd, sioc, false, false);
3901 object_unref(OBJECT(sioc));
3902 return 0;
3906 static int vnc_display_listen(VncDisplay *vd,
3907 SocketAddress **saddr,
3908 size_t nsaddr,
3909 SocketAddress **wsaddr,
3910 size_t nwsaddr,
3911 Error **errp)
3913 size_t i;
3915 if (nsaddr) {
3916 vd->listener = qio_net_listener_new();
3917 qio_net_listener_set_name(vd->listener, "vnc-listen");
3918 for (i = 0; i < nsaddr; i++) {
3919 if (qio_net_listener_open_sync(vd->listener,
3920 saddr[i], 1,
3921 errp) < 0) {
3922 return -1;
3926 qio_net_listener_set_client_func(vd->listener,
3927 vnc_listen_io, vd, NULL);
3930 if (nwsaddr) {
3931 vd->wslistener = qio_net_listener_new();
3932 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
3933 for (i = 0; i < nwsaddr; i++) {
3934 if (qio_net_listener_open_sync(vd->wslistener,
3935 wsaddr[i], 1,
3936 errp) < 0) {
3937 return -1;
3941 qio_net_listener_set_client_func(vd->wslistener,
3942 vnc_listen_io, vd, NULL);
3945 return 0;
3949 void vnc_display_open(const char *id, Error **errp)
3951 VncDisplay *vd = vnc_display_find(id);
3952 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3953 SocketAddress **saddr = NULL, **wsaddr = NULL;
3954 size_t nsaddr, nwsaddr;
3955 const char *share, *device_id;
3956 QemuConsole *con;
3957 bool password = false;
3958 bool reverse = false;
3959 const char *credid;
3960 bool sasl = false;
3961 const char *tlsauthz;
3962 const char *saslauthz;
3963 int lock_key_sync = 1;
3964 int key_delay_ms;
3965 const char *audiodev;
3966 const char *passwordSecret;
3968 if (!vd) {
3969 error_setg(errp, "VNC display not active");
3970 return;
3972 vnc_display_close(vd);
3974 if (!opts) {
3975 return;
3978 reverse = qemu_opt_get_bool(opts, "reverse", false);
3979 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3980 &wsaddr, &nwsaddr, errp) < 0) {
3981 goto fail;
3985 passwordSecret = qemu_opt_get(opts, "password-secret");
3986 if (passwordSecret) {
3987 if (qemu_opt_get(opts, "password")) {
3988 error_setg(errp,
3989 "'password' flag is redundant with 'password-secret'");
3990 goto fail;
3992 vd->password = qcrypto_secret_lookup_as_utf8(passwordSecret,
3993 errp);
3994 if (!vd->password) {
3995 goto fail;
3997 password = true;
3998 } else {
3999 password = qemu_opt_get_bool(opts, "password", false);
4001 if (password) {
4002 if (fips_get_state()) {
4003 error_setg(errp,
4004 "VNC password auth disabled due to FIPS mode, "
4005 "consider using the VeNCrypt or SASL authentication "
4006 "methods as an alternative");
4007 goto fail;
4009 if (!qcrypto_cipher_supports(
4010 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
4011 error_setg(errp,
4012 "Cipher backend does not support DES RFB algorithm");
4013 goto fail;
4017 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
4018 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
4019 sasl = qemu_opt_get_bool(opts, "sasl", false);
4020 #ifndef CONFIG_VNC_SASL
4021 if (sasl) {
4022 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
4023 goto fail;
4025 #endif /* CONFIG_VNC_SASL */
4026 credid = qemu_opt_get(opts, "tls-creds");
4027 if (credid) {
4028 Object *creds;
4029 creds = object_resolve_path_component(
4030 object_get_objects_root(), credid);
4031 if (!creds) {
4032 error_setg(errp, "No TLS credentials with id '%s'",
4033 credid);
4034 goto fail;
4036 vd->tlscreds = (QCryptoTLSCreds *)
4037 object_dynamic_cast(creds,
4038 TYPE_QCRYPTO_TLS_CREDS);
4039 if (!vd->tlscreds) {
4040 error_setg(errp, "Object with id '%s' is not TLS credentials",
4041 credid);
4042 goto fail;
4044 object_ref(OBJECT(vd->tlscreds));
4046 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
4047 error_setg(errp,
4048 "Expecting TLS credentials with a server endpoint");
4049 goto fail;
4052 tlsauthz = qemu_opt_get(opts, "tls-authz");
4053 if (tlsauthz && !vd->tlscreds) {
4054 error_setg(errp, "'tls-authz' provided but TLS is not enabled");
4055 goto fail;
4058 saslauthz = qemu_opt_get(opts, "sasl-authz");
4059 if (saslauthz && !sasl) {
4060 error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
4061 goto fail;
4064 share = qemu_opt_get(opts, "share");
4065 if (share) {
4066 if (strcmp(share, "ignore") == 0) {
4067 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4068 } else if (strcmp(share, "allow-exclusive") == 0) {
4069 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4070 } else if (strcmp(share, "force-shared") == 0) {
4071 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4072 } else {
4073 error_setg(errp, "unknown vnc share= option");
4074 goto fail;
4076 } else {
4077 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4079 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4081 #ifdef CONFIG_VNC_JPEG
4082 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4083 #endif
4084 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
4085 /* adaptive updates are only used with tight encoding and
4086 * if lossy updates are enabled so we can disable all the
4087 * calculations otherwise */
4088 if (!vd->lossy) {
4089 vd->non_adaptive = true;
4092 vd->power_control = qemu_opt_get_bool(opts, "power-control", false);
4094 if (tlsauthz) {
4095 vd->tlsauthzid = g_strdup(tlsauthz);
4097 #ifdef CONFIG_VNC_SASL
4098 if (sasl) {
4099 if (saslauthz) {
4100 vd->sasl.authzid = g_strdup(saslauthz);
4103 #endif
4105 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4106 vd->tlscreds, password,
4107 sasl, false, errp) < 0) {
4108 goto fail;
4110 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
4112 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4113 vd->tlscreds, password,
4114 sasl, true, errp) < 0) {
4115 goto fail;
4117 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
4119 #ifdef CONFIG_VNC_SASL
4120 if (sasl) {
4121 int saslErr = sasl_server_init(NULL, "qemu");
4123 if (saslErr != SASL_OK) {
4124 error_setg(errp, "Failed to initialize SASL auth: %s",
4125 sasl_errstring(saslErr, NULL, NULL));
4126 goto fail;
4129 #endif
4130 vd->lock_key_sync = lock_key_sync;
4131 if (lock_key_sync) {
4132 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4134 vd->ledstate = 0;
4136 audiodev = qemu_opt_get(opts, "audiodev");
4137 if (audiodev) {
4138 vd->audio_state = audio_state_by_name(audiodev);
4139 if (!vd->audio_state) {
4140 error_setg(errp, "Audiodev '%s' not found", audiodev);
4141 goto fail;
4145 device_id = qemu_opt_get(opts, "display");
4146 if (device_id) {
4147 int head = qemu_opt_get_number(opts, "head", 0);
4148 Error *err = NULL;
4150 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4151 if (err) {
4152 error_propagate(errp, err);
4153 goto fail;
4155 } else {
4156 con = NULL;
4159 if (con != vd->dcl.con) {
4160 qkbd_state_free(vd->kbd);
4161 unregister_displaychangelistener(&vd->dcl);
4162 vd->dcl.con = con;
4163 register_displaychangelistener(&vd->dcl);
4164 vd->kbd = qkbd_state_init(vd->dcl.con);
4166 qkbd_state_set_delay(vd->kbd, key_delay_ms);
4168 if (saddr == NULL) {
4169 goto cleanup;
4172 if (reverse) {
4173 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4174 goto fail;
4176 } else {
4177 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4178 goto fail;
4182 if (qemu_opt_get(opts, "to")) {
4183 vnc_display_print_local_addr(vd);
4186 cleanup:
4187 vnc_free_addresses(&saddr, &nsaddr);
4188 vnc_free_addresses(&wsaddr, &nwsaddr);
4189 return;
4191 fail:
4192 vnc_display_close(vd);
4193 goto cleanup;
4196 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4198 VncDisplay *vd = vnc_display_find(id);
4199 QIOChannelSocket *sioc;
4201 if (!vd) {
4202 return;
4205 sioc = qio_channel_socket_new_fd(csock, NULL);
4206 if (sioc) {
4207 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4208 vnc_connect(vd, sioc, skipauth, false);
4209 object_unref(OBJECT(sioc));
4213 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4215 int i = 2;
4216 char *id;
4218 id = g_strdup("default");
4219 while (qemu_opts_find(olist, id)) {
4220 g_free(id);
4221 id = g_strdup_printf("vnc%d", i++);
4223 qemu_opts_set_id(opts, id);
4226 void vnc_parse(const char *str)
4228 QemuOptsList *olist = qemu_find_opts("vnc");
4229 QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str));
4230 const char *id;
4232 if (!opts) {
4233 exit(1);
4236 id = qemu_opts_id(opts);
4237 if (!id) {
4238 /* auto-assign id if not present */
4239 vnc_auto_assign_id(olist, opts);
4243 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4245 Error *local_err = NULL;
4246 char *id = (char *)qemu_opts_id(opts);
4248 assert(id);
4249 vnc_display_init(id, &local_err);
4250 if (local_err) {
4251 error_propagate(errp, local_err);
4252 return -1;
4254 vnc_display_open(id, &local_err);
4255 if (local_err != NULL) {
4256 error_propagate(errp, local_err);
4257 return -1;
4259 return 0;
4262 static void vnc_register_config(void)
4264 qemu_add_opts(&qemu_vnc_opts);
4266 opts_init(vnc_register_config);