virt-arm: add node-id property to CPU
[qemu.git] / ui / vnc.c
blob9c4edcdbf5d9826c55afc267e62c97fbff7367cc
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.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
36 #include "qemu/acl.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
48 #include "io/dns-resolver.h"
50 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
51 #define VNC_REFRESH_INTERVAL_INC 50
52 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
53 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
54 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
56 #include "vnc_keysym.h"
57 #include "crypto/cipher.h"
59 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
60 QTAILQ_HEAD_INITIALIZER(vnc_displays);
62 static int vnc_cursor_define(VncState *vs);
63 static void vnc_release_modifiers(VncState *vs);
65 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
67 #ifdef _VNC_DEBUG
68 static const char *mn[] = {
69 [0] = "undefined",
70 [VNC_SHARE_MODE_CONNECTING] = "connecting",
71 [VNC_SHARE_MODE_SHARED] = "shared",
72 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
73 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
75 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
76 vs->ioc, mn[vs->share_mode], mn[mode]);
77 #endif
79 switch (vs->share_mode) {
80 case VNC_SHARE_MODE_CONNECTING:
81 vs->vd->num_connecting--;
82 break;
83 case VNC_SHARE_MODE_SHARED:
84 vs->vd->num_shared--;
85 break;
86 case VNC_SHARE_MODE_EXCLUSIVE:
87 vs->vd->num_exclusive--;
88 break;
89 default:
90 break;
93 vs->share_mode = mode;
95 switch (vs->share_mode) {
96 case VNC_SHARE_MODE_CONNECTING:
97 vs->vd->num_connecting++;
98 break;
99 case VNC_SHARE_MODE_SHARED:
100 vs->vd->num_shared++;
101 break;
102 case VNC_SHARE_MODE_EXCLUSIVE:
103 vs->vd->num_exclusive++;
104 break;
105 default:
106 break;
111 static void vnc_init_basic_info(SocketAddress *addr,
112 VncBasicInfo *info,
113 Error **errp)
115 switch (addr->type) {
116 case SOCKET_ADDRESS_TYPE_INET:
117 info->host = g_strdup(addr->u.inet.host);
118 info->service = g_strdup(addr->u.inet.port);
119 if (addr->u.inet.ipv6) {
120 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
121 } else {
122 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
124 break;
126 case SOCKET_ADDRESS_TYPE_UNIX:
127 info->host = g_strdup("");
128 info->service = g_strdup(addr->u.q_unix.path);
129 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
130 break;
132 case SOCKET_ADDRESS_TYPE_VSOCK:
133 case SOCKET_ADDRESS_TYPE_FD:
134 error_setg(errp, "Unsupported socket address type %s",
135 SocketAddressType_lookup[addr->type]);
136 break;
137 default:
138 abort();
141 return;
144 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
145 VncBasicInfo *info,
146 Error **errp)
148 SocketAddress *addr = NULL;
150 if (!ioc) {
151 error_setg(errp, "No listener socket available");
152 return;
155 addr = qio_channel_socket_get_local_address(ioc, errp);
156 if (!addr) {
157 return;
160 vnc_init_basic_info(addr, info, errp);
161 qapi_free_SocketAddress(addr);
164 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
165 VncBasicInfo *info,
166 Error **errp)
168 SocketAddress *addr = NULL;
170 addr = qio_channel_socket_get_remote_address(ioc, errp);
171 if (!addr) {
172 return;
175 vnc_init_basic_info(addr, info, errp);
176 qapi_free_SocketAddress(addr);
179 static const char *vnc_auth_name(VncDisplay *vd) {
180 switch (vd->auth) {
181 case VNC_AUTH_INVALID:
182 return "invalid";
183 case VNC_AUTH_NONE:
184 return "none";
185 case VNC_AUTH_VNC:
186 return "vnc";
187 case VNC_AUTH_RA2:
188 return "ra2";
189 case VNC_AUTH_RA2NE:
190 return "ra2ne";
191 case VNC_AUTH_TIGHT:
192 return "tight";
193 case VNC_AUTH_ULTRA:
194 return "ultra";
195 case VNC_AUTH_TLS:
196 return "tls";
197 case VNC_AUTH_VENCRYPT:
198 switch (vd->subauth) {
199 case VNC_AUTH_VENCRYPT_PLAIN:
200 return "vencrypt+plain";
201 case VNC_AUTH_VENCRYPT_TLSNONE:
202 return "vencrypt+tls+none";
203 case VNC_AUTH_VENCRYPT_TLSVNC:
204 return "vencrypt+tls+vnc";
205 case VNC_AUTH_VENCRYPT_TLSPLAIN:
206 return "vencrypt+tls+plain";
207 case VNC_AUTH_VENCRYPT_X509NONE:
208 return "vencrypt+x509+none";
209 case VNC_AUTH_VENCRYPT_X509VNC:
210 return "vencrypt+x509+vnc";
211 case VNC_AUTH_VENCRYPT_X509PLAIN:
212 return "vencrypt+x509+plain";
213 case VNC_AUTH_VENCRYPT_TLSSASL:
214 return "vencrypt+tls+sasl";
215 case VNC_AUTH_VENCRYPT_X509SASL:
216 return "vencrypt+x509+sasl";
217 default:
218 return "vencrypt";
220 case VNC_AUTH_SASL:
221 return "sasl";
223 return "unknown";
226 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
228 VncServerInfo *info;
229 Error *err = NULL;
231 if (!vd->nlsock) {
232 return NULL;
235 info = g_malloc0(sizeof(*info));
236 vnc_init_basic_info_from_server_addr(vd->lsock[0],
237 qapi_VncServerInfo_base(info), &err);
238 info->has_auth = true;
239 info->auth = g_strdup(vnc_auth_name(vd));
240 if (err) {
241 qapi_free_VncServerInfo(info);
242 info = NULL;
243 error_free(err);
245 return info;
248 static void vnc_client_cache_auth(VncState *client)
250 if (!client->info) {
251 return;
254 if (client->tls) {
255 client->info->x509_dname =
256 qcrypto_tls_session_get_peer_name(client->tls);
257 client->info->has_x509_dname =
258 client->info->x509_dname != NULL;
260 #ifdef CONFIG_VNC_SASL
261 if (client->sasl.conn &&
262 client->sasl.username) {
263 client->info->has_sasl_username = true;
264 client->info->sasl_username = g_strdup(client->sasl.username);
266 #endif
269 static void vnc_client_cache_addr(VncState *client)
271 Error *err = NULL;
273 client->info = g_malloc0(sizeof(*client->info));
274 vnc_init_basic_info_from_remote_addr(client->sioc,
275 qapi_VncClientInfo_base(client->info),
276 &err);
277 if (err) {
278 qapi_free_VncClientInfo(client->info);
279 client->info = NULL;
280 error_free(err);
284 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
286 VncServerInfo *si;
288 if (!vs->info) {
289 return;
292 si = vnc_server_info_get(vs->vd);
293 if (!si) {
294 return;
297 switch (event) {
298 case QAPI_EVENT_VNC_CONNECTED:
299 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
300 &error_abort);
301 break;
302 case QAPI_EVENT_VNC_INITIALIZED:
303 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
304 break;
305 case QAPI_EVENT_VNC_DISCONNECTED:
306 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
307 break;
308 default:
309 break;
312 qapi_free_VncServerInfo(si);
315 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
317 VncClientInfo *info;
318 Error *err = NULL;
320 info = g_malloc0(sizeof(*info));
322 vnc_init_basic_info_from_remote_addr(client->sioc,
323 qapi_VncClientInfo_base(info),
324 &err);
325 if (err) {
326 error_free(err);
327 qapi_free_VncClientInfo(info);
328 return NULL;
331 info->websocket = client->websocket;
333 if (client->tls) {
334 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
335 info->has_x509_dname = info->x509_dname != NULL;
337 #ifdef CONFIG_VNC_SASL
338 if (client->sasl.conn && client->sasl.username) {
339 info->has_sasl_username = true;
340 info->sasl_username = g_strdup(client->sasl.username);
342 #endif
344 return info;
347 static VncDisplay *vnc_display_find(const char *id)
349 VncDisplay *vd;
351 if (id == NULL) {
352 return QTAILQ_FIRST(&vnc_displays);
354 QTAILQ_FOREACH(vd, &vnc_displays, next) {
355 if (strcmp(id, vd->id) == 0) {
356 return vd;
359 return NULL;
362 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
364 VncClientInfoList *cinfo, *prev = NULL;
365 VncState *client;
367 QTAILQ_FOREACH(client, &vd->clients, next) {
368 cinfo = g_new0(VncClientInfoList, 1);
369 cinfo->value = qmp_query_vnc_client(client);
370 cinfo->next = prev;
371 prev = cinfo;
373 return prev;
376 VncInfo *qmp_query_vnc(Error **errp)
378 VncInfo *info = g_malloc0(sizeof(*info));
379 VncDisplay *vd = vnc_display_find(NULL);
380 SocketAddress *addr = NULL;
382 if (vd == NULL || !vd->nlsock) {
383 info->enabled = false;
384 } else {
385 info->enabled = true;
387 /* for compatibility with the original command */
388 info->has_clients = true;
389 info->clients = qmp_query_client_list(vd);
391 if (vd->lsock == NULL) {
392 return info;
395 addr = qio_channel_socket_get_local_address(vd->lsock[0], errp);
396 if (!addr) {
397 goto out_error;
400 switch (addr->type) {
401 case SOCKET_ADDRESS_TYPE_INET:
402 info->host = g_strdup(addr->u.inet.host);
403 info->service = g_strdup(addr->u.inet.port);
404 if (addr->u.inet.ipv6) {
405 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
406 } else {
407 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
409 break;
411 case SOCKET_ADDRESS_TYPE_UNIX:
412 info->host = g_strdup("");
413 info->service = g_strdup(addr->u.q_unix.path);
414 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
415 break;
417 case SOCKET_ADDRESS_TYPE_VSOCK:
418 case SOCKET_ADDRESS_TYPE_FD:
419 error_setg(errp, "Unsupported socket address type %s",
420 SocketAddressType_lookup[addr->type]);
421 goto out_error;
422 default:
423 abort();
426 info->has_host = true;
427 info->has_service = true;
428 info->has_family = true;
430 info->has_auth = true;
431 info->auth = g_strdup(vnc_auth_name(vd));
434 qapi_free_SocketAddress(addr);
435 return info;
437 out_error:
438 qapi_free_SocketAddress(addr);
439 qapi_free_VncInfo(info);
440 return NULL;
444 static void qmp_query_auth(int auth, int subauth,
445 VncPrimaryAuth *qmp_auth,
446 VncVencryptSubAuth *qmp_vencrypt,
447 bool *qmp_has_vencrypt);
449 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
450 bool websocket,
451 int auth,
452 int subauth,
453 VncServerInfo2List *prev)
455 VncServerInfo2List *list;
456 VncServerInfo2 *info;
457 Error *err = NULL;
458 SocketAddress *addr;
460 addr = qio_channel_socket_get_local_address(ioc, &err);
461 if (!addr) {
462 error_free(err);
463 return prev;
466 info = g_new0(VncServerInfo2, 1);
467 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
468 qapi_free_SocketAddress(addr);
469 if (err) {
470 qapi_free_VncServerInfo2(info);
471 error_free(err);
472 return prev;
474 info->websocket = websocket;
476 qmp_query_auth(auth, subauth, &info->auth,
477 &info->vencrypt, &info->has_vencrypt);
479 list = g_new0(VncServerInfo2List, 1);
480 list->value = info;
481 list->next = prev;
482 return list;
485 static void qmp_query_auth(int auth, int subauth,
486 VncPrimaryAuth *qmp_auth,
487 VncVencryptSubAuth *qmp_vencrypt,
488 bool *qmp_has_vencrypt)
490 switch (auth) {
491 case VNC_AUTH_VNC:
492 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
493 break;
494 case VNC_AUTH_RA2:
495 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
496 break;
497 case VNC_AUTH_RA2NE:
498 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
499 break;
500 case VNC_AUTH_TIGHT:
501 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
502 break;
503 case VNC_AUTH_ULTRA:
504 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
505 break;
506 case VNC_AUTH_TLS:
507 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
508 break;
509 case VNC_AUTH_VENCRYPT:
510 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
511 *qmp_has_vencrypt = true;
512 switch (subauth) {
513 case VNC_AUTH_VENCRYPT_PLAIN:
514 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
515 break;
516 case VNC_AUTH_VENCRYPT_TLSNONE:
517 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
518 break;
519 case VNC_AUTH_VENCRYPT_TLSVNC:
520 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
521 break;
522 case VNC_AUTH_VENCRYPT_TLSPLAIN:
523 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
524 break;
525 case VNC_AUTH_VENCRYPT_X509NONE:
526 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
527 break;
528 case VNC_AUTH_VENCRYPT_X509VNC:
529 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
530 break;
531 case VNC_AUTH_VENCRYPT_X509PLAIN:
532 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
533 break;
534 case VNC_AUTH_VENCRYPT_TLSSASL:
535 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
536 break;
537 case VNC_AUTH_VENCRYPT_X509SASL:
538 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
539 break;
540 default:
541 *qmp_has_vencrypt = false;
542 break;
544 break;
545 case VNC_AUTH_SASL:
546 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
547 break;
548 case VNC_AUTH_NONE:
549 default:
550 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
551 break;
555 VncInfo2List *qmp_query_vnc_servers(Error **errp)
557 VncInfo2List *item, *prev = NULL;
558 VncInfo2 *info;
559 VncDisplay *vd;
560 DeviceState *dev;
561 size_t i;
563 QTAILQ_FOREACH(vd, &vnc_displays, next) {
564 info = g_new0(VncInfo2, 1);
565 info->id = g_strdup(vd->id);
566 info->clients = qmp_query_client_list(vd);
567 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
568 &info->vencrypt, &info->has_vencrypt);
569 if (vd->dcl.con) {
570 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
571 "device", NULL));
572 info->has_display = true;
573 info->display = g_strdup(dev->id);
575 for (i = 0; i < vd->nlsock; i++) {
576 info->server = qmp_query_server_entry(
577 vd->lsock[i], false, vd->auth, vd->subauth, info->server);
579 for (i = 0; i < vd->nlwebsock; i++) {
580 info->server = qmp_query_server_entry(
581 vd->lwebsock[i], true, vd->ws_auth,
582 vd->ws_subauth, info->server);
585 item = g_new0(VncInfo2List, 1);
586 item->value = info;
587 item->next = prev;
588 prev = item;
590 return prev;
593 /* TODO
594 1) Get the queue working for IO.
595 2) there is some weirdness when using the -S option (the screen is grey
596 and not totally invalidated
597 3) resolutions > 1024
600 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
601 static void vnc_disconnect_start(VncState *vs);
603 static void vnc_colordepth(VncState *vs);
604 static void framebuffer_update_request(VncState *vs, int incremental,
605 int x_position, int y_position,
606 int w, int h);
607 static void vnc_refresh(DisplayChangeListener *dcl);
608 static int vnc_refresh_server_surface(VncDisplay *vd);
610 static int vnc_width(VncDisplay *vd)
612 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
613 VNC_DIRTY_PIXELS_PER_BIT));
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);
666 static void vnc_desktop_resize(VncState *vs)
668 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
669 return;
671 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
672 vs->client_height == pixman_image_get_height(vs->vd->server)) {
673 return;
675 vs->client_width = pixman_image_get_width(vs->vd->server);
676 vs->client_height = pixman_image_get_height(vs->vd->server);
677 vnc_lock_output(vs);
678 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
679 vnc_write_u8(vs, 0);
680 vnc_write_u16(vs, 1); /* number of rects */
681 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
682 VNC_ENCODING_DESKTOPRESIZE);
683 vnc_unlock_output(vs);
684 vnc_flush(vs);
687 static void vnc_abort_display_jobs(VncDisplay *vd)
689 VncState *vs;
691 QTAILQ_FOREACH(vs, &vd->clients, next) {
692 vnc_lock_output(vs);
693 vs->abort = true;
694 vnc_unlock_output(vs);
696 QTAILQ_FOREACH(vs, &vd->clients, next) {
697 vnc_jobs_join(vs);
699 QTAILQ_FOREACH(vs, &vd->clients, next) {
700 vnc_lock_output(vs);
701 vs->abort = false;
702 vnc_unlock_output(vs);
706 int vnc_server_fb_stride(VncDisplay *vd)
708 return pixman_image_get_stride(vd->server);
711 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
713 uint8_t *ptr;
715 ptr = (uint8_t *)pixman_image_get_data(vd->server);
716 ptr += y * vnc_server_fb_stride(vd);
717 ptr += x * VNC_SERVER_FB_BYTES;
718 return ptr;
721 static void vnc_update_server_surface(VncDisplay *vd)
723 int width, height;
725 qemu_pixman_image_unref(vd->server);
726 vd->server = NULL;
728 if (QTAILQ_EMPTY(&vd->clients)) {
729 return;
732 width = vnc_width(vd);
733 height = vnc_height(vd);
734 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
735 width, height,
736 NULL, 0);
738 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
739 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
740 width, height);
743 static void vnc_dpy_switch(DisplayChangeListener *dcl,
744 DisplaySurface *surface)
746 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
747 VncState *vs;
749 vnc_abort_display_jobs(vd);
750 vd->ds = surface;
752 /* server surface */
753 vnc_update_server_surface(vd);
755 /* guest surface */
756 qemu_pixman_image_unref(vd->guest.fb);
757 vd->guest.fb = pixman_image_ref(surface->image);
758 vd->guest.format = surface->format;
760 QTAILQ_FOREACH(vs, &vd->clients, next) {
761 vnc_colordepth(vs);
762 vnc_desktop_resize(vs);
763 if (vs->vd->cursor) {
764 vnc_cursor_define(vs);
766 memset(vs->dirty, 0x00, sizeof(vs->dirty));
767 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
768 vnc_width(vd),
769 vnc_height(vd));
773 /* fastest code */
774 static void vnc_write_pixels_copy(VncState *vs,
775 void *pixels, int size)
777 vnc_write(vs, pixels, size);
780 /* slowest but generic code. */
781 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
783 uint8_t r, g, b;
785 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
786 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
787 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
788 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
789 #else
790 # error need some bits here if you change VNC_SERVER_FB_FORMAT
791 #endif
792 v = (r << vs->client_pf.rshift) |
793 (g << vs->client_pf.gshift) |
794 (b << vs->client_pf.bshift);
795 switch (vs->client_pf.bytes_per_pixel) {
796 case 1:
797 buf[0] = v;
798 break;
799 case 2:
800 if (vs->client_be) {
801 buf[0] = v >> 8;
802 buf[1] = v;
803 } else {
804 buf[1] = v >> 8;
805 buf[0] = v;
807 break;
808 default:
809 case 4:
810 if (vs->client_be) {
811 buf[0] = v >> 24;
812 buf[1] = v >> 16;
813 buf[2] = v >> 8;
814 buf[3] = v;
815 } else {
816 buf[3] = v >> 24;
817 buf[2] = v >> 16;
818 buf[1] = v >> 8;
819 buf[0] = v;
821 break;
825 static void vnc_write_pixels_generic(VncState *vs,
826 void *pixels1, int size)
828 uint8_t buf[4];
830 if (VNC_SERVER_FB_BYTES == 4) {
831 uint32_t *pixels = pixels1;
832 int n, i;
833 n = size >> 2;
834 for (i = 0; i < n; i++) {
835 vnc_convert_pixel(vs, buf, pixels[i]);
836 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
841 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
843 int i;
844 uint8_t *row;
845 VncDisplay *vd = vs->vd;
847 row = vnc_server_fb_ptr(vd, x, y);
848 for (i = 0; i < h; i++) {
849 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
850 row += vnc_server_fb_stride(vd);
852 return 1;
855 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
857 int n = 0;
858 bool encode_raw = false;
859 size_t saved_offs = vs->output.offset;
861 switch(vs->vnc_encoding) {
862 case VNC_ENCODING_ZLIB:
863 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
864 break;
865 case VNC_ENCODING_HEXTILE:
866 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
867 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
868 break;
869 case VNC_ENCODING_TIGHT:
870 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
871 break;
872 case VNC_ENCODING_TIGHT_PNG:
873 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
874 break;
875 case VNC_ENCODING_ZRLE:
876 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
877 break;
878 case VNC_ENCODING_ZYWRLE:
879 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
880 break;
881 default:
882 encode_raw = true;
883 break;
886 /* If the client has the same pixel format as our internal buffer and
887 * a RAW encoding would need less space fall back to RAW encoding to
888 * save bandwidth and processing power in the client. */
889 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
890 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
891 vs->output.offset = saved_offs;
892 encode_raw = true;
895 if (encode_raw) {
896 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
897 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
900 return n;
903 static void vnc_mouse_set(DisplayChangeListener *dcl,
904 int x, int y, int visible)
906 /* can we ask the client(s) to move the pointer ??? */
909 static int vnc_cursor_define(VncState *vs)
911 QEMUCursor *c = vs->vd->cursor;
912 int isize;
914 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
915 vnc_lock_output(vs);
916 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
917 vnc_write_u8(vs, 0); /* padding */
918 vnc_write_u16(vs, 1); /* # of rects */
919 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
920 VNC_ENCODING_RICH_CURSOR);
921 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
922 vnc_write_pixels_generic(vs, c->data, isize);
923 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
924 vnc_unlock_output(vs);
925 return 0;
927 return -1;
930 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
931 QEMUCursor *c)
933 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
934 VncState *vs;
936 cursor_put(vd->cursor);
937 g_free(vd->cursor_mask);
939 vd->cursor = c;
940 cursor_get(vd->cursor);
941 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
942 vd->cursor_mask = g_malloc0(vd->cursor_msize);
943 cursor_get_mono_mask(c, 0, vd->cursor_mask);
945 QTAILQ_FOREACH(vs, &vd->clients, next) {
946 vnc_cursor_define(vs);
950 static int find_and_clear_dirty_height(VncState *vs,
951 int y, int last_x, int x, int height)
953 int h;
955 for (h = 1; h < (height - y); h++) {
956 if (!test_bit(last_x, vs->dirty[y + h])) {
957 break;
959 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
962 return h;
965 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
967 if (vs->disconnecting) {
968 vnc_disconnect_finish(vs);
969 return 0;
972 vs->has_dirty += has_dirty;
973 if (vs->need_update && !vs->disconnecting) {
974 VncDisplay *vd = vs->vd;
975 VncJob *job;
976 int y;
977 int height, width;
978 int n = 0;
980 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
981 /* kernel send buffers are full -> drop frames to throttle */
982 return 0;
984 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
985 return 0;
988 * Send screen updates to the vnc client using the server
989 * surface and server dirty map. guest surface updates
990 * happening in parallel don't disturb us, the next pass will
991 * send them to the client.
993 job = vnc_job_new(vs);
995 height = pixman_image_get_height(vd->server);
996 width = pixman_image_get_width(vd->server);
998 y = 0;
999 for (;;) {
1000 int x, h;
1001 unsigned long x2;
1002 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1003 height * VNC_DIRTY_BPL(vs),
1004 y * VNC_DIRTY_BPL(vs));
1005 if (offset == height * VNC_DIRTY_BPL(vs)) {
1006 /* no more dirty bits */
1007 break;
1009 y = offset / VNC_DIRTY_BPL(vs);
1010 x = offset % VNC_DIRTY_BPL(vs);
1011 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1012 VNC_DIRTY_BPL(vs), x);
1013 bitmap_clear(vs->dirty[y], x, x2 - x);
1014 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1015 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1016 if (x2 > x) {
1017 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1018 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1020 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1021 y += h;
1022 if (y == height) {
1023 break;
1028 vnc_job_push(job);
1029 if (sync) {
1030 vnc_jobs_join(vs);
1032 vs->force_update = 0;
1033 vs->has_dirty = 0;
1034 return n;
1037 if (vs->disconnecting) {
1038 vnc_disconnect_finish(vs);
1039 } else if (sync) {
1040 vnc_jobs_join(vs);
1043 return 0;
1046 /* audio */
1047 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1049 VncState *vs = opaque;
1051 switch (cmd) {
1052 case AUD_CNOTIFY_DISABLE:
1053 vnc_lock_output(vs);
1054 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1055 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1056 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1057 vnc_unlock_output(vs);
1058 vnc_flush(vs);
1059 break;
1061 case AUD_CNOTIFY_ENABLE:
1062 vnc_lock_output(vs);
1063 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1064 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1065 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1066 vnc_unlock_output(vs);
1067 vnc_flush(vs);
1068 break;
1072 static void audio_capture_destroy(void *opaque)
1076 static void audio_capture(void *opaque, void *buf, int size)
1078 VncState *vs = opaque;
1080 vnc_lock_output(vs);
1081 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1082 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1083 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1084 vnc_write_u32(vs, size);
1085 vnc_write(vs, buf, size);
1086 vnc_unlock_output(vs);
1087 vnc_flush(vs);
1090 static void audio_add(VncState *vs)
1092 struct audio_capture_ops ops;
1094 if (vs->audio_cap) {
1095 error_report("audio already running");
1096 return;
1099 ops.notify = audio_capture_notify;
1100 ops.destroy = audio_capture_destroy;
1101 ops.capture = audio_capture;
1103 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1104 if (!vs->audio_cap) {
1105 error_report("Failed to add audio capture");
1109 static void audio_del(VncState *vs)
1111 if (vs->audio_cap) {
1112 AUD_del_capture(vs->audio_cap, vs);
1113 vs->audio_cap = NULL;
1117 static void vnc_disconnect_start(VncState *vs)
1119 if (vs->disconnecting) {
1120 return;
1122 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1123 if (vs->ioc_tag) {
1124 g_source_remove(vs->ioc_tag);
1126 qio_channel_close(vs->ioc, NULL);
1127 vs->disconnecting = TRUE;
1130 void vnc_disconnect_finish(VncState *vs)
1132 int i;
1134 vnc_jobs_join(vs); /* Wait encoding jobs */
1136 vnc_lock_output(vs);
1137 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1139 buffer_free(&vs->input);
1140 buffer_free(&vs->output);
1142 qapi_free_VncClientInfo(vs->info);
1144 vnc_zlib_clear(vs);
1145 vnc_tight_clear(vs);
1146 vnc_zrle_clear(vs);
1148 #ifdef CONFIG_VNC_SASL
1149 vnc_sasl_client_cleanup(vs);
1150 #endif /* CONFIG_VNC_SASL */
1151 audio_del(vs);
1152 vnc_release_modifiers(vs);
1154 if (vs->mouse_mode_notifier.notify != NULL) {
1155 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1157 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1158 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1159 /* last client gone */
1160 vnc_update_server_surface(vs->vd);
1163 vnc_unlock_output(vs);
1165 qemu_mutex_destroy(&vs->output_mutex);
1166 if (vs->bh != NULL) {
1167 qemu_bh_delete(vs->bh);
1169 buffer_free(&vs->jobs_buffer);
1171 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1172 g_free(vs->lossy_rect[i]);
1174 g_free(vs->lossy_rect);
1176 object_unref(OBJECT(vs->ioc));
1177 vs->ioc = NULL;
1178 object_unref(OBJECT(vs->sioc));
1179 vs->sioc = NULL;
1180 g_free(vs);
1183 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1185 if (ret <= 0) {
1186 if (ret == 0) {
1187 VNC_DEBUG("Closing down client sock: EOF\n");
1188 vnc_disconnect_start(vs);
1189 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1190 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1191 ret, errp ? error_get_pretty(*errp) : "Unknown");
1192 vnc_disconnect_start(vs);
1195 if (errp) {
1196 error_free(*errp);
1197 *errp = NULL;
1199 return 0;
1201 return ret;
1205 void vnc_client_error(VncState *vs)
1207 VNC_DEBUG("Closing down client sock: protocol error\n");
1208 vnc_disconnect_start(vs);
1213 * Called to write a chunk of data to the client socket. The data may
1214 * be the raw data, or may have already been encoded by SASL.
1215 * The data will be written either straight onto the socket, or
1216 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1218 * NB, it is theoretically possible to have 2 layers of encryption,
1219 * both SASL, and this TLS layer. It is highly unlikely in practice
1220 * though, since SASL encryption will typically be a no-op if TLS
1221 * is active
1223 * Returns the number of bytes written, which may be less than
1224 * the requested 'datalen' if the socket would block. Returns
1225 * -1 on error, and disconnects the client socket.
1227 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1229 Error *err = NULL;
1230 ssize_t ret;
1231 ret = qio_channel_write(
1232 vs->ioc, (const char *)data, datalen, &err);
1233 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1234 return vnc_client_io_error(vs, ret, &err);
1239 * Called to write buffered data to the client socket, when not
1240 * using any SASL SSF encryption layers. Will write as much data
1241 * as possible without blocking. If all buffered data is written,
1242 * will switch the FD poll() handler back to read monitoring.
1244 * Returns the number of bytes written, which may be less than
1245 * the buffered output data if the socket would block. Returns
1246 * -1 on error, and disconnects the client socket.
1248 static ssize_t vnc_client_write_plain(VncState *vs)
1250 ssize_t ret;
1252 #ifdef CONFIG_VNC_SASL
1253 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1254 vs->output.buffer, vs->output.capacity, vs->output.offset,
1255 vs->sasl.waitWriteSSF);
1257 if (vs->sasl.conn &&
1258 vs->sasl.runSSF &&
1259 vs->sasl.waitWriteSSF) {
1260 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1261 if (ret)
1262 vs->sasl.waitWriteSSF -= ret;
1263 } else
1264 #endif /* CONFIG_VNC_SASL */
1265 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1266 if (!ret)
1267 return 0;
1269 buffer_advance(&vs->output, ret);
1271 if (vs->output.offset == 0) {
1272 if (vs->ioc_tag) {
1273 g_source_remove(vs->ioc_tag);
1275 vs->ioc_tag = qio_channel_add_watch(
1276 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1279 return ret;
1284 * First function called whenever there is data to be written to
1285 * the client socket. Will delegate actual work according to whether
1286 * SASL SSF layers are enabled (thus requiring encryption calls)
1288 static void vnc_client_write_locked(VncState *vs)
1290 #ifdef CONFIG_VNC_SASL
1291 if (vs->sasl.conn &&
1292 vs->sasl.runSSF &&
1293 !vs->sasl.waitWriteSSF) {
1294 vnc_client_write_sasl(vs);
1295 } else
1296 #endif /* CONFIG_VNC_SASL */
1298 vnc_client_write_plain(vs);
1302 static void vnc_client_write(VncState *vs)
1305 vnc_lock_output(vs);
1306 if (vs->output.offset) {
1307 vnc_client_write_locked(vs);
1308 } else if (vs->ioc != NULL) {
1309 if (vs->ioc_tag) {
1310 g_source_remove(vs->ioc_tag);
1312 vs->ioc_tag = qio_channel_add_watch(
1313 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1315 vnc_unlock_output(vs);
1318 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1320 vs->read_handler = func;
1321 vs->read_handler_expect = expecting;
1326 * Called to read a chunk of data from the client socket. The data may
1327 * be the raw data, or may need to be further decoded by SASL.
1328 * The data will be read either straight from to the socket, or
1329 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1331 * NB, it is theoretically possible to have 2 layers of encryption,
1332 * both SASL, and this TLS layer. It is highly unlikely in practice
1333 * though, since SASL encryption will typically be a no-op if TLS
1334 * is active
1336 * Returns the number of bytes read, which may be less than
1337 * the requested 'datalen' if the socket would block. Returns
1338 * -1 on error, and disconnects the client socket.
1340 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1342 ssize_t ret;
1343 Error *err = NULL;
1344 ret = qio_channel_read(
1345 vs->ioc, (char *)data, datalen, &err);
1346 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1347 return vnc_client_io_error(vs, ret, &err);
1352 * Called to read data from the client socket to the input buffer,
1353 * when not using any SASL SSF encryption layers. Will read as much
1354 * data as possible without blocking.
1356 * Returns the number of bytes read. Returns -1 on error, and
1357 * disconnects the client socket.
1359 static ssize_t vnc_client_read_plain(VncState *vs)
1361 ssize_t ret;
1362 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1363 vs->input.buffer, vs->input.capacity, vs->input.offset);
1364 buffer_reserve(&vs->input, 4096);
1365 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1366 if (!ret)
1367 return 0;
1368 vs->input.offset += ret;
1369 return ret;
1372 static void vnc_jobs_bh(void *opaque)
1374 VncState *vs = opaque;
1376 vnc_jobs_consume_buffer(vs);
1380 * First function called whenever there is more data to be read from
1381 * the client socket. Will delegate actual work according to whether
1382 * SASL SSF layers are enabled (thus requiring decryption calls)
1383 * Returns 0 on success, -1 if client disconnected
1385 static int vnc_client_read(VncState *vs)
1387 ssize_t ret;
1389 #ifdef CONFIG_VNC_SASL
1390 if (vs->sasl.conn && vs->sasl.runSSF)
1391 ret = vnc_client_read_sasl(vs);
1392 else
1393 #endif /* CONFIG_VNC_SASL */
1394 ret = vnc_client_read_plain(vs);
1395 if (!ret) {
1396 if (vs->disconnecting) {
1397 vnc_disconnect_finish(vs);
1398 return -1;
1400 return 0;
1403 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1404 size_t len = vs->read_handler_expect;
1405 int ret;
1407 ret = vs->read_handler(vs, vs->input.buffer, len);
1408 if (vs->disconnecting) {
1409 vnc_disconnect_finish(vs);
1410 return -1;
1413 if (!ret) {
1414 buffer_advance(&vs->input, len);
1415 } else {
1416 vs->read_handler_expect = ret;
1419 return 0;
1422 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1423 GIOCondition condition, void *opaque)
1425 VncState *vs = opaque;
1426 if (condition & G_IO_IN) {
1427 if (vnc_client_read(vs) < 0) {
1428 return TRUE;
1431 if (condition & G_IO_OUT) {
1432 vnc_client_write(vs);
1434 return TRUE;
1438 void vnc_write(VncState *vs, const void *data, size_t len)
1440 buffer_reserve(&vs->output, len);
1442 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1443 if (vs->ioc_tag) {
1444 g_source_remove(vs->ioc_tag);
1446 vs->ioc_tag = qio_channel_add_watch(
1447 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1450 buffer_append(&vs->output, data, len);
1453 void vnc_write_s32(VncState *vs, int32_t value)
1455 vnc_write_u32(vs, *(uint32_t *)&value);
1458 void vnc_write_u32(VncState *vs, uint32_t value)
1460 uint8_t buf[4];
1462 buf[0] = (value >> 24) & 0xFF;
1463 buf[1] = (value >> 16) & 0xFF;
1464 buf[2] = (value >> 8) & 0xFF;
1465 buf[3] = value & 0xFF;
1467 vnc_write(vs, buf, 4);
1470 void vnc_write_u16(VncState *vs, uint16_t value)
1472 uint8_t buf[2];
1474 buf[0] = (value >> 8) & 0xFF;
1475 buf[1] = value & 0xFF;
1477 vnc_write(vs, buf, 2);
1480 void vnc_write_u8(VncState *vs, uint8_t value)
1482 vnc_write(vs, (char *)&value, 1);
1485 void vnc_flush(VncState *vs)
1487 vnc_lock_output(vs);
1488 if (vs->ioc != NULL && vs->output.offset) {
1489 vnc_client_write_locked(vs);
1491 vnc_unlock_output(vs);
1494 static uint8_t read_u8(uint8_t *data, size_t offset)
1496 return data[offset];
1499 static uint16_t read_u16(uint8_t *data, size_t offset)
1501 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1504 static int32_t read_s32(uint8_t *data, size_t offset)
1506 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1507 (data[offset + 2] << 8) | data[offset + 3]);
1510 uint32_t read_u32(uint8_t *data, size_t offset)
1512 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1513 (data[offset + 2] << 8) | data[offset + 3]);
1516 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1520 static void check_pointer_type_change(Notifier *notifier, void *data)
1522 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1523 int absolute = qemu_input_is_absolute();
1525 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1526 vnc_lock_output(vs);
1527 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1528 vnc_write_u8(vs, 0);
1529 vnc_write_u16(vs, 1);
1530 vnc_framebuffer_update(vs, absolute, 0,
1531 pixman_image_get_width(vs->vd->server),
1532 pixman_image_get_height(vs->vd->server),
1533 VNC_ENCODING_POINTER_TYPE_CHANGE);
1534 vnc_unlock_output(vs);
1535 vnc_flush(vs);
1537 vs->absolute = absolute;
1540 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1542 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1543 [INPUT_BUTTON_LEFT] = 0x01,
1544 [INPUT_BUTTON_MIDDLE] = 0x02,
1545 [INPUT_BUTTON_RIGHT] = 0x04,
1546 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1547 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1549 QemuConsole *con = vs->vd->dcl.con;
1550 int width = pixman_image_get_width(vs->vd->server);
1551 int height = pixman_image_get_height(vs->vd->server);
1553 if (vs->last_bmask != button_mask) {
1554 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1555 vs->last_bmask = button_mask;
1558 if (vs->absolute) {
1559 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1560 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1561 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1562 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1563 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1564 } else {
1565 if (vs->last_x != -1) {
1566 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1567 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1569 vs->last_x = x;
1570 vs->last_y = y;
1572 qemu_input_event_sync();
1575 static void reset_keys(VncState *vs)
1577 int i;
1578 for(i = 0; i < 256; i++) {
1579 if (vs->modifiers_state[i]) {
1580 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1581 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1582 vs->modifiers_state[i] = 0;
1587 static void press_key(VncState *vs, int keysym)
1589 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1590 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1591 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1592 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1593 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1596 static void vnc_led_state_change(VncState *vs)
1598 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1599 return;
1602 vnc_lock_output(vs);
1603 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1604 vnc_write_u8(vs, 0);
1605 vnc_write_u16(vs, 1);
1606 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1607 vnc_write_u8(vs, vs->vd->ledstate);
1608 vnc_unlock_output(vs);
1609 vnc_flush(vs);
1612 static void kbd_leds(void *opaque, int ledstate)
1614 VncDisplay *vd = opaque;
1615 VncState *client;
1617 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1618 (ledstate & QEMU_NUM_LOCK_LED),
1619 (ledstate & QEMU_SCROLL_LOCK_LED));
1621 if (ledstate == vd->ledstate) {
1622 return;
1625 vd->ledstate = ledstate;
1627 QTAILQ_FOREACH(client, &vd->clients, next) {
1628 vnc_led_state_change(client);
1632 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1634 /* QEMU console switch */
1635 switch(keycode) {
1636 case 0x2a: /* Left Shift */
1637 case 0x36: /* Right Shift */
1638 case 0x1d: /* Left CTRL */
1639 case 0x9d: /* Right CTRL */
1640 case 0x38: /* Left ALT */
1641 case 0xb8: /* Right ALT */
1642 if (down)
1643 vs->modifiers_state[keycode] = 1;
1644 else
1645 vs->modifiers_state[keycode] = 0;
1646 break;
1647 case 0x02 ... 0x0a: /* '1' to '9' keys */
1648 if (vs->vd->dcl.con == NULL &&
1649 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1650 /* Reset the modifiers sent to the current console */
1651 reset_keys(vs);
1652 console_select(keycode - 0x02);
1653 return;
1655 break;
1656 case 0x3a: /* CapsLock */
1657 case 0x45: /* NumLock */
1658 if (down)
1659 vs->modifiers_state[keycode] ^= 1;
1660 break;
1663 /* Turn off the lock state sync logic if the client support the led
1664 state extension.
1666 if (down && vs->vd->lock_key_sync &&
1667 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1668 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1669 /* If the numlock state needs to change then simulate an additional
1670 keypress before sending this one. This will happen if the user
1671 toggles numlock away from the VNC window.
1673 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1674 if (!vs->modifiers_state[0x45]) {
1675 trace_vnc_key_sync_numlock(true);
1676 vs->modifiers_state[0x45] = 1;
1677 press_key(vs, 0xff7f);
1679 } else {
1680 if (vs->modifiers_state[0x45]) {
1681 trace_vnc_key_sync_numlock(false);
1682 vs->modifiers_state[0x45] = 0;
1683 press_key(vs, 0xff7f);
1688 if (down && vs->vd->lock_key_sync &&
1689 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1690 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1691 /* If the capslock state needs to change then simulate an additional
1692 keypress before sending this one. This will happen if the user
1693 toggles capslock away from the VNC window.
1695 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1696 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1697 int capslock = !!(vs->modifiers_state[0x3a]);
1698 if (capslock) {
1699 if (uppercase == shift) {
1700 trace_vnc_key_sync_capslock(false);
1701 vs->modifiers_state[0x3a] = 0;
1702 press_key(vs, 0xffe5);
1704 } else {
1705 if (uppercase != shift) {
1706 trace_vnc_key_sync_capslock(true);
1707 vs->modifiers_state[0x3a] = 1;
1708 press_key(vs, 0xffe5);
1713 if (qemu_console_is_graphic(NULL)) {
1714 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1715 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1716 } else {
1717 bool numlock = vs->modifiers_state[0x45];
1718 bool control = (vs->modifiers_state[0x1d] ||
1719 vs->modifiers_state[0x9d]);
1720 /* QEMU console emulation */
1721 if (down) {
1722 switch (keycode) {
1723 case 0x2a: /* Left Shift */
1724 case 0x36: /* Right Shift */
1725 case 0x1d: /* Left CTRL */
1726 case 0x9d: /* Right CTRL */
1727 case 0x38: /* Left ALT */
1728 case 0xb8: /* Right ALT */
1729 break;
1730 case 0xc8:
1731 kbd_put_keysym(QEMU_KEY_UP);
1732 break;
1733 case 0xd0:
1734 kbd_put_keysym(QEMU_KEY_DOWN);
1735 break;
1736 case 0xcb:
1737 kbd_put_keysym(QEMU_KEY_LEFT);
1738 break;
1739 case 0xcd:
1740 kbd_put_keysym(QEMU_KEY_RIGHT);
1741 break;
1742 case 0xd3:
1743 kbd_put_keysym(QEMU_KEY_DELETE);
1744 break;
1745 case 0xc7:
1746 kbd_put_keysym(QEMU_KEY_HOME);
1747 break;
1748 case 0xcf:
1749 kbd_put_keysym(QEMU_KEY_END);
1750 break;
1751 case 0xc9:
1752 kbd_put_keysym(QEMU_KEY_PAGEUP);
1753 break;
1754 case 0xd1:
1755 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1756 break;
1758 case 0x47:
1759 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1760 break;
1761 case 0x48:
1762 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1763 break;
1764 case 0x49:
1765 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1766 break;
1767 case 0x4b:
1768 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1769 break;
1770 case 0x4c:
1771 kbd_put_keysym('5');
1772 break;
1773 case 0x4d:
1774 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1775 break;
1776 case 0x4f:
1777 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1778 break;
1779 case 0x50:
1780 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1781 break;
1782 case 0x51:
1783 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1784 break;
1785 case 0x52:
1786 kbd_put_keysym('0');
1787 break;
1788 case 0x53:
1789 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1790 break;
1792 case 0xb5:
1793 kbd_put_keysym('/');
1794 break;
1795 case 0x37:
1796 kbd_put_keysym('*');
1797 break;
1798 case 0x4a:
1799 kbd_put_keysym('-');
1800 break;
1801 case 0x4e:
1802 kbd_put_keysym('+');
1803 break;
1804 case 0x9c:
1805 kbd_put_keysym('\n');
1806 break;
1808 default:
1809 if (control) {
1810 kbd_put_keysym(sym & 0x1f);
1811 } else {
1812 kbd_put_keysym(sym);
1814 break;
1820 static void vnc_release_modifiers(VncState *vs)
1822 static const int keycodes[] = {
1823 /* shift, control, alt keys, both left & right */
1824 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1826 int i, keycode;
1828 if (!qemu_console_is_graphic(NULL)) {
1829 return;
1831 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1832 keycode = keycodes[i];
1833 if (!vs->modifiers_state[keycode]) {
1834 continue;
1836 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1837 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1841 static const char *code2name(int keycode)
1843 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1846 static void key_event(VncState *vs, int down, uint32_t sym)
1848 int keycode;
1849 int lsym = sym;
1851 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1852 lsym = lsym - 'A' + 'a';
1855 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1856 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1857 do_key_event(vs, down, keycode, sym);
1860 static void ext_key_event(VncState *vs, int down,
1861 uint32_t sym, uint16_t keycode)
1863 /* if the user specifies a keyboard layout, always use it */
1864 if (keyboard_layout) {
1865 key_event(vs, down, sym);
1866 } else {
1867 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1868 do_key_event(vs, down, keycode, sym);
1872 static void framebuffer_update_request(VncState *vs, int incremental,
1873 int x, int y, int w, int h)
1875 vs->need_update = 1;
1877 if (incremental) {
1878 return;
1881 vs->force_update = 1;
1882 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1885 static void send_ext_key_event_ack(VncState *vs)
1887 vnc_lock_output(vs);
1888 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1889 vnc_write_u8(vs, 0);
1890 vnc_write_u16(vs, 1);
1891 vnc_framebuffer_update(vs, 0, 0,
1892 pixman_image_get_width(vs->vd->server),
1893 pixman_image_get_height(vs->vd->server),
1894 VNC_ENCODING_EXT_KEY_EVENT);
1895 vnc_unlock_output(vs);
1896 vnc_flush(vs);
1899 static void send_ext_audio_ack(VncState *vs)
1901 vnc_lock_output(vs);
1902 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1903 vnc_write_u8(vs, 0);
1904 vnc_write_u16(vs, 1);
1905 vnc_framebuffer_update(vs, 0, 0,
1906 pixman_image_get_width(vs->vd->server),
1907 pixman_image_get_height(vs->vd->server),
1908 VNC_ENCODING_AUDIO);
1909 vnc_unlock_output(vs);
1910 vnc_flush(vs);
1913 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1915 int i;
1916 unsigned int enc = 0;
1918 vs->features = 0;
1919 vs->vnc_encoding = 0;
1920 vs->tight.compression = 9;
1921 vs->tight.quality = -1; /* Lossless by default */
1922 vs->absolute = -1;
1925 * Start from the end because the encodings are sent in order of preference.
1926 * This way the preferred encoding (first encoding defined in the array)
1927 * will be set at the end of the loop.
1929 for (i = n_encodings - 1; i >= 0; i--) {
1930 enc = encodings[i];
1931 switch (enc) {
1932 case VNC_ENCODING_RAW:
1933 vs->vnc_encoding = enc;
1934 break;
1935 case VNC_ENCODING_COPYRECT:
1936 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1937 break;
1938 case VNC_ENCODING_HEXTILE:
1939 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1940 vs->vnc_encoding = enc;
1941 break;
1942 case VNC_ENCODING_TIGHT:
1943 vs->features |= VNC_FEATURE_TIGHT_MASK;
1944 vs->vnc_encoding = enc;
1945 break;
1946 #ifdef CONFIG_VNC_PNG
1947 case VNC_ENCODING_TIGHT_PNG:
1948 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
1949 vs->vnc_encoding = enc;
1950 break;
1951 #endif
1952 case VNC_ENCODING_ZLIB:
1953 vs->features |= VNC_FEATURE_ZLIB_MASK;
1954 vs->vnc_encoding = enc;
1955 break;
1956 case VNC_ENCODING_ZRLE:
1957 vs->features |= VNC_FEATURE_ZRLE_MASK;
1958 vs->vnc_encoding = enc;
1959 break;
1960 case VNC_ENCODING_ZYWRLE:
1961 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
1962 vs->vnc_encoding = enc;
1963 break;
1964 case VNC_ENCODING_DESKTOPRESIZE:
1965 vs->features |= VNC_FEATURE_RESIZE_MASK;
1966 break;
1967 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1968 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1969 break;
1970 case VNC_ENCODING_RICH_CURSOR:
1971 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
1972 if (vs->vd->cursor) {
1973 vnc_cursor_define(vs);
1975 break;
1976 case VNC_ENCODING_EXT_KEY_EVENT:
1977 send_ext_key_event_ack(vs);
1978 break;
1979 case VNC_ENCODING_AUDIO:
1980 send_ext_audio_ack(vs);
1981 break;
1982 case VNC_ENCODING_WMVi:
1983 vs->features |= VNC_FEATURE_WMVI_MASK;
1984 break;
1985 case VNC_ENCODING_LED_STATE:
1986 vs->features |= VNC_FEATURE_LED_STATE_MASK;
1987 break;
1988 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1989 vs->tight.compression = (enc & 0x0F);
1990 break;
1991 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1992 if (vs->vd->lossy) {
1993 vs->tight.quality = (enc & 0x0F);
1995 break;
1996 default:
1997 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1998 break;
2001 vnc_desktop_resize(vs);
2002 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2003 vnc_led_state_change(vs);
2006 static void set_pixel_conversion(VncState *vs)
2008 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2010 if (fmt == VNC_SERVER_FB_FORMAT) {
2011 vs->write_pixels = vnc_write_pixels_copy;
2012 vnc_hextile_set_pixel_conversion(vs, 0);
2013 } else {
2014 vs->write_pixels = vnc_write_pixels_generic;
2015 vnc_hextile_set_pixel_conversion(vs, 1);
2019 static void send_color_map(VncState *vs)
2021 int i;
2023 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2024 vnc_write_u8(vs, 0); /* padding */
2025 vnc_write_u16(vs, 0); /* first color */
2026 vnc_write_u16(vs, 256); /* # of colors */
2028 for (i = 0; i < 256; i++) {
2029 PixelFormat *pf = &vs->client_pf;
2031 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2032 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2033 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2037 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2038 int big_endian_flag, int true_color_flag,
2039 int red_max, int green_max, int blue_max,
2040 int red_shift, int green_shift, int blue_shift)
2042 if (!true_color_flag) {
2043 /* Expose a reasonable default 256 color map */
2044 bits_per_pixel = 8;
2045 red_max = 7;
2046 green_max = 7;
2047 blue_max = 3;
2048 red_shift = 0;
2049 green_shift = 3;
2050 blue_shift = 6;
2053 switch (bits_per_pixel) {
2054 case 8:
2055 case 16:
2056 case 32:
2057 break;
2058 default:
2059 vnc_client_error(vs);
2060 return;
2063 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2064 vs->client_pf.rbits = hweight_long(red_max);
2065 vs->client_pf.rshift = red_shift;
2066 vs->client_pf.rmask = red_max << red_shift;
2067 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2068 vs->client_pf.gbits = hweight_long(green_max);
2069 vs->client_pf.gshift = green_shift;
2070 vs->client_pf.gmask = green_max << green_shift;
2071 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2072 vs->client_pf.bbits = hweight_long(blue_max);
2073 vs->client_pf.bshift = blue_shift;
2074 vs->client_pf.bmask = blue_max << blue_shift;
2075 vs->client_pf.bits_per_pixel = bits_per_pixel;
2076 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2077 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2078 vs->client_be = big_endian_flag;
2080 if (!true_color_flag) {
2081 send_color_map(vs);
2084 set_pixel_conversion(vs);
2086 graphic_hw_invalidate(vs->vd->dcl.con);
2087 graphic_hw_update(vs->vd->dcl.con);
2090 static void pixel_format_message (VncState *vs) {
2091 char pad[3] = { 0, 0, 0 };
2093 vs->client_pf = qemu_default_pixelformat(32);
2095 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2096 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2098 #ifdef HOST_WORDS_BIGENDIAN
2099 vnc_write_u8(vs, 1); /* big-endian-flag */
2100 #else
2101 vnc_write_u8(vs, 0); /* big-endian-flag */
2102 #endif
2103 vnc_write_u8(vs, 1); /* true-color-flag */
2104 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2105 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2106 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2107 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2108 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2109 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2110 vnc_write(vs, pad, 3); /* padding */
2112 vnc_hextile_set_pixel_conversion(vs, 0);
2113 vs->write_pixels = vnc_write_pixels_copy;
2116 static void vnc_colordepth(VncState *vs)
2118 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2119 /* Sending a WMVi message to notify the client*/
2120 vnc_lock_output(vs);
2121 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2122 vnc_write_u8(vs, 0);
2123 vnc_write_u16(vs, 1); /* number of rects */
2124 vnc_framebuffer_update(vs, 0, 0,
2125 pixman_image_get_width(vs->vd->server),
2126 pixman_image_get_height(vs->vd->server),
2127 VNC_ENCODING_WMVi);
2128 pixel_format_message(vs);
2129 vnc_unlock_output(vs);
2130 vnc_flush(vs);
2131 } else {
2132 set_pixel_conversion(vs);
2136 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2138 int i;
2139 uint16_t limit;
2140 VncDisplay *vd = vs->vd;
2142 if (data[0] > 3) {
2143 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2146 switch (data[0]) {
2147 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2148 if (len == 1)
2149 return 20;
2151 set_pixel_format(vs, read_u8(data, 4),
2152 read_u8(data, 6), read_u8(data, 7),
2153 read_u16(data, 8), read_u16(data, 10),
2154 read_u16(data, 12), read_u8(data, 14),
2155 read_u8(data, 15), read_u8(data, 16));
2156 break;
2157 case VNC_MSG_CLIENT_SET_ENCODINGS:
2158 if (len == 1)
2159 return 4;
2161 if (len == 4) {
2162 limit = read_u16(data, 2);
2163 if (limit > 0)
2164 return 4 + (limit * 4);
2165 } else
2166 limit = read_u16(data, 2);
2168 for (i = 0; i < limit; i++) {
2169 int32_t val = read_s32(data, 4 + (i * 4));
2170 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2173 set_encodings(vs, (int32_t *)(data + 4), limit);
2174 break;
2175 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2176 if (len == 1)
2177 return 10;
2179 framebuffer_update_request(vs,
2180 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2181 read_u16(data, 6), read_u16(data, 8));
2182 break;
2183 case VNC_MSG_CLIENT_KEY_EVENT:
2184 if (len == 1)
2185 return 8;
2187 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2188 break;
2189 case VNC_MSG_CLIENT_POINTER_EVENT:
2190 if (len == 1)
2191 return 6;
2193 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2194 break;
2195 case VNC_MSG_CLIENT_CUT_TEXT:
2196 if (len == 1) {
2197 return 8;
2199 if (len == 8) {
2200 uint32_t dlen = read_u32(data, 4);
2201 if (dlen > (1 << 20)) {
2202 error_report("vnc: client_cut_text msg payload has %u bytes"
2203 " which exceeds our limit of 1MB.", dlen);
2204 vnc_client_error(vs);
2205 break;
2207 if (dlen > 0) {
2208 return 8 + dlen;
2212 client_cut_text(vs, read_u32(data, 4), data + 8);
2213 break;
2214 case VNC_MSG_CLIENT_QEMU:
2215 if (len == 1)
2216 return 2;
2218 switch (read_u8(data, 1)) {
2219 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2220 if (len == 2)
2221 return 12;
2223 ext_key_event(vs, read_u16(data, 2),
2224 read_u32(data, 4), read_u32(data, 8));
2225 break;
2226 case VNC_MSG_CLIENT_QEMU_AUDIO:
2227 if (len == 2)
2228 return 4;
2230 switch (read_u16 (data, 2)) {
2231 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2232 audio_add(vs);
2233 break;
2234 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2235 audio_del(vs);
2236 break;
2237 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2238 if (len == 4)
2239 return 10;
2240 switch (read_u8(data, 4)) {
2241 case 0: vs->as.fmt = AUD_FMT_U8; break;
2242 case 1: vs->as.fmt = AUD_FMT_S8; break;
2243 case 2: vs->as.fmt = AUD_FMT_U16; break;
2244 case 3: vs->as.fmt = AUD_FMT_S16; break;
2245 case 4: vs->as.fmt = AUD_FMT_U32; break;
2246 case 5: vs->as.fmt = AUD_FMT_S32; break;
2247 default:
2248 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2249 vnc_client_error(vs);
2250 break;
2252 vs->as.nchannels = read_u8(data, 5);
2253 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2254 VNC_DEBUG("Invalid audio channel coount %d\n",
2255 read_u8(data, 5));
2256 vnc_client_error(vs);
2257 break;
2259 vs->as.freq = read_u32(data, 6);
2260 break;
2261 default:
2262 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2263 vnc_client_error(vs);
2264 break;
2266 break;
2268 default:
2269 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2270 vnc_client_error(vs);
2271 break;
2273 break;
2274 default:
2275 VNC_DEBUG("Msg: %d\n", data[0]);
2276 vnc_client_error(vs);
2277 break;
2280 vnc_read_when(vs, protocol_client_msg, 1);
2281 return 0;
2284 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2286 char buf[1024];
2287 VncShareMode mode;
2288 int size;
2290 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2291 switch (vs->vd->share_policy) {
2292 case VNC_SHARE_POLICY_IGNORE:
2294 * Ignore the shared flag. Nothing to do here.
2296 * Doesn't conform to the rfb spec but is traditional qemu
2297 * behavior, thus left here as option for compatibility
2298 * reasons.
2300 break;
2301 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2303 * Policy: Allow clients ask for exclusive access.
2305 * Implementation: When a client asks for exclusive access,
2306 * disconnect all others. Shared connects are allowed as long
2307 * as no exclusive connection exists.
2309 * This is how the rfb spec suggests to handle the shared flag.
2311 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2312 VncState *client;
2313 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2314 if (vs == client) {
2315 continue;
2317 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2318 client->share_mode != VNC_SHARE_MODE_SHARED) {
2319 continue;
2321 vnc_disconnect_start(client);
2324 if (mode == VNC_SHARE_MODE_SHARED) {
2325 if (vs->vd->num_exclusive > 0) {
2326 vnc_disconnect_start(vs);
2327 return 0;
2330 break;
2331 case VNC_SHARE_POLICY_FORCE_SHARED:
2333 * Policy: Shared connects only.
2334 * Implementation: Disallow clients asking for exclusive access.
2336 * Useful for shared desktop sessions where you don't want
2337 * someone forgetting to say -shared when running the vnc
2338 * client disconnect everybody else.
2340 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2341 vnc_disconnect_start(vs);
2342 return 0;
2344 break;
2346 vnc_set_share_mode(vs, mode);
2348 if (vs->vd->num_shared > vs->vd->connections_limit) {
2349 vnc_disconnect_start(vs);
2350 return 0;
2353 vs->client_width = pixman_image_get_width(vs->vd->server);
2354 vs->client_height = pixman_image_get_height(vs->vd->server);
2355 vnc_write_u16(vs, vs->client_width);
2356 vnc_write_u16(vs, vs->client_height);
2358 pixel_format_message(vs);
2360 if (qemu_name) {
2361 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2362 if (size > sizeof(buf)) {
2363 size = sizeof(buf);
2365 } else {
2366 size = snprintf(buf, sizeof(buf), "QEMU");
2369 vnc_write_u32(vs, size);
2370 vnc_write(vs, buf, size);
2371 vnc_flush(vs);
2373 vnc_client_cache_auth(vs);
2374 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2376 vnc_read_when(vs, protocol_client_msg, 1);
2378 return 0;
2381 void start_client_init(VncState *vs)
2383 vnc_read_when(vs, protocol_client_init, 1);
2386 static void make_challenge(VncState *vs)
2388 int i;
2390 srand(time(NULL)+getpid()+getpid()*987654+rand());
2392 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2393 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2396 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2398 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2399 size_t i, pwlen;
2400 unsigned char key[8];
2401 time_t now = time(NULL);
2402 QCryptoCipher *cipher = NULL;
2403 Error *err = NULL;
2405 if (!vs->vd->password) {
2406 VNC_DEBUG("No password configured on server");
2407 goto reject;
2409 if (vs->vd->expires < now) {
2410 VNC_DEBUG("Password is expired");
2411 goto reject;
2414 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2416 /* Calculate the expected challenge response */
2417 pwlen = strlen(vs->vd->password);
2418 for (i=0; i<sizeof(key); i++)
2419 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2421 cipher = qcrypto_cipher_new(
2422 QCRYPTO_CIPHER_ALG_DES_RFB,
2423 QCRYPTO_CIPHER_MODE_ECB,
2424 key, G_N_ELEMENTS(key),
2425 &err);
2426 if (!cipher) {
2427 VNC_DEBUG("Cannot initialize cipher %s",
2428 error_get_pretty(err));
2429 error_free(err);
2430 goto reject;
2433 if (qcrypto_cipher_encrypt(cipher,
2434 vs->challenge,
2435 response,
2436 VNC_AUTH_CHALLENGE_SIZE,
2437 &err) < 0) {
2438 VNC_DEBUG("Cannot encrypt challenge %s",
2439 error_get_pretty(err));
2440 error_free(err);
2441 goto reject;
2444 /* Compare expected vs actual challenge response */
2445 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2446 VNC_DEBUG("Client challenge response did not match\n");
2447 goto reject;
2448 } else {
2449 VNC_DEBUG("Accepting VNC challenge response\n");
2450 vnc_write_u32(vs, 0); /* Accept auth */
2451 vnc_flush(vs);
2453 start_client_init(vs);
2456 qcrypto_cipher_free(cipher);
2457 return 0;
2459 reject:
2460 vnc_write_u32(vs, 1); /* Reject auth */
2461 if (vs->minor >= 8) {
2462 static const char err[] = "Authentication failed";
2463 vnc_write_u32(vs, sizeof(err));
2464 vnc_write(vs, err, sizeof(err));
2466 vnc_flush(vs);
2467 vnc_client_error(vs);
2468 qcrypto_cipher_free(cipher);
2469 return 0;
2472 void start_auth_vnc(VncState *vs)
2474 make_challenge(vs);
2475 /* Send client a 'random' challenge */
2476 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2477 vnc_flush(vs);
2479 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2483 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2485 /* We only advertise 1 auth scheme at a time, so client
2486 * must pick the one we sent. Verify this */
2487 if (data[0] != vs->auth) { /* Reject auth */
2488 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2489 vnc_write_u32(vs, 1);
2490 if (vs->minor >= 8) {
2491 static const char err[] = "Authentication failed";
2492 vnc_write_u32(vs, sizeof(err));
2493 vnc_write(vs, err, sizeof(err));
2495 vnc_client_error(vs);
2496 } else { /* Accept requested auth */
2497 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2498 switch (vs->auth) {
2499 case VNC_AUTH_NONE:
2500 VNC_DEBUG("Accept auth none\n");
2501 if (vs->minor >= 8) {
2502 vnc_write_u32(vs, 0); /* Accept auth completion */
2503 vnc_flush(vs);
2505 start_client_init(vs);
2506 break;
2508 case VNC_AUTH_VNC:
2509 VNC_DEBUG("Start VNC auth\n");
2510 start_auth_vnc(vs);
2511 break;
2513 case VNC_AUTH_VENCRYPT:
2514 VNC_DEBUG("Accept VeNCrypt auth\n");
2515 start_auth_vencrypt(vs);
2516 break;
2518 #ifdef CONFIG_VNC_SASL
2519 case VNC_AUTH_SASL:
2520 VNC_DEBUG("Accept SASL auth\n");
2521 start_auth_sasl(vs);
2522 break;
2523 #endif /* CONFIG_VNC_SASL */
2525 default: /* Should not be possible, but just in case */
2526 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2527 vnc_write_u8(vs, 1);
2528 if (vs->minor >= 8) {
2529 static const char err[] = "Authentication failed";
2530 vnc_write_u32(vs, sizeof(err));
2531 vnc_write(vs, err, sizeof(err));
2533 vnc_client_error(vs);
2536 return 0;
2539 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2541 char local[13];
2543 memcpy(local, version, 12);
2544 local[12] = 0;
2546 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2547 VNC_DEBUG("Malformed protocol version %s\n", local);
2548 vnc_client_error(vs);
2549 return 0;
2551 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2552 if (vs->major != 3 ||
2553 (vs->minor != 3 &&
2554 vs->minor != 4 &&
2555 vs->minor != 5 &&
2556 vs->minor != 7 &&
2557 vs->minor != 8)) {
2558 VNC_DEBUG("Unsupported client version\n");
2559 vnc_write_u32(vs, VNC_AUTH_INVALID);
2560 vnc_flush(vs);
2561 vnc_client_error(vs);
2562 return 0;
2564 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2565 * as equivalent to v3.3 by servers
2567 if (vs->minor == 4 || vs->minor == 5)
2568 vs->minor = 3;
2570 if (vs->minor == 3) {
2571 if (vs->auth == VNC_AUTH_NONE) {
2572 VNC_DEBUG("Tell client auth none\n");
2573 vnc_write_u32(vs, vs->auth);
2574 vnc_flush(vs);
2575 start_client_init(vs);
2576 } else if (vs->auth == VNC_AUTH_VNC) {
2577 VNC_DEBUG("Tell client VNC auth\n");
2578 vnc_write_u32(vs, vs->auth);
2579 vnc_flush(vs);
2580 start_auth_vnc(vs);
2581 } else {
2582 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2583 vnc_write_u32(vs, VNC_AUTH_INVALID);
2584 vnc_flush(vs);
2585 vnc_client_error(vs);
2587 } else {
2588 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2589 vnc_write_u8(vs, 1); /* num auth */
2590 vnc_write_u8(vs, vs->auth);
2591 vnc_read_when(vs, protocol_client_auth, 1);
2592 vnc_flush(vs);
2595 return 0;
2598 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2600 struct VncSurface *vs = &vd->guest;
2602 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2605 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2607 int i, j;
2609 w = (x + w) / VNC_STAT_RECT;
2610 h = (y + h) / VNC_STAT_RECT;
2611 x /= VNC_STAT_RECT;
2612 y /= VNC_STAT_RECT;
2614 for (j = y; j <= h; j++) {
2615 for (i = x; i <= w; i++) {
2616 vs->lossy_rect[j][i] = 1;
2621 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2623 VncState *vs;
2624 int sty = y / VNC_STAT_RECT;
2625 int stx = x / VNC_STAT_RECT;
2626 int has_dirty = 0;
2628 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2629 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2631 QTAILQ_FOREACH(vs, &vd->clients, next) {
2632 int j;
2634 /* kernel send buffers are full -> refresh later */
2635 if (vs->output.offset) {
2636 continue;
2639 if (!vs->lossy_rect[sty][stx]) {
2640 continue;
2643 vs->lossy_rect[sty][stx] = 0;
2644 for (j = 0; j < VNC_STAT_RECT; ++j) {
2645 bitmap_set(vs->dirty[y + j],
2646 x / VNC_DIRTY_PIXELS_PER_BIT,
2647 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2649 has_dirty++;
2652 return has_dirty;
2655 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2657 int width = MIN(pixman_image_get_width(vd->guest.fb),
2658 pixman_image_get_width(vd->server));
2659 int height = MIN(pixman_image_get_height(vd->guest.fb),
2660 pixman_image_get_height(vd->server));
2661 int x, y;
2662 struct timeval res;
2663 int has_dirty = 0;
2665 for (y = 0; y < height; y += VNC_STAT_RECT) {
2666 for (x = 0; x < width; x += VNC_STAT_RECT) {
2667 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2669 rect->updated = false;
2673 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2675 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2676 return has_dirty;
2678 vd->guest.last_freq_check = *tv;
2680 for (y = 0; y < height; y += VNC_STAT_RECT) {
2681 for (x = 0; x < width; x += VNC_STAT_RECT) {
2682 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2683 int count = ARRAY_SIZE(rect->times);
2684 struct timeval min, max;
2686 if (!timerisset(&rect->times[count - 1])) {
2687 continue ;
2690 max = rect->times[(rect->idx + count - 1) % count];
2691 qemu_timersub(tv, &max, &res);
2693 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2694 rect->freq = 0;
2695 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2696 memset(rect->times, 0, sizeof (rect->times));
2697 continue ;
2700 min = rect->times[rect->idx];
2701 max = rect->times[(rect->idx + count - 1) % count];
2702 qemu_timersub(&max, &min, &res);
2704 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2705 rect->freq /= count;
2706 rect->freq = 1. / rect->freq;
2709 return has_dirty;
2712 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2714 int i, j;
2715 double total = 0;
2716 int num = 0;
2718 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2719 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2721 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2722 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2723 total += vnc_stat_rect(vs->vd, i, j)->freq;
2724 num++;
2728 if (num) {
2729 return total / num;
2730 } else {
2731 return 0;
2735 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2737 VncRectStat *rect;
2739 rect = vnc_stat_rect(vd, x, y);
2740 if (rect->updated) {
2741 return ;
2743 rect->times[rect->idx] = *tv;
2744 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2745 rect->updated = true;
2748 static int vnc_refresh_server_surface(VncDisplay *vd)
2750 int width = MIN(pixman_image_get_width(vd->guest.fb),
2751 pixman_image_get_width(vd->server));
2752 int height = MIN(pixman_image_get_height(vd->guest.fb),
2753 pixman_image_get_height(vd->server));
2754 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2755 uint8_t *guest_row0 = NULL, *server_row0;
2756 VncState *vs;
2757 int has_dirty = 0;
2758 pixman_image_t *tmpbuf = NULL;
2760 struct timeval tv = { 0, 0 };
2762 if (!vd->non_adaptive) {
2763 gettimeofday(&tv, NULL);
2764 has_dirty = vnc_update_stats(vd, &tv);
2768 * Walk through the guest dirty map.
2769 * Check and copy modified bits from guest to server surface.
2770 * Update server dirty map.
2772 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2773 server_stride = guest_stride = guest_ll =
2774 pixman_image_get_stride(vd->server);
2775 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2776 server_stride);
2777 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2778 int width = pixman_image_get_width(vd->server);
2779 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2780 } else {
2781 int guest_bpp =
2782 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2783 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2784 guest_stride = pixman_image_get_stride(vd->guest.fb);
2785 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2787 line_bytes = MIN(server_stride, guest_ll);
2789 for (;;) {
2790 int x;
2791 uint8_t *guest_ptr, *server_ptr;
2792 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2793 height * VNC_DIRTY_BPL(&vd->guest),
2794 y * VNC_DIRTY_BPL(&vd->guest));
2795 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2796 /* no more dirty bits */
2797 break;
2799 y = offset / VNC_DIRTY_BPL(&vd->guest);
2800 x = offset % VNC_DIRTY_BPL(&vd->guest);
2802 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2804 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2805 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2806 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2807 } else {
2808 guest_ptr = guest_row0 + y * guest_stride;
2810 guest_ptr += x * cmp_bytes;
2812 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2813 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2814 int _cmp_bytes = cmp_bytes;
2815 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2816 continue;
2818 if ((x + 1) * cmp_bytes > line_bytes) {
2819 _cmp_bytes = line_bytes - x * cmp_bytes;
2821 assert(_cmp_bytes >= 0);
2822 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2823 continue;
2825 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2826 if (!vd->non_adaptive) {
2827 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2828 y, &tv);
2830 QTAILQ_FOREACH(vs, &vd->clients, next) {
2831 set_bit(x, vs->dirty[y]);
2833 has_dirty++;
2836 y++;
2838 qemu_pixman_image_unref(tmpbuf);
2839 return has_dirty;
2842 static void vnc_refresh(DisplayChangeListener *dcl)
2844 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2845 VncState *vs, *vn;
2846 int has_dirty, rects = 0;
2848 if (QTAILQ_EMPTY(&vd->clients)) {
2849 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2850 return;
2853 graphic_hw_update(vd->dcl.con);
2855 if (vnc_trylock_display(vd)) {
2856 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2857 return;
2860 has_dirty = vnc_refresh_server_surface(vd);
2861 vnc_unlock_display(vd);
2863 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2864 rects += vnc_update_client(vs, has_dirty, false);
2865 /* vs might be free()ed here */
2868 if (has_dirty && rects) {
2869 vd->dcl.update_interval /= 2;
2870 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2871 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2873 } else {
2874 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2875 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2876 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2881 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2882 bool skipauth, bool websocket)
2884 VncState *vs = g_new0(VncState, 1);
2885 bool first_client = QTAILQ_EMPTY(&vd->clients);
2886 int i;
2888 vs->sioc = sioc;
2889 object_ref(OBJECT(vs->sioc));
2890 vs->ioc = QIO_CHANNEL(sioc);
2891 object_ref(OBJECT(vs->ioc));
2892 vs->vd = vd;
2894 buffer_init(&vs->input, "vnc-input/%p", sioc);
2895 buffer_init(&vs->output, "vnc-output/%p", sioc);
2896 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2898 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2899 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2900 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2901 #ifdef CONFIG_VNC_JPEG
2902 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2903 #endif
2904 #ifdef CONFIG_VNC_PNG
2905 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2906 #endif
2907 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2908 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2909 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2910 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2912 if (skipauth) {
2913 vs->auth = VNC_AUTH_NONE;
2914 vs->subauth = VNC_AUTH_INVALID;
2915 } else {
2916 if (websocket) {
2917 vs->auth = vd->ws_auth;
2918 vs->subauth = VNC_AUTH_INVALID;
2919 } else {
2920 vs->auth = vd->auth;
2921 vs->subauth = vd->subauth;
2924 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2925 sioc, websocket, vs->auth, vs->subauth);
2927 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
2928 for (i = 0; i < VNC_STAT_ROWS; ++i) {
2929 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
2932 VNC_DEBUG("New client on socket %p\n", vs->sioc);
2933 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2934 qio_channel_set_blocking(vs->ioc, false, NULL);
2935 if (websocket) {
2936 vs->websocket = 1;
2937 if (vd->tlscreds) {
2938 vs->ioc_tag = qio_channel_add_watch(
2939 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
2940 } else {
2941 vs->ioc_tag = qio_channel_add_watch(
2942 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
2944 } else {
2945 vs->ioc_tag = qio_channel_add_watch(
2946 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
2949 vnc_client_cache_addr(vs);
2950 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
2951 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
2953 vs->last_x = -1;
2954 vs->last_y = -1;
2956 vs->as.freq = 44100;
2957 vs->as.nchannels = 2;
2958 vs->as.fmt = AUD_FMT_S16;
2959 vs->as.endianness = 0;
2961 qemu_mutex_init(&vs->output_mutex);
2962 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
2964 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
2965 if (first_client) {
2966 vnc_update_server_surface(vd);
2969 graphic_hw_update(vd->dcl.con);
2971 if (!vs->websocket) {
2972 vnc_start_protocol(vs);
2975 if (vd->num_connecting > vd->connections_limit) {
2976 QTAILQ_FOREACH(vs, &vd->clients, next) {
2977 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
2978 vnc_disconnect_start(vs);
2979 return;
2985 void vnc_start_protocol(VncState *vs)
2987 vnc_write(vs, "RFB 003.008\n", 12);
2988 vnc_flush(vs);
2989 vnc_read_when(vs, protocol_version, 12);
2991 vs->mouse_mode_notifier.notify = check_pointer_type_change;
2992 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
2995 static gboolean vnc_listen_io(QIOChannel *ioc,
2996 GIOCondition condition,
2997 void *opaque)
2999 VncDisplay *vd = opaque;
3000 QIOChannelSocket *sioc = NULL;
3001 Error *err = NULL;
3002 bool isWebsock = false;
3003 size_t i;
3005 for (i = 0; i < vd->nlwebsock; i++) {
3006 if (ioc == QIO_CHANNEL(vd->lwebsock[i])) {
3007 isWebsock = true;
3008 break;
3012 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3013 if (sioc != NULL) {
3014 qio_channel_set_name(QIO_CHANNEL(sioc),
3015 isWebsock ? "vnc-ws-server" : "vnc-server");
3016 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3017 vnc_connect(vd, sioc, false, isWebsock);
3018 object_unref(OBJECT(sioc));
3019 } else {
3020 /* client probably closed connection before we got there */
3021 error_free(err);
3024 return TRUE;
3027 static const DisplayChangeListenerOps dcl_ops = {
3028 .dpy_name = "vnc",
3029 .dpy_refresh = vnc_refresh,
3030 .dpy_gfx_update = vnc_dpy_update,
3031 .dpy_gfx_switch = vnc_dpy_switch,
3032 .dpy_gfx_check_format = qemu_pixman_check_format,
3033 .dpy_mouse_set = vnc_mouse_set,
3034 .dpy_cursor_define = vnc_dpy_cursor_define,
3037 void vnc_display_init(const char *id)
3039 VncDisplay *vd;
3041 if (vnc_display_find(id) != NULL) {
3042 return;
3044 vd = g_malloc0(sizeof(*vd));
3046 vd->id = strdup(id);
3047 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3049 QTAILQ_INIT(&vd->clients);
3050 vd->expires = TIME_MAX;
3052 if (keyboard_layout) {
3053 trace_vnc_key_map_init(keyboard_layout);
3054 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3055 } else {
3056 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3059 if (!vd->kbd_layout) {
3060 exit(1);
3063 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3064 vd->connections_limit = 32;
3066 qemu_mutex_init(&vd->mutex);
3067 vnc_start_worker_thread();
3069 vd->dcl.ops = &dcl_ops;
3070 register_displaychangelistener(&vd->dcl);
3074 static void vnc_display_close(VncDisplay *vd)
3076 size_t i;
3077 if (!vd) {
3078 return;
3080 vd->is_unix = false;
3081 for (i = 0; i < vd->nlsock; i++) {
3082 if (vd->lsock_tag[i]) {
3083 g_source_remove(vd->lsock_tag[i]);
3085 object_unref(OBJECT(vd->lsock[i]));
3087 g_free(vd->lsock);
3088 g_free(vd->lsock_tag);
3089 vd->lsock = NULL;
3090 vd->lsock_tag = NULL;
3091 vd->nlsock = 0;
3093 for (i = 0; i < vd->nlwebsock; i++) {
3094 if (vd->lwebsock_tag[i]) {
3095 g_source_remove(vd->lwebsock_tag[i]);
3097 object_unref(OBJECT(vd->lwebsock[i]));
3099 g_free(vd->lwebsock);
3100 g_free(vd->lwebsock_tag);
3101 vd->lwebsock = NULL;
3102 vd->lwebsock_tag = NULL;
3103 vd->nlwebsock = 0;
3105 vd->auth = VNC_AUTH_INVALID;
3106 vd->subauth = VNC_AUTH_INVALID;
3107 if (vd->tlscreds) {
3108 object_unparent(OBJECT(vd->tlscreds));
3109 vd->tlscreds = NULL;
3111 g_free(vd->tlsaclname);
3112 vd->tlsaclname = NULL;
3113 if (vd->lock_key_sync) {
3114 qemu_remove_led_event_handler(vd->led);
3115 vd->led = NULL;
3119 int vnc_display_password(const char *id, const char *password)
3121 VncDisplay *vd = vnc_display_find(id);
3123 if (!vd) {
3124 return -EINVAL;
3126 if (vd->auth == VNC_AUTH_NONE) {
3127 error_printf_unless_qmp("If you want use passwords please enable "
3128 "password auth using '-vnc ${dpy},password'.\n");
3129 return -EINVAL;
3132 g_free(vd->password);
3133 vd->password = g_strdup(password);
3135 return 0;
3138 int vnc_display_pw_expire(const char *id, time_t expires)
3140 VncDisplay *vd = vnc_display_find(id);
3142 if (!vd) {
3143 return -EINVAL;
3146 vd->expires = expires;
3147 return 0;
3150 static void vnc_display_print_local_addr(VncDisplay *vd)
3152 SocketAddress *addr;
3153 Error *err = NULL;
3155 if (!vd->nlsock) {
3156 return;
3159 addr = qio_channel_socket_get_local_address(vd->lsock[0], &err);
3160 if (!addr) {
3161 return;
3164 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3165 qapi_free_SocketAddress(addr);
3166 return;
3168 error_printf_unless_qmp("VNC server running on %s:%s\n",
3169 addr->u.inet.host,
3170 addr->u.inet.port);
3171 qapi_free_SocketAddress(addr);
3174 static QemuOptsList qemu_vnc_opts = {
3175 .name = "vnc",
3176 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3177 .implied_opt_name = "vnc",
3178 .desc = {
3180 .name = "vnc",
3181 .type = QEMU_OPT_STRING,
3183 .name = "websocket",
3184 .type = QEMU_OPT_STRING,
3186 .name = "tls-creds",
3187 .type = QEMU_OPT_STRING,
3189 /* Deprecated in favour of tls-creds */
3190 .name = "x509",
3191 .type = QEMU_OPT_STRING,
3193 .name = "share",
3194 .type = QEMU_OPT_STRING,
3196 .name = "display",
3197 .type = QEMU_OPT_STRING,
3199 .name = "head",
3200 .type = QEMU_OPT_NUMBER,
3202 .name = "connections",
3203 .type = QEMU_OPT_NUMBER,
3205 .name = "to",
3206 .type = QEMU_OPT_NUMBER,
3208 .name = "ipv4",
3209 .type = QEMU_OPT_BOOL,
3211 .name = "ipv6",
3212 .type = QEMU_OPT_BOOL,
3214 .name = "password",
3215 .type = QEMU_OPT_BOOL,
3217 .name = "reverse",
3218 .type = QEMU_OPT_BOOL,
3220 .name = "lock-key-sync",
3221 .type = QEMU_OPT_BOOL,
3223 .name = "key-delay-ms",
3224 .type = QEMU_OPT_NUMBER,
3226 .name = "sasl",
3227 .type = QEMU_OPT_BOOL,
3229 /* Deprecated in favour of tls-creds */
3230 .name = "tls",
3231 .type = QEMU_OPT_BOOL,
3233 /* Deprecated in favour of tls-creds */
3234 .name = "x509verify",
3235 .type = QEMU_OPT_STRING,
3237 .name = "acl",
3238 .type = QEMU_OPT_BOOL,
3240 .name = "lossy",
3241 .type = QEMU_OPT_BOOL,
3243 .name = "non-adaptive",
3244 .type = QEMU_OPT_BOOL,
3246 { /* end of list */ }
3251 static int
3252 vnc_display_setup_auth(int *auth,
3253 int *subauth,
3254 QCryptoTLSCreds *tlscreds,
3255 bool password,
3256 bool sasl,
3257 bool websocket,
3258 Error **errp)
3261 * We have a choice of 3 authentication options
3263 * 1. none
3264 * 2. vnc
3265 * 3. sasl
3267 * The channel can be run in 2 modes
3269 * 1. clear
3270 * 2. tls
3272 * And TLS can use 2 types of credentials
3274 * 1. anon
3275 * 2. x509
3277 * We thus have 9 possible logical combinations
3279 * 1. clear + none
3280 * 2. clear + vnc
3281 * 3. clear + sasl
3282 * 4. tls + anon + none
3283 * 5. tls + anon + vnc
3284 * 6. tls + anon + sasl
3285 * 7. tls + x509 + none
3286 * 8. tls + x509 + vnc
3287 * 9. tls + x509 + sasl
3289 * These need to be mapped into the VNC auth schemes
3290 * in an appropriate manner. In regular VNC, all the
3291 * TLS options get mapped into VNC_AUTH_VENCRYPT
3292 * sub-auth types.
3294 * In websockets, the https:// protocol already provides
3295 * TLS support, so there is no need to make use of the
3296 * VeNCrypt extension. Furthermore, websockets browser
3297 * clients could not use VeNCrypt even if they wanted to,
3298 * as they cannot control when the TLS handshake takes
3299 * place. Thus there is no option but to rely on https://,
3300 * meaning combinations 4->6 and 7->9 will be mapped to
3301 * VNC auth schemes in the same way as combos 1->3.
3303 * Regardless of fact that we have a different mapping to
3304 * VNC auth mechs for plain VNC vs websockets VNC, the end
3305 * result has the same security characteristics.
3307 if (websocket || !tlscreds) {
3308 if (password) {
3309 VNC_DEBUG("Initializing VNC server with password auth\n");
3310 *auth = VNC_AUTH_VNC;
3311 } else if (sasl) {
3312 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3313 *auth = VNC_AUTH_SASL;
3314 } else {
3315 VNC_DEBUG("Initializing VNC server with no auth\n");
3316 *auth = VNC_AUTH_NONE;
3318 *subauth = VNC_AUTH_INVALID;
3319 } else {
3320 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3321 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3322 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3323 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3325 if (!is_x509 && !is_anon) {
3326 error_setg(errp,
3327 "Unsupported TLS cred type %s",
3328 object_get_typename(OBJECT(tlscreds)));
3329 return -1;
3331 *auth = VNC_AUTH_VENCRYPT;
3332 if (password) {
3333 if (is_x509) {
3334 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3335 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3336 } else {
3337 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3338 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3341 } else if (sasl) {
3342 if (is_x509) {
3343 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3344 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3345 } else {
3346 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3347 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3349 } else {
3350 if (is_x509) {
3351 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3352 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3353 } else {
3354 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3355 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3359 return 0;
3364 * Handle back compat with old CLI syntax by creating some
3365 * suitable QCryptoTLSCreds objects
3367 static QCryptoTLSCreds *
3368 vnc_display_create_creds(bool x509,
3369 bool x509verify,
3370 const char *dir,
3371 const char *id,
3372 Error **errp)
3374 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3375 Object *parent = object_get_objects_root();
3376 Object *creds;
3377 Error *err = NULL;
3379 if (x509) {
3380 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3381 parent,
3382 credsid,
3383 &err,
3384 "endpoint", "server",
3385 "dir", dir,
3386 "verify-peer", x509verify ? "yes" : "no",
3387 NULL);
3388 } else {
3389 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3390 parent,
3391 credsid,
3392 &err,
3393 "endpoint", "server",
3394 NULL);
3397 g_free(credsid);
3399 if (err) {
3400 error_propagate(errp, err);
3401 return NULL;
3404 return QCRYPTO_TLS_CREDS(creds);
3408 static int vnc_display_get_address(const char *addrstr,
3409 bool websocket,
3410 bool reverse,
3411 int displaynum,
3412 int to,
3413 bool has_ipv4,
3414 bool has_ipv6,
3415 bool ipv4,
3416 bool ipv6,
3417 SocketAddress **retaddr,
3418 Error **errp)
3420 int ret = -1;
3421 SocketAddress *addr = NULL;
3423 addr = g_new0(SocketAddress, 1);
3425 if (strncmp(addrstr, "unix:", 5) == 0) {
3426 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3427 addr->u.q_unix.path = g_strdup(addrstr + 5);
3429 if (websocket) {
3430 error_setg(errp, "UNIX sockets not supported with websock");
3431 goto cleanup;
3434 if (to) {
3435 error_setg(errp, "Port range not support with UNIX socket");
3436 goto cleanup;
3438 ret = 0;
3439 } else {
3440 const char *port;
3441 size_t hostlen;
3442 unsigned long long baseport = 0;
3443 InetSocketAddress *inet;
3445 port = strrchr(addrstr, ':');
3446 if (!port) {
3447 if (websocket) {
3448 hostlen = 0;
3449 port = addrstr;
3450 } else {
3451 error_setg(errp, "no vnc port specified");
3452 goto cleanup;
3454 } else {
3455 hostlen = port - addrstr;
3456 port++;
3457 if (*port == '\0') {
3458 error_setg(errp, "vnc port cannot be empty");
3459 goto cleanup;
3463 addr->type = SOCKET_ADDRESS_TYPE_INET;
3464 inet = &addr->u.inet;
3465 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3466 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3467 } else {
3468 inet->host = g_strndup(addrstr, hostlen);
3470 /* plain VNC port is just an offset, for websocket
3471 * port is absolute */
3472 if (websocket) {
3473 if (g_str_equal(addrstr, "") ||
3474 g_str_equal(addrstr, "on")) {
3475 if (displaynum == -1) {
3476 error_setg(errp, "explicit websocket port is required");
3477 goto cleanup;
3479 inet->port = g_strdup_printf(
3480 "%d", displaynum + 5700);
3481 if (to) {
3482 inet->has_to = true;
3483 inet->to = to + 5700;
3485 } else {
3486 inet->port = g_strdup(port);
3488 } else {
3489 int offset = reverse ? 0 : 5900;
3490 if (parse_uint_full(port, &baseport, 10) < 0) {
3491 error_setg(errp, "can't convert to a number: %s", port);
3492 goto cleanup;
3494 if (baseport > 65535 ||
3495 baseport + offset > 65535) {
3496 error_setg(errp, "port %s out of range", port);
3497 goto cleanup;
3499 inet->port = g_strdup_printf(
3500 "%d", (int)baseport + offset);
3502 if (to) {
3503 inet->has_to = true;
3504 inet->to = to + offset;
3508 inet->ipv4 = ipv4;
3509 inet->has_ipv4 = has_ipv4;
3510 inet->ipv6 = ipv6;
3511 inet->has_ipv6 = has_ipv6;
3513 ret = baseport;
3516 *retaddr = addr;
3518 cleanup:
3519 if (ret < 0) {
3520 qapi_free_SocketAddress(addr);
3522 return ret;
3525 static int vnc_display_get_addresses(QemuOpts *opts,
3526 bool reverse,
3527 SocketAddress ***retsaddr,
3528 size_t *retnsaddr,
3529 SocketAddress ***retwsaddr,
3530 size_t *retnwsaddr,
3531 Error **errp)
3533 SocketAddress *saddr = NULL;
3534 SocketAddress *wsaddr = NULL;
3535 QemuOptsIter addriter;
3536 const char *addr;
3537 int to = qemu_opt_get_number(opts, "to", 0);
3538 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3539 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3540 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3541 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3542 size_t i;
3543 int displaynum = -1;
3544 int ret = -1;
3546 *retsaddr = NULL;
3547 *retnsaddr = 0;
3548 *retwsaddr = NULL;
3549 *retnwsaddr = 0;
3551 addr = qemu_opt_get(opts, "vnc");
3552 if (addr == NULL || g_str_equal(addr, "none")) {
3553 ret = 0;
3554 goto cleanup;
3556 if (qemu_opt_get(opts, "websocket") &&
3557 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3558 error_setg(errp,
3559 "SHA1 hash support is required for websockets");
3560 goto cleanup;
3563 qemu_opt_iter_init(&addriter, opts, "vnc");
3564 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3565 int rv;
3566 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3567 has_ipv4, has_ipv6,
3568 ipv4, ipv6,
3569 &saddr, errp);
3570 if (rv < 0) {
3571 goto cleanup;
3573 /* Historical compat - first listen address can be used
3574 * to set the default websocket port
3576 if (displaynum == -1) {
3577 displaynum = rv;
3579 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3580 (*retsaddr)[(*retnsaddr)++] = saddr;
3583 /* If we had multiple primary displays, we don't do defaults
3584 * for websocket, and require explicit config instead. */
3585 if (*retnsaddr > 1) {
3586 displaynum = -1;
3589 qemu_opt_iter_init(&addriter, opts, "websocket");
3590 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3591 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3592 has_ipv4, has_ipv6,
3593 ipv4, ipv6,
3594 &wsaddr, errp) < 0) {
3595 goto cleanup;
3598 /* Historical compat - if only a single listen address was
3599 * provided, then this is used to set the default listen
3600 * address for websocket too
3602 if (*retnsaddr == 1 &&
3603 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3604 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3605 g_str_equal(wsaddr->u.inet.host, "") &&
3606 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3607 g_free(wsaddr->u.inet.host);
3608 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3611 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3612 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3615 ret = 0;
3616 cleanup:
3617 if (ret < 0) {
3618 for (i = 0; i < *retnsaddr; i++) {
3619 qapi_free_SocketAddress((*retsaddr)[i]);
3621 g_free(*retsaddr);
3622 for (i = 0; i < *retnwsaddr; i++) {
3623 qapi_free_SocketAddress((*retwsaddr)[i]);
3625 g_free(*retwsaddr);
3626 *retsaddr = *retwsaddr = NULL;
3627 *retnsaddr = *retnwsaddr = 0;
3629 return ret;
3632 static int vnc_display_connect(VncDisplay *vd,
3633 SocketAddress **saddr,
3634 size_t nsaddr,
3635 SocketAddress **wsaddr,
3636 size_t nwsaddr,
3637 Error **errp)
3639 /* connect to viewer */
3640 QIOChannelSocket *sioc = NULL;
3641 if (nwsaddr != 0) {
3642 error_setg(errp, "Cannot use websockets in reverse mode");
3643 return -1;
3645 if (nsaddr != 1) {
3646 error_setg(errp, "Expected a single address in reverse mode");
3647 return -1;
3649 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3650 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3651 sioc = qio_channel_socket_new();
3652 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3653 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3654 return -1;
3656 vnc_connect(vd, sioc, false, false);
3657 object_unref(OBJECT(sioc));
3658 return 0;
3662 static int vnc_display_listen_addr(VncDisplay *vd,
3663 SocketAddress *addr,
3664 const char *name,
3665 QIOChannelSocket ***lsock,
3666 guint **lsock_tag,
3667 size_t *nlsock,
3668 Error **errp)
3670 QIODNSResolver *resolver = qio_dns_resolver_get_instance();
3671 SocketAddress **rawaddrs = NULL;
3672 size_t nrawaddrs = 0;
3673 Error *listenerr = NULL;
3674 bool listening = false;
3675 size_t i;
3677 if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,
3678 &rawaddrs, errp) < 0) {
3679 return -1;
3682 for (i = 0; i < nrawaddrs; i++) {
3683 QIOChannelSocket *sioc = qio_channel_socket_new();
3685 qio_channel_set_name(QIO_CHANNEL(sioc), name);
3686 if (qio_channel_socket_listen_sync(
3687 sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
3688 object_unref(OBJECT(sioc));
3689 continue;
3691 listening = true;
3692 (*nlsock)++;
3693 *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);
3694 *lsock_tag = g_renew(guint, *lsock_tag, *nlsock);
3696 (*lsock)[*nlsock - 1] = sioc;
3697 (*lsock_tag)[*nlsock - 1] = 0;
3700 for (i = 0; i < nrawaddrs; i++) {
3701 qapi_free_SocketAddress(rawaddrs[i]);
3703 g_free(rawaddrs);
3705 if (listenerr) {
3706 if (!listening) {
3707 error_propagate(errp, listenerr);
3708 return -1;
3709 } else {
3710 error_free(listenerr);
3714 for (i = 0; i < *nlsock; i++) {
3715 (*lsock_tag)[i] = qio_channel_add_watch(
3716 QIO_CHANNEL((*lsock)[i]),
3717 G_IO_IN, vnc_listen_io, vd, NULL);
3720 return 0;
3724 static int vnc_display_listen(VncDisplay *vd,
3725 SocketAddress **saddr,
3726 size_t nsaddr,
3727 SocketAddress **wsaddr,
3728 size_t nwsaddr,
3729 Error **errp)
3731 size_t i;
3733 for (i = 0; i < nsaddr; i++) {
3734 if (vnc_display_listen_addr(vd, saddr[i],
3735 "vnc-listen",
3736 &vd->lsock,
3737 &vd->lsock_tag,
3738 &vd->nlsock,
3739 errp) < 0) {
3740 return -1;
3743 for (i = 0; i < nwsaddr; i++) {
3744 if (vnc_display_listen_addr(vd, wsaddr[i],
3745 "vnc-ws-listen",
3746 &vd->lwebsock,
3747 &vd->lwebsock_tag,
3748 &vd->nlwebsock,
3749 errp) < 0) {
3750 return -1;
3754 return 0;
3758 void vnc_display_open(const char *id, Error **errp)
3760 VncDisplay *vd = vnc_display_find(id);
3761 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3762 SocketAddress **saddr = NULL, **wsaddr = NULL;
3763 size_t nsaddr, nwsaddr;
3764 const char *share, *device_id;
3765 QemuConsole *con;
3766 bool password = false;
3767 bool reverse = false;
3768 const char *credid;
3769 bool sasl = false;
3770 #ifdef CONFIG_VNC_SASL
3771 int saslErr;
3772 #endif
3773 int acl = 0;
3774 int lock_key_sync = 1;
3775 int key_delay_ms;
3776 size_t i;
3778 if (!vd) {
3779 error_setg(errp, "VNC display not active");
3780 return;
3782 vnc_display_close(vd);
3784 if (!opts) {
3785 return;
3788 reverse = qemu_opt_get_bool(opts, "reverse", false);
3789 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3790 &wsaddr, &nwsaddr, errp) < 0) {
3791 goto fail;
3794 password = qemu_opt_get_bool(opts, "password", false);
3795 if (password) {
3796 if (fips_get_state()) {
3797 error_setg(errp,
3798 "VNC password auth disabled due to FIPS mode, "
3799 "consider using the VeNCrypt or SASL authentication "
3800 "methods as an alternative");
3801 goto fail;
3803 if (!qcrypto_cipher_supports(
3804 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3805 error_setg(errp,
3806 "Cipher backend does not support DES RFB algorithm");
3807 goto fail;
3811 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3812 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
3813 sasl = qemu_opt_get_bool(opts, "sasl", false);
3814 #ifndef CONFIG_VNC_SASL
3815 if (sasl) {
3816 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3817 goto fail;
3819 #endif /* CONFIG_VNC_SASL */
3820 credid = qemu_opt_get(opts, "tls-creds");
3821 if (credid) {
3822 Object *creds;
3823 if (qemu_opt_get(opts, "tls") ||
3824 qemu_opt_get(opts, "x509") ||
3825 qemu_opt_get(opts, "x509verify")) {
3826 error_setg(errp,
3827 "'tls-creds' parameter is mutually exclusive with "
3828 "'tls', 'x509' and 'x509verify' parameters");
3829 goto fail;
3832 creds = object_resolve_path_component(
3833 object_get_objects_root(), credid);
3834 if (!creds) {
3835 error_setg(errp, "No TLS credentials with id '%s'",
3836 credid);
3837 goto fail;
3839 vd->tlscreds = (QCryptoTLSCreds *)
3840 object_dynamic_cast(creds,
3841 TYPE_QCRYPTO_TLS_CREDS);
3842 if (!vd->tlscreds) {
3843 error_setg(errp, "Object with id '%s' is not TLS credentials",
3844 credid);
3845 goto fail;
3847 object_ref(OBJECT(vd->tlscreds));
3849 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3850 error_setg(errp,
3851 "Expecting TLS credentials with a server endpoint");
3852 goto fail;
3854 } else {
3855 const char *path;
3856 bool tls = false, x509 = false, x509verify = false;
3857 tls = qemu_opt_get_bool(opts, "tls", false);
3858 if (tls) {
3859 path = qemu_opt_get(opts, "x509");
3861 if (path) {
3862 x509 = true;
3863 } else {
3864 path = qemu_opt_get(opts, "x509verify");
3865 if (path) {
3866 x509 = true;
3867 x509verify = true;
3870 vd->tlscreds = vnc_display_create_creds(x509,
3871 x509verify,
3872 path,
3873 vd->id,
3874 errp);
3875 if (!vd->tlscreds) {
3876 goto fail;
3880 acl = qemu_opt_get_bool(opts, "acl", false);
3882 share = qemu_opt_get(opts, "share");
3883 if (share) {
3884 if (strcmp(share, "ignore") == 0) {
3885 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
3886 } else if (strcmp(share, "allow-exclusive") == 0) {
3887 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3888 } else if (strcmp(share, "force-shared") == 0) {
3889 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3890 } else {
3891 error_setg(errp, "unknown vnc share= option");
3892 goto fail;
3894 } else {
3895 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3897 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3899 #ifdef CONFIG_VNC_JPEG
3900 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
3901 #endif
3902 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3903 /* adaptive updates are only used with tight encoding and
3904 * if lossy updates are enabled so we can disable all the
3905 * calculations otherwise */
3906 if (!vd->lossy) {
3907 vd->non_adaptive = true;
3910 if (acl) {
3911 if (strcmp(vd->id, "default") == 0) {
3912 vd->tlsaclname = g_strdup("vnc.x509dname");
3913 } else {
3914 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
3916 qemu_acl_init(vd->tlsaclname);
3918 #ifdef CONFIG_VNC_SASL
3919 if (acl && sasl) {
3920 char *aclname;
3922 if (strcmp(vd->id, "default") == 0) {
3923 aclname = g_strdup("vnc.username");
3924 } else {
3925 aclname = g_strdup_printf("vnc.%s.username", vd->id);
3927 vd->sasl.acl = qemu_acl_init(aclname);
3928 g_free(aclname);
3930 #endif
3932 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
3933 vd->tlscreds, password,
3934 sasl, false, errp) < 0) {
3935 goto fail;
3938 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
3939 vd->tlscreds, password,
3940 sasl, true, errp) < 0) {
3941 goto fail;
3944 #ifdef CONFIG_VNC_SASL
3945 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3946 error_setg(errp, "Failed to initialize SASL auth: %s",
3947 sasl_errstring(saslErr, NULL, NULL));
3948 goto fail;
3950 #endif
3951 vd->lock_key_sync = lock_key_sync;
3952 if (lock_key_sync) {
3953 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
3955 vd->ledstate = 0;
3956 vd->key_delay_ms = key_delay_ms;
3958 device_id = qemu_opt_get(opts, "display");
3959 if (device_id) {
3960 int head = qemu_opt_get_number(opts, "head", 0);
3961 Error *err = NULL;
3963 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3964 if (err) {
3965 error_propagate(errp, err);
3966 goto fail;
3968 } else {
3969 con = NULL;
3972 if (con != vd->dcl.con) {
3973 unregister_displaychangelistener(&vd->dcl);
3974 vd->dcl.con = con;
3975 register_displaychangelistener(&vd->dcl);
3978 if (saddr == NULL) {
3979 goto cleanup;
3982 if (reverse) {
3983 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3984 goto fail;
3986 } else {
3987 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3988 goto fail;
3992 if (qemu_opt_get(opts, "to")) {
3993 vnc_display_print_local_addr(vd);
3996 cleanup:
3997 for (i = 0; i < nsaddr; i++) {
3998 qapi_free_SocketAddress(saddr[i]);
4000 for (i = 0; i < nwsaddr; i++) {
4001 qapi_free_SocketAddress(wsaddr[i]);
4003 return;
4005 fail:
4006 vnc_display_close(vd);
4007 goto cleanup;
4010 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4012 VncDisplay *vd = vnc_display_find(id);
4013 QIOChannelSocket *sioc;
4015 if (!vd) {
4016 return;
4019 sioc = qio_channel_socket_new_fd(csock, NULL);
4020 if (sioc) {
4021 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4022 vnc_connect(vd, sioc, skipauth, false);
4023 object_unref(OBJECT(sioc));
4027 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4029 int i = 2;
4030 char *id;
4032 id = g_strdup("default");
4033 while (qemu_opts_find(olist, id)) {
4034 g_free(id);
4035 id = g_strdup_printf("vnc%d", i++);
4037 qemu_opts_set_id(opts, id);
4040 QemuOpts *vnc_parse(const char *str, Error **errp)
4042 QemuOptsList *olist = qemu_find_opts("vnc");
4043 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
4044 const char *id;
4046 if (!opts) {
4047 return NULL;
4050 id = qemu_opts_id(opts);
4051 if (!id) {
4052 /* auto-assign id if not present */
4053 vnc_auto_assign_id(olist, opts);
4055 return opts;
4058 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4060 Error *local_err = NULL;
4061 char *id = (char *)qemu_opts_id(opts);
4063 assert(id);
4064 vnc_display_init(id);
4065 vnc_display_open(id, &local_err);
4066 if (local_err != NULL) {
4067 error_reportf_err(local_err, "Failed to start VNC server: ");
4068 exit(1);
4070 return 0;
4073 static void vnc_register_config(void)
4075 qemu_add_opts(&qemu_vnc_opts);
4077 opts_init(vnc_register_config);