ui: introduce enum to track VNC client framebuffer update request state
[qemu/ar7.git] / ui / vnc.c
blob30e2feeae39e450a7219566f8803904c7c3cbacb
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 "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
35 #include "qemu/acl.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.h"
40 #include "ui/input.h"
41 #include "qapi-event.h"
42 #include "crypto/hash.h"
43 #include "crypto/tlscredsanon.h"
44 #include "crypto/tlscredsx509.h"
45 #include "qom/object_interfaces.h"
46 #include "qemu/cutils.h"
47 #include "io/dns-resolver.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
59 QTAILQ_HEAD_INITIALIZER(vnc_displays);
61 static int vnc_cursor_define(VncState *vs);
62 static void vnc_release_modifiers(VncState *vs);
64 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
66 #ifdef _VNC_DEBUG
67 static const char *mn[] = {
68 [0] = "undefined",
69 [VNC_SHARE_MODE_CONNECTING] = "connecting",
70 [VNC_SHARE_MODE_SHARED] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
74 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
75 vs->ioc, mn[vs->share_mode], mn[mode]);
76 #endif
78 switch (vs->share_mode) {
79 case VNC_SHARE_MODE_CONNECTING:
80 vs->vd->num_connecting--;
81 break;
82 case VNC_SHARE_MODE_SHARED:
83 vs->vd->num_shared--;
84 break;
85 case VNC_SHARE_MODE_EXCLUSIVE:
86 vs->vd->num_exclusive--;
87 break;
88 default:
89 break;
92 vs->share_mode = mode;
94 switch (vs->share_mode) {
95 case VNC_SHARE_MODE_CONNECTING:
96 vs->vd->num_connecting++;
97 break;
98 case VNC_SHARE_MODE_SHARED:
99 vs->vd->num_shared++;
100 break;
101 case VNC_SHARE_MODE_EXCLUSIVE:
102 vs->vd->num_exclusive++;
103 break;
104 default:
105 break;
110 static void vnc_init_basic_info(SocketAddress *addr,
111 VncBasicInfo *info,
112 Error **errp)
114 switch (addr->type) {
115 case SOCKET_ADDRESS_TYPE_INET:
116 info->host = g_strdup(addr->u.inet.host);
117 info->service = g_strdup(addr->u.inet.port);
118 if (addr->u.inet.ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_TYPE_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 case SOCKET_ADDRESS_TYPE_VSOCK:
132 case SOCKET_ADDRESS_TYPE_FD:
133 error_setg(errp, "Unsupported socket address type %s",
134 SocketAddressType_str(addr->type));
135 break;
136 default:
137 abort();
140 return;
143 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
144 VncBasicInfo *info,
145 Error **errp)
147 SocketAddress *addr = NULL;
149 if (!ioc) {
150 error_setg(errp, "No listener socket available");
151 return;
154 addr = qio_channel_socket_get_local_address(ioc, errp);
155 if (!addr) {
156 return;
159 vnc_init_basic_info(addr, info, errp);
160 qapi_free_SocketAddress(addr);
163 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
164 VncBasicInfo *info,
165 Error **errp)
167 SocketAddress *addr = NULL;
169 addr = qio_channel_socket_get_remote_address(ioc, errp);
170 if (!addr) {
171 return;
174 vnc_init_basic_info(addr, info, errp);
175 qapi_free_SocketAddress(addr);
178 static const char *vnc_auth_name(VncDisplay *vd) {
179 switch (vd->auth) {
180 case VNC_AUTH_INVALID:
181 return "invalid";
182 case VNC_AUTH_NONE:
183 return "none";
184 case VNC_AUTH_VNC:
185 return "vnc";
186 case VNC_AUTH_RA2:
187 return "ra2";
188 case VNC_AUTH_RA2NE:
189 return "ra2ne";
190 case VNC_AUTH_TIGHT:
191 return "tight";
192 case VNC_AUTH_ULTRA:
193 return "ultra";
194 case VNC_AUTH_TLS:
195 return "tls";
196 case VNC_AUTH_VENCRYPT:
197 switch (vd->subauth) {
198 case VNC_AUTH_VENCRYPT_PLAIN:
199 return "vencrypt+plain";
200 case VNC_AUTH_VENCRYPT_TLSNONE:
201 return "vencrypt+tls+none";
202 case VNC_AUTH_VENCRYPT_TLSVNC:
203 return "vencrypt+tls+vnc";
204 case VNC_AUTH_VENCRYPT_TLSPLAIN:
205 return "vencrypt+tls+plain";
206 case VNC_AUTH_VENCRYPT_X509NONE:
207 return "vencrypt+x509+none";
208 case VNC_AUTH_VENCRYPT_X509VNC:
209 return "vencrypt+x509+vnc";
210 case VNC_AUTH_VENCRYPT_X509PLAIN:
211 return "vencrypt+x509+plain";
212 case VNC_AUTH_VENCRYPT_TLSSASL:
213 return "vencrypt+tls+sasl";
214 case VNC_AUTH_VENCRYPT_X509SASL:
215 return "vencrypt+x509+sasl";
216 default:
217 return "vencrypt";
219 case VNC_AUTH_SASL:
220 return "sasl";
222 return "unknown";
225 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
227 VncServerInfo *info;
228 Error *err = NULL;
230 if (!vd->nlsock) {
231 return NULL;
234 info = g_malloc0(sizeof(*info));
235 vnc_init_basic_info_from_server_addr(vd->lsock[0],
236 qapi_VncServerInfo_base(info), &err);
237 info->has_auth = true;
238 info->auth = g_strdup(vnc_auth_name(vd));
239 if (err) {
240 qapi_free_VncServerInfo(info);
241 info = NULL;
242 error_free(err);
244 return info;
247 static void vnc_client_cache_auth(VncState *client)
249 if (!client->info) {
250 return;
253 if (client->tls) {
254 client->info->x509_dname =
255 qcrypto_tls_session_get_peer_name(client->tls);
256 client->info->has_x509_dname =
257 client->info->x509_dname != NULL;
259 #ifdef CONFIG_VNC_SASL
260 if (client->sasl.conn &&
261 client->sasl.username) {
262 client->info->has_sasl_username = true;
263 client->info->sasl_username = g_strdup(client->sasl.username);
265 #endif
268 static void vnc_client_cache_addr(VncState *client)
270 Error *err = NULL;
272 client->info = g_malloc0(sizeof(*client->info));
273 vnc_init_basic_info_from_remote_addr(client->sioc,
274 qapi_VncClientInfo_base(client->info),
275 &err);
276 if (err) {
277 qapi_free_VncClientInfo(client->info);
278 client->info = NULL;
279 error_free(err);
283 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
285 VncServerInfo *si;
287 if (!vs->info) {
288 return;
291 si = vnc_server_info_get(vs->vd);
292 if (!si) {
293 return;
296 switch (event) {
297 case QAPI_EVENT_VNC_CONNECTED:
298 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
299 &error_abort);
300 break;
301 case QAPI_EVENT_VNC_INITIALIZED:
302 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
303 break;
304 case QAPI_EVENT_VNC_DISCONNECTED:
305 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
306 break;
307 default:
308 break;
311 qapi_free_VncServerInfo(si);
314 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
316 VncClientInfo *info;
317 Error *err = NULL;
319 info = g_malloc0(sizeof(*info));
321 vnc_init_basic_info_from_remote_addr(client->sioc,
322 qapi_VncClientInfo_base(info),
323 &err);
324 if (err) {
325 error_free(err);
326 qapi_free_VncClientInfo(info);
327 return NULL;
330 info->websocket = client->websocket;
332 if (client->tls) {
333 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
334 info->has_x509_dname = info->x509_dname != NULL;
336 #ifdef CONFIG_VNC_SASL
337 if (client->sasl.conn && client->sasl.username) {
338 info->has_sasl_username = true;
339 info->sasl_username = g_strdup(client->sasl.username);
341 #endif
343 return info;
346 static VncDisplay *vnc_display_find(const char *id)
348 VncDisplay *vd;
350 if (id == NULL) {
351 return QTAILQ_FIRST(&vnc_displays);
353 QTAILQ_FOREACH(vd, &vnc_displays, next) {
354 if (strcmp(id, vd->id) == 0) {
355 return vd;
358 return NULL;
361 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
363 VncClientInfoList *cinfo, *prev = NULL;
364 VncState *client;
366 QTAILQ_FOREACH(client, &vd->clients, next) {
367 cinfo = g_new0(VncClientInfoList, 1);
368 cinfo->value = qmp_query_vnc_client(client);
369 cinfo->next = prev;
370 prev = cinfo;
372 return prev;
375 VncInfo *qmp_query_vnc(Error **errp)
377 VncInfo *info = g_malloc0(sizeof(*info));
378 VncDisplay *vd = vnc_display_find(NULL);
379 SocketAddress *addr = NULL;
381 if (vd == NULL || !vd->nlsock) {
382 info->enabled = false;
383 } else {
384 info->enabled = true;
386 /* for compatibility with the original command */
387 info->has_clients = true;
388 info->clients = qmp_query_client_list(vd);
390 if (vd->lsock == NULL) {
391 return info;
394 addr = qio_channel_socket_get_local_address(vd->lsock[0], errp);
395 if (!addr) {
396 goto out_error;
399 switch (addr->type) {
400 case SOCKET_ADDRESS_TYPE_INET:
401 info->host = g_strdup(addr->u.inet.host);
402 info->service = g_strdup(addr->u.inet.port);
403 if (addr->u.inet.ipv6) {
404 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
405 } else {
406 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
408 break;
410 case SOCKET_ADDRESS_TYPE_UNIX:
411 info->host = g_strdup("");
412 info->service = g_strdup(addr->u.q_unix.path);
413 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
414 break;
416 case SOCKET_ADDRESS_TYPE_VSOCK:
417 case SOCKET_ADDRESS_TYPE_FD:
418 error_setg(errp, "Unsupported socket address type %s",
419 SocketAddressType_str(addr->type));
420 goto out_error;
421 default:
422 abort();
425 info->has_host = true;
426 info->has_service = true;
427 info->has_family = true;
429 info->has_auth = true;
430 info->auth = g_strdup(vnc_auth_name(vd));
433 qapi_free_SocketAddress(addr);
434 return info;
436 out_error:
437 qapi_free_SocketAddress(addr);
438 qapi_free_VncInfo(info);
439 return NULL;
443 static void qmp_query_auth(int auth, int subauth,
444 VncPrimaryAuth *qmp_auth,
445 VncVencryptSubAuth *qmp_vencrypt,
446 bool *qmp_has_vencrypt);
448 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
449 bool websocket,
450 int auth,
451 int subauth,
452 VncServerInfo2List *prev)
454 VncServerInfo2List *list;
455 VncServerInfo2 *info;
456 Error *err = NULL;
457 SocketAddress *addr;
459 addr = qio_channel_socket_get_local_address(ioc, &err);
460 if (!addr) {
461 error_free(err);
462 return prev;
465 info = g_new0(VncServerInfo2, 1);
466 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
467 qapi_free_SocketAddress(addr);
468 if (err) {
469 qapi_free_VncServerInfo2(info);
470 error_free(err);
471 return prev;
473 info->websocket = websocket;
475 qmp_query_auth(auth, subauth, &info->auth,
476 &info->vencrypt, &info->has_vencrypt);
478 list = g_new0(VncServerInfo2List, 1);
479 list->value = info;
480 list->next = prev;
481 return list;
484 static void qmp_query_auth(int auth, int subauth,
485 VncPrimaryAuth *qmp_auth,
486 VncVencryptSubAuth *qmp_vencrypt,
487 bool *qmp_has_vencrypt)
489 switch (auth) {
490 case VNC_AUTH_VNC:
491 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
492 break;
493 case VNC_AUTH_RA2:
494 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
495 break;
496 case VNC_AUTH_RA2NE:
497 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
498 break;
499 case VNC_AUTH_TIGHT:
500 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
501 break;
502 case VNC_AUTH_ULTRA:
503 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
504 break;
505 case VNC_AUTH_TLS:
506 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
507 break;
508 case VNC_AUTH_VENCRYPT:
509 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
510 *qmp_has_vencrypt = true;
511 switch (subauth) {
512 case VNC_AUTH_VENCRYPT_PLAIN:
513 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
514 break;
515 case VNC_AUTH_VENCRYPT_TLSNONE:
516 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
517 break;
518 case VNC_AUTH_VENCRYPT_TLSVNC:
519 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
520 break;
521 case VNC_AUTH_VENCRYPT_TLSPLAIN:
522 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
523 break;
524 case VNC_AUTH_VENCRYPT_X509NONE:
525 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
526 break;
527 case VNC_AUTH_VENCRYPT_X509VNC:
528 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
529 break;
530 case VNC_AUTH_VENCRYPT_X509PLAIN:
531 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
532 break;
533 case VNC_AUTH_VENCRYPT_TLSSASL:
534 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
535 break;
536 case VNC_AUTH_VENCRYPT_X509SASL:
537 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
538 break;
539 default:
540 *qmp_has_vencrypt = false;
541 break;
543 break;
544 case VNC_AUTH_SASL:
545 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
546 break;
547 case VNC_AUTH_NONE:
548 default:
549 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
550 break;
554 VncInfo2List *qmp_query_vnc_servers(Error **errp)
556 VncInfo2List *item, *prev = NULL;
557 VncInfo2 *info;
558 VncDisplay *vd;
559 DeviceState *dev;
560 size_t i;
562 QTAILQ_FOREACH(vd, &vnc_displays, next) {
563 info = g_new0(VncInfo2, 1);
564 info->id = g_strdup(vd->id);
565 info->clients = qmp_query_client_list(vd);
566 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
567 &info->vencrypt, &info->has_vencrypt);
568 if (vd->dcl.con) {
569 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
570 "device", NULL));
571 info->has_display = true;
572 info->display = g_strdup(dev->id);
574 for (i = 0; i < vd->nlsock; i++) {
575 info->server = qmp_query_server_entry(
576 vd->lsock[i], false, vd->auth, vd->subauth, info->server);
578 for (i = 0; i < vd->nlwebsock; i++) {
579 info->server = qmp_query_server_entry(
580 vd->lwebsock[i], true, vd->ws_auth,
581 vd->ws_subauth, info->server);
584 item = g_new0(VncInfo2List, 1);
585 item->value = info;
586 item->next = prev;
587 prev = item;
589 return prev;
592 /* TODO
593 1) Get the queue working for IO.
594 2) there is some weirdness when using the -S option (the screen is grey
595 and not totally invalidated
596 3) resolutions > 1024
599 static int vnc_update_client(VncState *vs, int has_dirty);
600 static void vnc_disconnect_start(VncState *vs);
602 static void vnc_colordepth(VncState *vs);
603 static void framebuffer_update_request(VncState *vs, int incremental,
604 int x_position, int y_position,
605 int w, int h);
606 static void vnc_refresh(DisplayChangeListener *dcl);
607 static int vnc_refresh_server_surface(VncDisplay *vd);
609 static int vnc_width(VncDisplay *vd)
611 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
612 VNC_DIRTY_PIXELS_PER_BIT));
615 static int vnc_height(VncDisplay *vd)
617 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
620 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
621 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
622 VncDisplay *vd,
623 int x, int y, int w, int h)
625 int width = vnc_width(vd);
626 int height = vnc_height(vd);
628 /* this is needed this to ensure we updated all affected
629 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
630 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
631 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
633 x = MIN(x, width);
634 y = MIN(y, height);
635 w = MIN(x + w, width) - x;
636 h = MIN(y + h, height);
638 for (; y < h; y++) {
639 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
640 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
644 static void vnc_dpy_update(DisplayChangeListener *dcl,
645 int x, int y, int w, int h)
647 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
648 struct VncSurface *s = &vd->guest;
650 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
653 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
654 int32_t encoding)
656 vnc_write_u16(vs, x);
657 vnc_write_u16(vs, y);
658 vnc_write_u16(vs, w);
659 vnc_write_u16(vs, h);
661 vnc_write_s32(vs, encoding);
665 static void vnc_desktop_resize(VncState *vs)
667 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
668 return;
670 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
671 vs->client_height == pixman_image_get_height(vs->vd->server)) {
672 return;
674 vs->client_width = pixman_image_get_width(vs->vd->server);
675 vs->client_height = pixman_image_get_height(vs->vd->server);
676 vnc_lock_output(vs);
677 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
678 vnc_write_u8(vs, 0);
679 vnc_write_u16(vs, 1); /* number of rects */
680 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
681 VNC_ENCODING_DESKTOPRESIZE);
682 vnc_unlock_output(vs);
683 vnc_flush(vs);
686 static void vnc_abort_display_jobs(VncDisplay *vd)
688 VncState *vs;
690 QTAILQ_FOREACH(vs, &vd->clients, next) {
691 vnc_lock_output(vs);
692 vs->abort = true;
693 vnc_unlock_output(vs);
695 QTAILQ_FOREACH(vs, &vd->clients, next) {
696 vnc_jobs_join(vs);
698 QTAILQ_FOREACH(vs, &vd->clients, next) {
699 vnc_lock_output(vs);
700 vs->abort = false;
701 vnc_unlock_output(vs);
705 int vnc_server_fb_stride(VncDisplay *vd)
707 return pixman_image_get_stride(vd->server);
710 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
712 uint8_t *ptr;
714 ptr = (uint8_t *)pixman_image_get_data(vd->server);
715 ptr += y * vnc_server_fb_stride(vd);
716 ptr += x * VNC_SERVER_FB_BYTES;
717 return ptr;
720 static void vnc_update_server_surface(VncDisplay *vd)
722 int width, height;
724 qemu_pixman_image_unref(vd->server);
725 vd->server = NULL;
727 if (QTAILQ_EMPTY(&vd->clients)) {
728 return;
731 width = vnc_width(vd);
732 height = vnc_height(vd);
733 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
734 width, height,
735 NULL, 0);
737 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
738 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
739 width, height);
742 static void vnc_dpy_switch(DisplayChangeListener *dcl,
743 DisplaySurface *surface)
745 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
746 VncState *vs;
748 vnc_abort_display_jobs(vd);
749 vd->ds = surface;
751 /* server surface */
752 vnc_update_server_surface(vd);
754 /* guest surface */
755 qemu_pixman_image_unref(vd->guest.fb);
756 vd->guest.fb = pixman_image_ref(surface->image);
757 vd->guest.format = surface->format;
759 QTAILQ_FOREACH(vs, &vd->clients, next) {
760 vnc_colordepth(vs);
761 vnc_desktop_resize(vs);
762 if (vs->vd->cursor) {
763 vnc_cursor_define(vs);
765 memset(vs->dirty, 0x00, sizeof(vs->dirty));
766 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
767 vnc_width(vd),
768 vnc_height(vd));
772 /* fastest code */
773 static void vnc_write_pixels_copy(VncState *vs,
774 void *pixels, int size)
776 vnc_write(vs, pixels, size);
779 /* slowest but generic code. */
780 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
782 uint8_t r, g, b;
784 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
785 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
786 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
787 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
788 #else
789 # error need some bits here if you change VNC_SERVER_FB_FORMAT
790 #endif
791 v = (r << vs->client_pf.rshift) |
792 (g << vs->client_pf.gshift) |
793 (b << vs->client_pf.bshift);
794 switch (vs->client_pf.bytes_per_pixel) {
795 case 1:
796 buf[0] = v;
797 break;
798 case 2:
799 if (vs->client_be) {
800 buf[0] = v >> 8;
801 buf[1] = v;
802 } else {
803 buf[1] = v >> 8;
804 buf[0] = v;
806 break;
807 default:
808 case 4:
809 if (vs->client_be) {
810 buf[0] = v >> 24;
811 buf[1] = v >> 16;
812 buf[2] = v >> 8;
813 buf[3] = v;
814 } else {
815 buf[3] = v >> 24;
816 buf[2] = v >> 16;
817 buf[1] = v >> 8;
818 buf[0] = v;
820 break;
824 static void vnc_write_pixels_generic(VncState *vs,
825 void *pixels1, int size)
827 uint8_t buf[4];
829 if (VNC_SERVER_FB_BYTES == 4) {
830 uint32_t *pixels = pixels1;
831 int n, i;
832 n = size >> 2;
833 for (i = 0; i < n; i++) {
834 vnc_convert_pixel(vs, buf, pixels[i]);
835 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
840 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
842 int i;
843 uint8_t *row;
844 VncDisplay *vd = vs->vd;
846 row = vnc_server_fb_ptr(vd, x, y);
847 for (i = 0; i < h; i++) {
848 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
849 row += vnc_server_fb_stride(vd);
851 return 1;
854 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
856 int n = 0;
857 bool encode_raw = false;
858 size_t saved_offs = vs->output.offset;
860 switch(vs->vnc_encoding) {
861 case VNC_ENCODING_ZLIB:
862 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
863 break;
864 case VNC_ENCODING_HEXTILE:
865 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
866 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
867 break;
868 case VNC_ENCODING_TIGHT:
869 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
870 break;
871 case VNC_ENCODING_TIGHT_PNG:
872 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
873 break;
874 case VNC_ENCODING_ZRLE:
875 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
876 break;
877 case VNC_ENCODING_ZYWRLE:
878 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
879 break;
880 default:
881 encode_raw = true;
882 break;
885 /* If the client has the same pixel format as our internal buffer and
886 * a RAW encoding would need less space fall back to RAW encoding to
887 * save bandwidth and processing power in the client. */
888 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
889 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
890 vs->output.offset = saved_offs;
891 encode_raw = true;
894 if (encode_raw) {
895 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
896 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
899 return n;
902 static void vnc_mouse_set(DisplayChangeListener *dcl,
903 int x, int y, int visible)
905 /* can we ask the client(s) to move the pointer ??? */
908 static int vnc_cursor_define(VncState *vs)
910 QEMUCursor *c = vs->vd->cursor;
911 int isize;
913 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
914 vnc_lock_output(vs);
915 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
916 vnc_write_u8(vs, 0); /* padding */
917 vnc_write_u16(vs, 1); /* # of rects */
918 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
919 VNC_ENCODING_RICH_CURSOR);
920 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
921 vnc_write_pixels_generic(vs, c->data, isize);
922 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
923 vnc_unlock_output(vs);
924 return 0;
926 return -1;
929 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
930 QEMUCursor *c)
932 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
933 VncState *vs;
935 cursor_put(vd->cursor);
936 g_free(vd->cursor_mask);
938 vd->cursor = c;
939 cursor_get(vd->cursor);
940 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
941 vd->cursor_mask = g_malloc0(vd->cursor_msize);
942 cursor_get_mono_mask(c, 0, vd->cursor_mask);
944 QTAILQ_FOREACH(vs, &vd->clients, next) {
945 vnc_cursor_define(vs);
949 static int find_and_clear_dirty_height(VncState *vs,
950 int y, int last_x, int x, int height)
952 int h;
954 for (h = 1; h < (height - y); h++) {
955 if (!test_bit(last_x, vs->dirty[y + h])) {
956 break;
958 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
961 return h;
964 static int vnc_update_client(VncState *vs, int has_dirty)
966 VncDisplay *vd = vs->vd;
967 VncJob *job;
968 int y;
969 int height, width;
970 int n = 0;
972 if (vs->disconnecting) {
973 vnc_disconnect_finish(vs);
974 return 0;
977 vs->has_dirty += has_dirty;
978 if (vs->update == VNC_STATE_UPDATE_NONE) {
979 return 0;
982 if (vs->output.offset && !vs->audio_cap &&
983 vs->update != VNC_STATE_UPDATE_FORCE) {
984 /* kernel send buffers are full -> drop frames to throttle */
985 return 0;
988 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
989 return 0;
993 * Send screen updates to the vnc client using the server
994 * surface and server dirty map. guest surface updates
995 * happening in parallel don't disturb us, the next pass will
996 * send them to the client.
998 job = vnc_job_new(vs);
1000 height = pixman_image_get_height(vd->server);
1001 width = pixman_image_get_width(vd->server);
1003 y = 0;
1004 for (;;) {
1005 int x, h;
1006 unsigned long x2;
1007 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1008 height * VNC_DIRTY_BPL(vs),
1009 y * VNC_DIRTY_BPL(vs));
1010 if (offset == height * VNC_DIRTY_BPL(vs)) {
1011 /* no more dirty bits */
1012 break;
1014 y = offset / VNC_DIRTY_BPL(vs);
1015 x = offset % VNC_DIRTY_BPL(vs);
1016 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1017 VNC_DIRTY_BPL(vs), x);
1018 bitmap_clear(vs->dirty[y], x, x2 - x);
1019 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1020 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1021 if (x2 > x) {
1022 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1023 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1025 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1026 y += h;
1027 if (y == height) {
1028 break;
1033 vnc_job_push(job);
1034 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
1035 vs->has_dirty = 0;
1036 return n;
1039 /* audio */
1040 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1042 VncState *vs = opaque;
1044 switch (cmd) {
1045 case AUD_CNOTIFY_DISABLE:
1046 vnc_lock_output(vs);
1047 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1048 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1049 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1050 vnc_unlock_output(vs);
1051 vnc_flush(vs);
1052 break;
1054 case AUD_CNOTIFY_ENABLE:
1055 vnc_lock_output(vs);
1056 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1057 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1058 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1059 vnc_unlock_output(vs);
1060 vnc_flush(vs);
1061 break;
1065 static void audio_capture_destroy(void *opaque)
1069 static void audio_capture(void *opaque, void *buf, int size)
1071 VncState *vs = opaque;
1073 vnc_lock_output(vs);
1074 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1075 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1076 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1077 vnc_write_u32(vs, size);
1078 vnc_write(vs, buf, size);
1079 vnc_unlock_output(vs);
1080 vnc_flush(vs);
1083 static void audio_add(VncState *vs)
1085 struct audio_capture_ops ops;
1087 if (vs->audio_cap) {
1088 error_report("audio already running");
1089 return;
1092 ops.notify = audio_capture_notify;
1093 ops.destroy = audio_capture_destroy;
1094 ops.capture = audio_capture;
1096 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1097 if (!vs->audio_cap) {
1098 error_report("Failed to add audio capture");
1102 static void audio_del(VncState *vs)
1104 if (vs->audio_cap) {
1105 AUD_del_capture(vs->audio_cap, vs);
1106 vs->audio_cap = NULL;
1110 static void vnc_disconnect_start(VncState *vs)
1112 if (vs->disconnecting) {
1113 return;
1115 trace_vnc_client_disconnect_start(vs, vs->ioc);
1116 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1117 if (vs->ioc_tag) {
1118 g_source_remove(vs->ioc_tag);
1119 vs->ioc_tag = 0;
1121 qio_channel_close(vs->ioc, NULL);
1122 vs->disconnecting = TRUE;
1125 void vnc_disconnect_finish(VncState *vs)
1127 int i;
1129 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1131 vnc_jobs_join(vs); /* Wait encoding jobs */
1133 vnc_lock_output(vs);
1134 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1136 buffer_free(&vs->input);
1137 buffer_free(&vs->output);
1139 qapi_free_VncClientInfo(vs->info);
1141 vnc_zlib_clear(vs);
1142 vnc_tight_clear(vs);
1143 vnc_zrle_clear(vs);
1145 #ifdef CONFIG_VNC_SASL
1146 vnc_sasl_client_cleanup(vs);
1147 #endif /* CONFIG_VNC_SASL */
1148 audio_del(vs);
1149 vnc_release_modifiers(vs);
1151 if (vs->mouse_mode_notifier.notify != NULL) {
1152 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1154 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1155 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1156 /* last client gone */
1157 vnc_update_server_surface(vs->vd);
1160 vnc_unlock_output(vs);
1162 qemu_mutex_destroy(&vs->output_mutex);
1163 if (vs->bh != NULL) {
1164 qemu_bh_delete(vs->bh);
1166 buffer_free(&vs->jobs_buffer);
1168 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1169 g_free(vs->lossy_rect[i]);
1171 g_free(vs->lossy_rect);
1173 object_unref(OBJECT(vs->ioc));
1174 vs->ioc = NULL;
1175 object_unref(OBJECT(vs->sioc));
1176 vs->sioc = NULL;
1177 g_free(vs);
1180 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1182 if (ret <= 0) {
1183 if (ret == 0) {
1184 trace_vnc_client_eof(vs, vs->ioc);
1185 vnc_disconnect_start(vs);
1186 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1187 trace_vnc_client_io_error(vs, vs->ioc,
1188 errp ? error_get_pretty(*errp) :
1189 "Unknown");
1190 vnc_disconnect_start(vs);
1193 if (errp) {
1194 error_free(*errp);
1195 *errp = NULL;
1197 return 0;
1199 return ret;
1203 void vnc_client_error(VncState *vs)
1205 VNC_DEBUG("Closing down client sock: protocol error\n");
1206 vnc_disconnect_start(vs);
1211 * Called to write a chunk of data to the client socket. The data may
1212 * be the raw data, or may have already been encoded by SASL.
1213 * The data will be written either straight onto the socket, or
1214 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1216 * NB, it is theoretically possible to have 2 layers of encryption,
1217 * both SASL, and this TLS layer. It is highly unlikely in practice
1218 * though, since SASL encryption will typically be a no-op if TLS
1219 * is active
1221 * Returns the number of bytes written, which may be less than
1222 * the requested 'datalen' if the socket would block. Returns
1223 * -1 on error, and disconnects the client socket.
1225 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1227 Error *err = NULL;
1228 ssize_t ret;
1229 ret = qio_channel_write(
1230 vs->ioc, (const char *)data, datalen, &err);
1231 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1232 return vnc_client_io_error(vs, ret, &err);
1237 * Called to write buffered data to the client socket, when not
1238 * using any SASL SSF encryption layers. Will write as much data
1239 * as possible without blocking. If all buffered data is written,
1240 * will switch the FD poll() handler back to read monitoring.
1242 * Returns the number of bytes written, which may be less than
1243 * the buffered output data if the socket would block. Returns
1244 * -1 on error, and disconnects the client socket.
1246 static ssize_t vnc_client_write_plain(VncState *vs)
1248 ssize_t ret;
1250 #ifdef CONFIG_VNC_SASL
1251 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1252 vs->output.buffer, vs->output.capacity, vs->output.offset,
1253 vs->sasl.waitWriteSSF);
1255 if (vs->sasl.conn &&
1256 vs->sasl.runSSF &&
1257 vs->sasl.waitWriteSSF) {
1258 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1259 if (ret)
1260 vs->sasl.waitWriteSSF -= ret;
1261 } else
1262 #endif /* CONFIG_VNC_SASL */
1263 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1264 if (!ret)
1265 return 0;
1267 buffer_advance(&vs->output, ret);
1269 if (vs->output.offset == 0) {
1270 if (vs->ioc_tag) {
1271 g_source_remove(vs->ioc_tag);
1273 vs->ioc_tag = qio_channel_add_watch(
1274 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1277 return ret;
1282 * First function called whenever there is data to be written to
1283 * the client socket. Will delegate actual work according to whether
1284 * SASL SSF layers are enabled (thus requiring encryption calls)
1286 static void vnc_client_write_locked(VncState *vs)
1288 #ifdef CONFIG_VNC_SASL
1289 if (vs->sasl.conn &&
1290 vs->sasl.runSSF &&
1291 !vs->sasl.waitWriteSSF) {
1292 vnc_client_write_sasl(vs);
1293 } else
1294 #endif /* CONFIG_VNC_SASL */
1296 vnc_client_write_plain(vs);
1300 static void vnc_client_write(VncState *vs)
1303 vnc_lock_output(vs);
1304 if (vs->output.offset) {
1305 vnc_client_write_locked(vs);
1306 } else if (vs->ioc != NULL) {
1307 if (vs->ioc_tag) {
1308 g_source_remove(vs->ioc_tag);
1310 vs->ioc_tag = qio_channel_add_watch(
1311 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1313 vnc_unlock_output(vs);
1316 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1318 vs->read_handler = func;
1319 vs->read_handler_expect = expecting;
1324 * Called to read a chunk of data from the client socket. The data may
1325 * be the raw data, or may need to be further decoded by SASL.
1326 * The data will be read either straight from to the socket, or
1327 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1329 * NB, it is theoretically possible to have 2 layers of encryption,
1330 * both SASL, and this TLS layer. It is highly unlikely in practice
1331 * though, since SASL encryption will typically be a no-op if TLS
1332 * is active
1334 * Returns the number of bytes read, which may be less than
1335 * the requested 'datalen' if the socket would block. Returns
1336 * -1 on error, and disconnects the client socket.
1338 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1340 ssize_t ret;
1341 Error *err = NULL;
1342 ret = qio_channel_read(
1343 vs->ioc, (char *)data, datalen, &err);
1344 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1345 return vnc_client_io_error(vs, ret, &err);
1350 * Called to read data from the client socket to the input buffer,
1351 * when not using any SASL SSF encryption layers. Will read as much
1352 * data as possible without blocking.
1354 * Returns the number of bytes read. Returns -1 on error, and
1355 * disconnects the client socket.
1357 static ssize_t vnc_client_read_plain(VncState *vs)
1359 ssize_t ret;
1360 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1361 vs->input.buffer, vs->input.capacity, vs->input.offset);
1362 buffer_reserve(&vs->input, 4096);
1363 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1364 if (!ret)
1365 return 0;
1366 vs->input.offset += ret;
1367 return ret;
1370 static void vnc_jobs_bh(void *opaque)
1372 VncState *vs = opaque;
1374 vnc_jobs_consume_buffer(vs);
1378 * First function called whenever there is more data to be read from
1379 * the client socket. Will delegate actual work according to whether
1380 * SASL SSF layers are enabled (thus requiring decryption calls)
1381 * Returns 0 on success, -1 if client disconnected
1383 static int vnc_client_read(VncState *vs)
1385 ssize_t ret;
1387 #ifdef CONFIG_VNC_SASL
1388 if (vs->sasl.conn && vs->sasl.runSSF)
1389 ret = vnc_client_read_sasl(vs);
1390 else
1391 #endif /* CONFIG_VNC_SASL */
1392 ret = vnc_client_read_plain(vs);
1393 if (!ret) {
1394 if (vs->disconnecting) {
1395 vnc_disconnect_finish(vs);
1396 return -1;
1398 return 0;
1401 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1402 size_t len = vs->read_handler_expect;
1403 int ret;
1405 ret = vs->read_handler(vs, vs->input.buffer, len);
1406 if (vs->disconnecting) {
1407 vnc_disconnect_finish(vs);
1408 return -1;
1411 if (!ret) {
1412 buffer_advance(&vs->input, len);
1413 } else {
1414 vs->read_handler_expect = ret;
1417 return 0;
1420 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1421 GIOCondition condition, void *opaque)
1423 VncState *vs = opaque;
1424 if (condition & G_IO_IN) {
1425 if (vnc_client_read(vs) < 0) {
1426 return TRUE;
1429 if (condition & G_IO_OUT) {
1430 vnc_client_write(vs);
1432 return TRUE;
1436 void vnc_write(VncState *vs, const void *data, size_t len)
1438 buffer_reserve(&vs->output, len);
1440 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1441 if (vs->ioc_tag) {
1442 g_source_remove(vs->ioc_tag);
1444 vs->ioc_tag = qio_channel_add_watch(
1445 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1448 buffer_append(&vs->output, data, len);
1451 void vnc_write_s32(VncState *vs, int32_t value)
1453 vnc_write_u32(vs, *(uint32_t *)&value);
1456 void vnc_write_u32(VncState *vs, uint32_t value)
1458 uint8_t buf[4];
1460 buf[0] = (value >> 24) & 0xFF;
1461 buf[1] = (value >> 16) & 0xFF;
1462 buf[2] = (value >> 8) & 0xFF;
1463 buf[3] = value & 0xFF;
1465 vnc_write(vs, buf, 4);
1468 void vnc_write_u16(VncState *vs, uint16_t value)
1470 uint8_t buf[2];
1472 buf[0] = (value >> 8) & 0xFF;
1473 buf[1] = value & 0xFF;
1475 vnc_write(vs, buf, 2);
1478 void vnc_write_u8(VncState *vs, uint8_t value)
1480 vnc_write(vs, (char *)&value, 1);
1483 void vnc_flush(VncState *vs)
1485 vnc_lock_output(vs);
1486 if (vs->ioc != NULL && vs->output.offset) {
1487 vnc_client_write_locked(vs);
1489 vnc_unlock_output(vs);
1492 static uint8_t read_u8(uint8_t *data, size_t offset)
1494 return data[offset];
1497 static uint16_t read_u16(uint8_t *data, size_t offset)
1499 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1502 static int32_t read_s32(uint8_t *data, size_t offset)
1504 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1505 (data[offset + 2] << 8) | data[offset + 3]);
1508 uint32_t read_u32(uint8_t *data, size_t offset)
1510 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1511 (data[offset + 2] << 8) | data[offset + 3]);
1514 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1518 static void check_pointer_type_change(Notifier *notifier, void *data)
1520 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1521 int absolute = qemu_input_is_absolute();
1523 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1524 vnc_lock_output(vs);
1525 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1526 vnc_write_u8(vs, 0);
1527 vnc_write_u16(vs, 1);
1528 vnc_framebuffer_update(vs, absolute, 0,
1529 pixman_image_get_width(vs->vd->server),
1530 pixman_image_get_height(vs->vd->server),
1531 VNC_ENCODING_POINTER_TYPE_CHANGE);
1532 vnc_unlock_output(vs);
1533 vnc_flush(vs);
1535 vs->absolute = absolute;
1538 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1540 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1541 [INPUT_BUTTON_LEFT] = 0x01,
1542 [INPUT_BUTTON_MIDDLE] = 0x02,
1543 [INPUT_BUTTON_RIGHT] = 0x04,
1544 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1545 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1547 QemuConsole *con = vs->vd->dcl.con;
1548 int width = pixman_image_get_width(vs->vd->server);
1549 int height = pixman_image_get_height(vs->vd->server);
1551 if (vs->last_bmask != button_mask) {
1552 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1553 vs->last_bmask = button_mask;
1556 if (vs->absolute) {
1557 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1558 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1559 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1560 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1561 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1562 } else {
1563 if (vs->last_x != -1) {
1564 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1565 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1567 vs->last_x = x;
1568 vs->last_y = y;
1570 qemu_input_event_sync();
1573 static void reset_keys(VncState *vs)
1575 int i;
1576 for(i = 0; i < 256; i++) {
1577 if (vs->modifiers_state[i]) {
1578 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1579 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1580 vs->modifiers_state[i] = 0;
1585 static void press_key(VncState *vs, int keysym)
1587 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1588 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1589 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1590 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1591 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1594 static void vnc_led_state_change(VncState *vs)
1596 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1597 return;
1600 vnc_lock_output(vs);
1601 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1602 vnc_write_u8(vs, 0);
1603 vnc_write_u16(vs, 1);
1604 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1605 vnc_write_u8(vs, vs->vd->ledstate);
1606 vnc_unlock_output(vs);
1607 vnc_flush(vs);
1610 static void kbd_leds(void *opaque, int ledstate)
1612 VncDisplay *vd = opaque;
1613 VncState *client;
1615 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1616 (ledstate & QEMU_NUM_LOCK_LED),
1617 (ledstate & QEMU_SCROLL_LOCK_LED));
1619 if (ledstate == vd->ledstate) {
1620 return;
1623 vd->ledstate = ledstate;
1625 QTAILQ_FOREACH(client, &vd->clients, next) {
1626 vnc_led_state_change(client);
1630 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1632 /* QEMU console switch */
1633 switch(keycode) {
1634 case 0x2a: /* Left Shift */
1635 case 0x36: /* Right Shift */
1636 case 0x1d: /* Left CTRL */
1637 case 0x9d: /* Right CTRL */
1638 case 0x38: /* Left ALT */
1639 case 0xb8: /* Right ALT */
1640 if (down)
1641 vs->modifiers_state[keycode] = 1;
1642 else
1643 vs->modifiers_state[keycode] = 0;
1644 break;
1645 case 0x02 ... 0x0a: /* '1' to '9' keys */
1646 if (vs->vd->dcl.con == NULL &&
1647 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1648 /* Reset the modifiers sent to the current console */
1649 reset_keys(vs);
1650 console_select(keycode - 0x02);
1651 return;
1653 break;
1654 case 0x3a: /* CapsLock */
1655 case 0x45: /* NumLock */
1656 if (down)
1657 vs->modifiers_state[keycode] ^= 1;
1658 break;
1661 /* Turn off the lock state sync logic if the client support the led
1662 state extension.
1664 if (down && vs->vd->lock_key_sync &&
1665 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1666 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1667 /* If the numlock state needs to change then simulate an additional
1668 keypress before sending this one. This will happen if the user
1669 toggles numlock away from the VNC window.
1671 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1672 if (!vs->modifiers_state[0x45]) {
1673 trace_vnc_key_sync_numlock(true);
1674 vs->modifiers_state[0x45] = 1;
1675 press_key(vs, 0xff7f);
1677 } else {
1678 if (vs->modifiers_state[0x45]) {
1679 trace_vnc_key_sync_numlock(false);
1680 vs->modifiers_state[0x45] = 0;
1681 press_key(vs, 0xff7f);
1686 if (down && vs->vd->lock_key_sync &&
1687 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1688 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1689 /* If the capslock state needs to change then simulate an additional
1690 keypress before sending this one. This will happen if the user
1691 toggles capslock away from the VNC window.
1693 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1694 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1695 int capslock = !!(vs->modifiers_state[0x3a]);
1696 if (capslock) {
1697 if (uppercase == shift) {
1698 trace_vnc_key_sync_capslock(false);
1699 vs->modifiers_state[0x3a] = 0;
1700 press_key(vs, 0xffe5);
1702 } else {
1703 if (uppercase != shift) {
1704 trace_vnc_key_sync_capslock(true);
1705 vs->modifiers_state[0x3a] = 1;
1706 press_key(vs, 0xffe5);
1711 if (qemu_console_is_graphic(NULL)) {
1712 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1713 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1714 } else {
1715 bool numlock = vs->modifiers_state[0x45];
1716 bool control = (vs->modifiers_state[0x1d] ||
1717 vs->modifiers_state[0x9d]);
1718 /* QEMU console emulation */
1719 if (down) {
1720 switch (keycode) {
1721 case 0x2a: /* Left Shift */
1722 case 0x36: /* Right Shift */
1723 case 0x1d: /* Left CTRL */
1724 case 0x9d: /* Right CTRL */
1725 case 0x38: /* Left ALT */
1726 case 0xb8: /* Right ALT */
1727 break;
1728 case 0xc8:
1729 kbd_put_keysym(QEMU_KEY_UP);
1730 break;
1731 case 0xd0:
1732 kbd_put_keysym(QEMU_KEY_DOWN);
1733 break;
1734 case 0xcb:
1735 kbd_put_keysym(QEMU_KEY_LEFT);
1736 break;
1737 case 0xcd:
1738 kbd_put_keysym(QEMU_KEY_RIGHT);
1739 break;
1740 case 0xd3:
1741 kbd_put_keysym(QEMU_KEY_DELETE);
1742 break;
1743 case 0xc7:
1744 kbd_put_keysym(QEMU_KEY_HOME);
1745 break;
1746 case 0xcf:
1747 kbd_put_keysym(QEMU_KEY_END);
1748 break;
1749 case 0xc9:
1750 kbd_put_keysym(QEMU_KEY_PAGEUP);
1751 break;
1752 case 0xd1:
1753 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1754 break;
1756 case 0x47:
1757 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1758 break;
1759 case 0x48:
1760 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1761 break;
1762 case 0x49:
1763 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1764 break;
1765 case 0x4b:
1766 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1767 break;
1768 case 0x4c:
1769 kbd_put_keysym('5');
1770 break;
1771 case 0x4d:
1772 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1773 break;
1774 case 0x4f:
1775 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1776 break;
1777 case 0x50:
1778 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1779 break;
1780 case 0x51:
1781 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1782 break;
1783 case 0x52:
1784 kbd_put_keysym('0');
1785 break;
1786 case 0x53:
1787 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1788 break;
1790 case 0xb5:
1791 kbd_put_keysym('/');
1792 break;
1793 case 0x37:
1794 kbd_put_keysym('*');
1795 break;
1796 case 0x4a:
1797 kbd_put_keysym('-');
1798 break;
1799 case 0x4e:
1800 kbd_put_keysym('+');
1801 break;
1802 case 0x9c:
1803 kbd_put_keysym('\n');
1804 break;
1806 default:
1807 if (control) {
1808 kbd_put_keysym(sym & 0x1f);
1809 } else {
1810 kbd_put_keysym(sym);
1812 break;
1818 static void vnc_release_modifiers(VncState *vs)
1820 static const int keycodes[] = {
1821 /* shift, control, alt keys, both left & right */
1822 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1824 int i, keycode;
1826 if (!qemu_console_is_graphic(NULL)) {
1827 return;
1829 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1830 keycode = keycodes[i];
1831 if (!vs->modifiers_state[keycode]) {
1832 continue;
1834 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1835 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1839 static const char *code2name(int keycode)
1841 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
1844 static void key_event(VncState *vs, int down, uint32_t sym)
1846 int keycode;
1847 int lsym = sym;
1849 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1850 lsym = lsym - 'A' + 'a';
1853 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1854 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1855 do_key_event(vs, down, keycode, sym);
1858 static void ext_key_event(VncState *vs, int down,
1859 uint32_t sym, uint16_t keycode)
1861 /* if the user specifies a keyboard layout, always use it */
1862 if (keyboard_layout) {
1863 key_event(vs, down, sym);
1864 } else {
1865 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1866 do_key_event(vs, down, keycode, sym);
1870 static void framebuffer_update_request(VncState *vs, int incremental,
1871 int x, int y, int w, int h)
1873 if (incremental) {
1874 if (vs->update != VNC_STATE_UPDATE_FORCE) {
1875 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
1877 } else {
1878 vs->update = VNC_STATE_UPDATE_FORCE;
1879 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1883 static void send_ext_key_event_ack(VncState *vs)
1885 vnc_lock_output(vs);
1886 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1887 vnc_write_u8(vs, 0);
1888 vnc_write_u16(vs, 1);
1889 vnc_framebuffer_update(vs, 0, 0,
1890 pixman_image_get_width(vs->vd->server),
1891 pixman_image_get_height(vs->vd->server),
1892 VNC_ENCODING_EXT_KEY_EVENT);
1893 vnc_unlock_output(vs);
1894 vnc_flush(vs);
1897 static void send_ext_audio_ack(VncState *vs)
1899 vnc_lock_output(vs);
1900 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1901 vnc_write_u8(vs, 0);
1902 vnc_write_u16(vs, 1);
1903 vnc_framebuffer_update(vs, 0, 0,
1904 pixman_image_get_width(vs->vd->server),
1905 pixman_image_get_height(vs->vd->server),
1906 VNC_ENCODING_AUDIO);
1907 vnc_unlock_output(vs);
1908 vnc_flush(vs);
1911 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1913 int i;
1914 unsigned int enc = 0;
1916 vs->features = 0;
1917 vs->vnc_encoding = 0;
1918 vs->tight.compression = 9;
1919 vs->tight.quality = -1; /* Lossless by default */
1920 vs->absolute = -1;
1923 * Start from the end because the encodings are sent in order of preference.
1924 * This way the preferred encoding (first encoding defined in the array)
1925 * will be set at the end of the loop.
1927 for (i = n_encodings - 1; i >= 0; i--) {
1928 enc = encodings[i];
1929 switch (enc) {
1930 case VNC_ENCODING_RAW:
1931 vs->vnc_encoding = enc;
1932 break;
1933 case VNC_ENCODING_COPYRECT:
1934 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1935 break;
1936 case VNC_ENCODING_HEXTILE:
1937 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1938 vs->vnc_encoding = enc;
1939 break;
1940 case VNC_ENCODING_TIGHT:
1941 vs->features |= VNC_FEATURE_TIGHT_MASK;
1942 vs->vnc_encoding = enc;
1943 break;
1944 #ifdef CONFIG_VNC_PNG
1945 case VNC_ENCODING_TIGHT_PNG:
1946 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
1947 vs->vnc_encoding = enc;
1948 break;
1949 #endif
1950 case VNC_ENCODING_ZLIB:
1951 vs->features |= VNC_FEATURE_ZLIB_MASK;
1952 vs->vnc_encoding = enc;
1953 break;
1954 case VNC_ENCODING_ZRLE:
1955 vs->features |= VNC_FEATURE_ZRLE_MASK;
1956 vs->vnc_encoding = enc;
1957 break;
1958 case VNC_ENCODING_ZYWRLE:
1959 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
1960 vs->vnc_encoding = enc;
1961 break;
1962 case VNC_ENCODING_DESKTOPRESIZE:
1963 vs->features |= VNC_FEATURE_RESIZE_MASK;
1964 break;
1965 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1966 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1967 break;
1968 case VNC_ENCODING_RICH_CURSOR:
1969 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
1970 if (vs->vd->cursor) {
1971 vnc_cursor_define(vs);
1973 break;
1974 case VNC_ENCODING_EXT_KEY_EVENT:
1975 send_ext_key_event_ack(vs);
1976 break;
1977 case VNC_ENCODING_AUDIO:
1978 send_ext_audio_ack(vs);
1979 break;
1980 case VNC_ENCODING_WMVi:
1981 vs->features |= VNC_FEATURE_WMVI_MASK;
1982 break;
1983 case VNC_ENCODING_LED_STATE:
1984 vs->features |= VNC_FEATURE_LED_STATE_MASK;
1985 break;
1986 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1987 vs->tight.compression = (enc & 0x0F);
1988 break;
1989 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1990 if (vs->vd->lossy) {
1991 vs->tight.quality = (enc & 0x0F);
1993 break;
1994 default:
1995 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1996 break;
1999 vnc_desktop_resize(vs);
2000 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2001 vnc_led_state_change(vs);
2004 static void set_pixel_conversion(VncState *vs)
2006 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2008 if (fmt == VNC_SERVER_FB_FORMAT) {
2009 vs->write_pixels = vnc_write_pixels_copy;
2010 vnc_hextile_set_pixel_conversion(vs, 0);
2011 } else {
2012 vs->write_pixels = vnc_write_pixels_generic;
2013 vnc_hextile_set_pixel_conversion(vs, 1);
2017 static void send_color_map(VncState *vs)
2019 int i;
2021 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2022 vnc_write_u8(vs, 0); /* padding */
2023 vnc_write_u16(vs, 0); /* first color */
2024 vnc_write_u16(vs, 256); /* # of colors */
2026 for (i = 0; i < 256; i++) {
2027 PixelFormat *pf = &vs->client_pf;
2029 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2030 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2031 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2035 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2036 int big_endian_flag, int true_color_flag,
2037 int red_max, int green_max, int blue_max,
2038 int red_shift, int green_shift, int blue_shift)
2040 if (!true_color_flag) {
2041 /* Expose a reasonable default 256 color map */
2042 bits_per_pixel = 8;
2043 red_max = 7;
2044 green_max = 7;
2045 blue_max = 3;
2046 red_shift = 0;
2047 green_shift = 3;
2048 blue_shift = 6;
2051 switch (bits_per_pixel) {
2052 case 8:
2053 case 16:
2054 case 32:
2055 break;
2056 default:
2057 vnc_client_error(vs);
2058 return;
2061 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2062 vs->client_pf.rbits = ctpopl(red_max);
2063 vs->client_pf.rshift = red_shift;
2064 vs->client_pf.rmask = red_max << red_shift;
2065 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2066 vs->client_pf.gbits = ctpopl(green_max);
2067 vs->client_pf.gshift = green_shift;
2068 vs->client_pf.gmask = green_max << green_shift;
2069 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2070 vs->client_pf.bbits = ctpopl(blue_max);
2071 vs->client_pf.bshift = blue_shift;
2072 vs->client_pf.bmask = blue_max << blue_shift;
2073 vs->client_pf.bits_per_pixel = bits_per_pixel;
2074 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2075 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2076 vs->client_be = big_endian_flag;
2078 if (!true_color_flag) {
2079 send_color_map(vs);
2082 set_pixel_conversion(vs);
2084 graphic_hw_invalidate(vs->vd->dcl.con);
2085 graphic_hw_update(vs->vd->dcl.con);
2088 static void pixel_format_message (VncState *vs) {
2089 char pad[3] = { 0, 0, 0 };
2091 vs->client_pf = qemu_default_pixelformat(32);
2093 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2094 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2096 #ifdef HOST_WORDS_BIGENDIAN
2097 vnc_write_u8(vs, 1); /* big-endian-flag */
2098 #else
2099 vnc_write_u8(vs, 0); /* big-endian-flag */
2100 #endif
2101 vnc_write_u8(vs, 1); /* true-color-flag */
2102 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2103 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2104 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2105 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2106 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2107 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2108 vnc_write(vs, pad, 3); /* padding */
2110 vnc_hextile_set_pixel_conversion(vs, 0);
2111 vs->write_pixels = vnc_write_pixels_copy;
2114 static void vnc_colordepth(VncState *vs)
2116 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2117 /* Sending a WMVi message to notify the client*/
2118 vnc_lock_output(vs);
2119 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2120 vnc_write_u8(vs, 0);
2121 vnc_write_u16(vs, 1); /* number of rects */
2122 vnc_framebuffer_update(vs, 0, 0,
2123 pixman_image_get_width(vs->vd->server),
2124 pixman_image_get_height(vs->vd->server),
2125 VNC_ENCODING_WMVi);
2126 pixel_format_message(vs);
2127 vnc_unlock_output(vs);
2128 vnc_flush(vs);
2129 } else {
2130 set_pixel_conversion(vs);
2134 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2136 int i;
2137 uint16_t limit;
2138 VncDisplay *vd = vs->vd;
2140 if (data[0] > 3) {
2141 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2144 switch (data[0]) {
2145 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2146 if (len == 1)
2147 return 20;
2149 set_pixel_format(vs, read_u8(data, 4),
2150 read_u8(data, 6), read_u8(data, 7),
2151 read_u16(data, 8), read_u16(data, 10),
2152 read_u16(data, 12), read_u8(data, 14),
2153 read_u8(data, 15), read_u8(data, 16));
2154 break;
2155 case VNC_MSG_CLIENT_SET_ENCODINGS:
2156 if (len == 1)
2157 return 4;
2159 if (len == 4) {
2160 limit = read_u16(data, 2);
2161 if (limit > 0)
2162 return 4 + (limit * 4);
2163 } else
2164 limit = read_u16(data, 2);
2166 for (i = 0; i < limit; i++) {
2167 int32_t val = read_s32(data, 4 + (i * 4));
2168 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2171 set_encodings(vs, (int32_t *)(data + 4), limit);
2172 break;
2173 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2174 if (len == 1)
2175 return 10;
2177 framebuffer_update_request(vs,
2178 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2179 read_u16(data, 6), read_u16(data, 8));
2180 break;
2181 case VNC_MSG_CLIENT_KEY_EVENT:
2182 if (len == 1)
2183 return 8;
2185 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2186 break;
2187 case VNC_MSG_CLIENT_POINTER_EVENT:
2188 if (len == 1)
2189 return 6;
2191 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2192 break;
2193 case VNC_MSG_CLIENT_CUT_TEXT:
2194 if (len == 1) {
2195 return 8;
2197 if (len == 8) {
2198 uint32_t dlen = read_u32(data, 4);
2199 if (dlen > (1 << 20)) {
2200 error_report("vnc: client_cut_text msg payload has %u bytes"
2201 " which exceeds our limit of 1MB.", dlen);
2202 vnc_client_error(vs);
2203 break;
2205 if (dlen > 0) {
2206 return 8 + dlen;
2210 client_cut_text(vs, read_u32(data, 4), data + 8);
2211 break;
2212 case VNC_MSG_CLIENT_QEMU:
2213 if (len == 1)
2214 return 2;
2216 switch (read_u8(data, 1)) {
2217 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2218 if (len == 2)
2219 return 12;
2221 ext_key_event(vs, read_u16(data, 2),
2222 read_u32(data, 4), read_u32(data, 8));
2223 break;
2224 case VNC_MSG_CLIENT_QEMU_AUDIO:
2225 if (len == 2)
2226 return 4;
2228 switch (read_u16 (data, 2)) {
2229 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2230 audio_add(vs);
2231 break;
2232 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2233 audio_del(vs);
2234 break;
2235 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2236 if (len == 4)
2237 return 10;
2238 switch (read_u8(data, 4)) {
2239 case 0: vs->as.fmt = AUD_FMT_U8; break;
2240 case 1: vs->as.fmt = AUD_FMT_S8; break;
2241 case 2: vs->as.fmt = AUD_FMT_U16; break;
2242 case 3: vs->as.fmt = AUD_FMT_S16; break;
2243 case 4: vs->as.fmt = AUD_FMT_U32; break;
2244 case 5: vs->as.fmt = AUD_FMT_S32; break;
2245 default:
2246 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2247 vnc_client_error(vs);
2248 break;
2250 vs->as.nchannels = read_u8(data, 5);
2251 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2252 VNC_DEBUG("Invalid audio channel count %d\n",
2253 read_u8(data, 5));
2254 vnc_client_error(vs);
2255 break;
2257 vs->as.freq = read_u32(data, 6);
2258 break;
2259 default:
2260 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2261 vnc_client_error(vs);
2262 break;
2264 break;
2266 default:
2267 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2268 vnc_client_error(vs);
2269 break;
2271 break;
2272 default:
2273 VNC_DEBUG("Msg: %d\n", data[0]);
2274 vnc_client_error(vs);
2275 break;
2278 vnc_read_when(vs, protocol_client_msg, 1);
2279 return 0;
2282 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2284 char buf[1024];
2285 VncShareMode mode;
2286 int size;
2288 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2289 switch (vs->vd->share_policy) {
2290 case VNC_SHARE_POLICY_IGNORE:
2292 * Ignore the shared flag. Nothing to do here.
2294 * Doesn't conform to the rfb spec but is traditional qemu
2295 * behavior, thus left here as option for compatibility
2296 * reasons.
2298 break;
2299 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2301 * Policy: Allow clients ask for exclusive access.
2303 * Implementation: When a client asks for exclusive access,
2304 * disconnect all others. Shared connects are allowed as long
2305 * as no exclusive connection exists.
2307 * This is how the rfb spec suggests to handle the shared flag.
2309 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2310 VncState *client;
2311 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2312 if (vs == client) {
2313 continue;
2315 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2316 client->share_mode != VNC_SHARE_MODE_SHARED) {
2317 continue;
2319 vnc_disconnect_start(client);
2322 if (mode == VNC_SHARE_MODE_SHARED) {
2323 if (vs->vd->num_exclusive > 0) {
2324 vnc_disconnect_start(vs);
2325 return 0;
2328 break;
2329 case VNC_SHARE_POLICY_FORCE_SHARED:
2331 * Policy: Shared connects only.
2332 * Implementation: Disallow clients asking for exclusive access.
2334 * Useful for shared desktop sessions where you don't want
2335 * someone forgetting to say -shared when running the vnc
2336 * client disconnect everybody else.
2338 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2339 vnc_disconnect_start(vs);
2340 return 0;
2342 break;
2344 vnc_set_share_mode(vs, mode);
2346 if (vs->vd->num_shared > vs->vd->connections_limit) {
2347 vnc_disconnect_start(vs);
2348 return 0;
2351 vs->client_width = pixman_image_get_width(vs->vd->server);
2352 vs->client_height = pixman_image_get_height(vs->vd->server);
2353 vnc_write_u16(vs, vs->client_width);
2354 vnc_write_u16(vs, vs->client_height);
2356 pixel_format_message(vs);
2358 if (qemu_name) {
2359 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2360 if (size > sizeof(buf)) {
2361 size = sizeof(buf);
2363 } else {
2364 size = snprintf(buf, sizeof(buf), "QEMU");
2367 vnc_write_u32(vs, size);
2368 vnc_write(vs, buf, size);
2369 vnc_flush(vs);
2371 vnc_client_cache_auth(vs);
2372 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2374 vnc_read_when(vs, protocol_client_msg, 1);
2376 return 0;
2379 void start_client_init(VncState *vs)
2381 vnc_read_when(vs, protocol_client_init, 1);
2384 static void make_challenge(VncState *vs)
2386 int i;
2388 srand(time(NULL)+getpid()+getpid()*987654+rand());
2390 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2391 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2394 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2396 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2397 size_t i, pwlen;
2398 unsigned char key[8];
2399 time_t now = time(NULL);
2400 QCryptoCipher *cipher = NULL;
2401 Error *err = NULL;
2403 if (!vs->vd->password) {
2404 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2405 goto reject;
2407 if (vs->vd->expires < now) {
2408 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2409 goto reject;
2412 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2414 /* Calculate the expected challenge response */
2415 pwlen = strlen(vs->vd->password);
2416 for (i=0; i<sizeof(key); i++)
2417 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2419 cipher = qcrypto_cipher_new(
2420 QCRYPTO_CIPHER_ALG_DES_RFB,
2421 QCRYPTO_CIPHER_MODE_ECB,
2422 key, G_N_ELEMENTS(key),
2423 &err);
2424 if (!cipher) {
2425 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2426 error_get_pretty(err));
2427 error_free(err);
2428 goto reject;
2431 if (qcrypto_cipher_encrypt(cipher,
2432 vs->challenge,
2433 response,
2434 VNC_AUTH_CHALLENGE_SIZE,
2435 &err) < 0) {
2436 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2437 error_get_pretty(err));
2438 error_free(err);
2439 goto reject;
2442 /* Compare expected vs actual challenge response */
2443 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2444 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2445 goto reject;
2446 } else {
2447 trace_vnc_auth_pass(vs, vs->auth);
2448 vnc_write_u32(vs, 0); /* Accept auth */
2449 vnc_flush(vs);
2451 start_client_init(vs);
2454 qcrypto_cipher_free(cipher);
2455 return 0;
2457 reject:
2458 vnc_write_u32(vs, 1); /* Reject auth */
2459 if (vs->minor >= 8) {
2460 static const char err[] = "Authentication failed";
2461 vnc_write_u32(vs, sizeof(err));
2462 vnc_write(vs, err, sizeof(err));
2464 vnc_flush(vs);
2465 vnc_client_error(vs);
2466 qcrypto_cipher_free(cipher);
2467 return 0;
2470 void start_auth_vnc(VncState *vs)
2472 make_challenge(vs);
2473 /* Send client a 'random' challenge */
2474 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2475 vnc_flush(vs);
2477 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2481 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2483 /* We only advertise 1 auth scheme at a time, so client
2484 * must pick the one we sent. Verify this */
2485 if (data[0] != vs->auth) { /* Reject auth */
2486 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2487 vnc_write_u32(vs, 1);
2488 if (vs->minor >= 8) {
2489 static const char err[] = "Authentication failed";
2490 vnc_write_u32(vs, sizeof(err));
2491 vnc_write(vs, err, sizeof(err));
2493 vnc_client_error(vs);
2494 } else { /* Accept requested auth */
2495 trace_vnc_auth_start(vs, vs->auth);
2496 switch (vs->auth) {
2497 case VNC_AUTH_NONE:
2498 if (vs->minor >= 8) {
2499 vnc_write_u32(vs, 0); /* Accept auth completion */
2500 vnc_flush(vs);
2502 trace_vnc_auth_pass(vs, vs->auth);
2503 start_client_init(vs);
2504 break;
2506 case VNC_AUTH_VNC:
2507 start_auth_vnc(vs);
2508 break;
2510 case VNC_AUTH_VENCRYPT:
2511 start_auth_vencrypt(vs);
2512 break;
2514 #ifdef CONFIG_VNC_SASL
2515 case VNC_AUTH_SASL:
2516 start_auth_sasl(vs);
2517 break;
2518 #endif /* CONFIG_VNC_SASL */
2520 default: /* Should not be possible, but just in case */
2521 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2522 vnc_write_u8(vs, 1);
2523 if (vs->minor >= 8) {
2524 static const char err[] = "Authentication failed";
2525 vnc_write_u32(vs, sizeof(err));
2526 vnc_write(vs, err, sizeof(err));
2528 vnc_client_error(vs);
2531 return 0;
2534 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2536 char local[13];
2538 memcpy(local, version, 12);
2539 local[12] = 0;
2541 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2542 VNC_DEBUG("Malformed protocol version %s\n", local);
2543 vnc_client_error(vs);
2544 return 0;
2546 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2547 if (vs->major != 3 ||
2548 (vs->minor != 3 &&
2549 vs->minor != 4 &&
2550 vs->minor != 5 &&
2551 vs->minor != 7 &&
2552 vs->minor != 8)) {
2553 VNC_DEBUG("Unsupported client version\n");
2554 vnc_write_u32(vs, VNC_AUTH_INVALID);
2555 vnc_flush(vs);
2556 vnc_client_error(vs);
2557 return 0;
2559 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2560 * as equivalent to v3.3 by servers
2562 if (vs->minor == 4 || vs->minor == 5)
2563 vs->minor = 3;
2565 if (vs->minor == 3) {
2566 trace_vnc_auth_start(vs, vs->auth);
2567 if (vs->auth == VNC_AUTH_NONE) {
2568 vnc_write_u32(vs, vs->auth);
2569 vnc_flush(vs);
2570 trace_vnc_auth_pass(vs, vs->auth);
2571 start_client_init(vs);
2572 } else if (vs->auth == VNC_AUTH_VNC) {
2573 VNC_DEBUG("Tell client VNC auth\n");
2574 vnc_write_u32(vs, vs->auth);
2575 vnc_flush(vs);
2576 start_auth_vnc(vs);
2577 } else {
2578 trace_vnc_auth_fail(vs, vs->auth,
2579 "Unsupported auth method for v3.3", "");
2580 vnc_write_u32(vs, VNC_AUTH_INVALID);
2581 vnc_flush(vs);
2582 vnc_client_error(vs);
2584 } else {
2585 vnc_write_u8(vs, 1); /* num auth */
2586 vnc_write_u8(vs, vs->auth);
2587 vnc_read_when(vs, protocol_client_auth, 1);
2588 vnc_flush(vs);
2591 return 0;
2594 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2596 struct VncSurface *vs = &vd->guest;
2598 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2601 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2603 int i, j;
2605 w = (x + w) / VNC_STAT_RECT;
2606 h = (y + h) / VNC_STAT_RECT;
2607 x /= VNC_STAT_RECT;
2608 y /= VNC_STAT_RECT;
2610 for (j = y; j <= h; j++) {
2611 for (i = x; i <= w; i++) {
2612 vs->lossy_rect[j][i] = 1;
2617 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2619 VncState *vs;
2620 int sty = y / VNC_STAT_RECT;
2621 int stx = x / VNC_STAT_RECT;
2622 int has_dirty = 0;
2624 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2625 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2627 QTAILQ_FOREACH(vs, &vd->clients, next) {
2628 int j;
2630 /* kernel send buffers are full -> refresh later */
2631 if (vs->output.offset) {
2632 continue;
2635 if (!vs->lossy_rect[sty][stx]) {
2636 continue;
2639 vs->lossy_rect[sty][stx] = 0;
2640 for (j = 0; j < VNC_STAT_RECT; ++j) {
2641 bitmap_set(vs->dirty[y + j],
2642 x / VNC_DIRTY_PIXELS_PER_BIT,
2643 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2645 has_dirty++;
2648 return has_dirty;
2651 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2653 int width = MIN(pixman_image_get_width(vd->guest.fb),
2654 pixman_image_get_width(vd->server));
2655 int height = MIN(pixman_image_get_height(vd->guest.fb),
2656 pixman_image_get_height(vd->server));
2657 int x, y;
2658 struct timeval res;
2659 int has_dirty = 0;
2661 for (y = 0; y < height; y += VNC_STAT_RECT) {
2662 for (x = 0; x < width; x += VNC_STAT_RECT) {
2663 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2665 rect->updated = false;
2669 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2671 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2672 return has_dirty;
2674 vd->guest.last_freq_check = *tv;
2676 for (y = 0; y < height; y += VNC_STAT_RECT) {
2677 for (x = 0; x < width; x += VNC_STAT_RECT) {
2678 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2679 int count = ARRAY_SIZE(rect->times);
2680 struct timeval min, max;
2682 if (!timerisset(&rect->times[count - 1])) {
2683 continue ;
2686 max = rect->times[(rect->idx + count - 1) % count];
2687 qemu_timersub(tv, &max, &res);
2689 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2690 rect->freq = 0;
2691 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2692 memset(rect->times, 0, sizeof (rect->times));
2693 continue ;
2696 min = rect->times[rect->idx];
2697 max = rect->times[(rect->idx + count - 1) % count];
2698 qemu_timersub(&max, &min, &res);
2700 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2701 rect->freq /= count;
2702 rect->freq = 1. / rect->freq;
2705 return has_dirty;
2708 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2710 int i, j;
2711 double total = 0;
2712 int num = 0;
2714 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2715 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2717 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2718 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2719 total += vnc_stat_rect(vs->vd, i, j)->freq;
2720 num++;
2724 if (num) {
2725 return total / num;
2726 } else {
2727 return 0;
2731 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2733 VncRectStat *rect;
2735 rect = vnc_stat_rect(vd, x, y);
2736 if (rect->updated) {
2737 return ;
2739 rect->times[rect->idx] = *tv;
2740 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2741 rect->updated = true;
2744 static int vnc_refresh_server_surface(VncDisplay *vd)
2746 int width = MIN(pixman_image_get_width(vd->guest.fb),
2747 pixman_image_get_width(vd->server));
2748 int height = MIN(pixman_image_get_height(vd->guest.fb),
2749 pixman_image_get_height(vd->server));
2750 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2751 uint8_t *guest_row0 = NULL, *server_row0;
2752 VncState *vs;
2753 int has_dirty = 0;
2754 pixman_image_t *tmpbuf = NULL;
2756 struct timeval tv = { 0, 0 };
2758 if (!vd->non_adaptive) {
2759 gettimeofday(&tv, NULL);
2760 has_dirty = vnc_update_stats(vd, &tv);
2764 * Walk through the guest dirty map.
2765 * Check and copy modified bits from guest to server surface.
2766 * Update server dirty map.
2768 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2769 server_stride = guest_stride = guest_ll =
2770 pixman_image_get_stride(vd->server);
2771 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2772 server_stride);
2773 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2774 int width = pixman_image_get_width(vd->server);
2775 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2776 } else {
2777 int guest_bpp =
2778 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2779 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2780 guest_stride = pixman_image_get_stride(vd->guest.fb);
2781 guest_ll = pixman_image_get_width(vd->guest.fb) * (DIV_ROUND_UP(guest_bpp, 8));
2783 line_bytes = MIN(server_stride, guest_ll);
2785 for (;;) {
2786 int x;
2787 uint8_t *guest_ptr, *server_ptr;
2788 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2789 height * VNC_DIRTY_BPL(&vd->guest),
2790 y * VNC_DIRTY_BPL(&vd->guest));
2791 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2792 /* no more dirty bits */
2793 break;
2795 y = offset / VNC_DIRTY_BPL(&vd->guest);
2796 x = offset % VNC_DIRTY_BPL(&vd->guest);
2798 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2800 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2801 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2802 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2803 } else {
2804 guest_ptr = guest_row0 + y * guest_stride;
2806 guest_ptr += x * cmp_bytes;
2808 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2809 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2810 int _cmp_bytes = cmp_bytes;
2811 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2812 continue;
2814 if ((x + 1) * cmp_bytes > line_bytes) {
2815 _cmp_bytes = line_bytes - x * cmp_bytes;
2817 assert(_cmp_bytes >= 0);
2818 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2819 continue;
2821 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2822 if (!vd->non_adaptive) {
2823 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2824 y, &tv);
2826 QTAILQ_FOREACH(vs, &vd->clients, next) {
2827 set_bit(x, vs->dirty[y]);
2829 has_dirty++;
2832 y++;
2834 qemu_pixman_image_unref(tmpbuf);
2835 return has_dirty;
2838 static void vnc_refresh(DisplayChangeListener *dcl)
2840 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2841 VncState *vs, *vn;
2842 int has_dirty, rects = 0;
2844 if (QTAILQ_EMPTY(&vd->clients)) {
2845 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2846 return;
2849 graphic_hw_update(vd->dcl.con);
2851 if (vnc_trylock_display(vd)) {
2852 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2853 return;
2856 has_dirty = vnc_refresh_server_surface(vd);
2857 vnc_unlock_display(vd);
2859 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2860 rects += vnc_update_client(vs, has_dirty);
2861 /* vs might be free()ed here */
2864 if (has_dirty && rects) {
2865 vd->dcl.update_interval /= 2;
2866 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2867 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2869 } else {
2870 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2871 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2872 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2877 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2878 bool skipauth, bool websocket)
2880 VncState *vs = g_new0(VncState, 1);
2881 bool first_client = QTAILQ_EMPTY(&vd->clients);
2882 int i;
2884 trace_vnc_client_connect(vs, sioc);
2885 vs->sioc = sioc;
2886 object_ref(OBJECT(vs->sioc));
2887 vs->ioc = QIO_CHANNEL(sioc);
2888 object_ref(OBJECT(vs->ioc));
2889 vs->vd = vd;
2891 buffer_init(&vs->input, "vnc-input/%p", sioc);
2892 buffer_init(&vs->output, "vnc-output/%p", sioc);
2893 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2895 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2896 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2897 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2898 #ifdef CONFIG_VNC_JPEG
2899 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2900 #endif
2901 #ifdef CONFIG_VNC_PNG
2902 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2903 #endif
2904 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2905 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2906 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2907 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2909 if (skipauth) {
2910 vs->auth = VNC_AUTH_NONE;
2911 vs->subauth = VNC_AUTH_INVALID;
2912 } else {
2913 if (websocket) {
2914 vs->auth = vd->ws_auth;
2915 vs->subauth = VNC_AUTH_INVALID;
2916 } else {
2917 vs->auth = vd->auth;
2918 vs->subauth = vd->subauth;
2921 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2922 sioc, websocket, vs->auth, vs->subauth);
2924 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
2925 for (i = 0; i < VNC_STAT_ROWS; ++i) {
2926 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
2929 VNC_DEBUG("New client on socket %p\n", vs->sioc);
2930 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2931 qio_channel_set_blocking(vs->ioc, false, NULL);
2932 if (vs->ioc_tag) {
2933 g_source_remove(vs->ioc_tag);
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 void vnc_free_addresses(SocketAddress ***retsaddr,
3526 size_t *retnsaddr)
3528 size_t i;
3530 for (i = 0; i < *retnsaddr; i++) {
3531 qapi_free_SocketAddress((*retsaddr)[i]);
3533 g_free(*retsaddr);
3535 *retsaddr = NULL;
3536 *retnsaddr = 0;
3539 static int vnc_display_get_addresses(QemuOpts *opts,
3540 bool reverse,
3541 SocketAddress ***retsaddr,
3542 size_t *retnsaddr,
3543 SocketAddress ***retwsaddr,
3544 size_t *retnwsaddr,
3545 Error **errp)
3547 SocketAddress *saddr = NULL;
3548 SocketAddress *wsaddr = NULL;
3549 QemuOptsIter addriter;
3550 const char *addr;
3551 int to = qemu_opt_get_number(opts, "to", 0);
3552 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3553 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3554 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3555 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3556 int displaynum = -1;
3557 int ret = -1;
3559 *retsaddr = NULL;
3560 *retnsaddr = 0;
3561 *retwsaddr = NULL;
3562 *retnwsaddr = 0;
3564 addr = qemu_opt_get(opts, "vnc");
3565 if (addr == NULL || g_str_equal(addr, "none")) {
3566 ret = 0;
3567 goto cleanup;
3569 if (qemu_opt_get(opts, "websocket") &&
3570 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3571 error_setg(errp,
3572 "SHA1 hash support is required for websockets");
3573 goto cleanup;
3576 qemu_opt_iter_init(&addriter, opts, "vnc");
3577 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3578 int rv;
3579 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3580 has_ipv4, has_ipv6,
3581 ipv4, ipv6,
3582 &saddr, errp);
3583 if (rv < 0) {
3584 goto cleanup;
3586 /* Historical compat - first listen address can be used
3587 * to set the default websocket port
3589 if (displaynum == -1) {
3590 displaynum = rv;
3592 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3593 (*retsaddr)[(*retnsaddr)++] = saddr;
3596 /* If we had multiple primary displays, we don't do defaults
3597 * for websocket, and require explicit config instead. */
3598 if (*retnsaddr > 1) {
3599 displaynum = -1;
3602 qemu_opt_iter_init(&addriter, opts, "websocket");
3603 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3604 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3605 has_ipv4, has_ipv6,
3606 ipv4, ipv6,
3607 &wsaddr, errp) < 0) {
3608 goto cleanup;
3611 /* Historical compat - if only a single listen address was
3612 * provided, then this is used to set the default listen
3613 * address for websocket too
3615 if (*retnsaddr == 1 &&
3616 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3617 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3618 g_str_equal(wsaddr->u.inet.host, "") &&
3619 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3620 g_free(wsaddr->u.inet.host);
3621 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3624 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3625 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3628 ret = 0;
3629 cleanup:
3630 if (ret < 0) {
3631 vnc_free_addresses(retsaddr, retnsaddr);
3632 vnc_free_addresses(retwsaddr, retnwsaddr);
3634 return ret;
3637 static int vnc_display_connect(VncDisplay *vd,
3638 SocketAddress **saddr,
3639 size_t nsaddr,
3640 SocketAddress **wsaddr,
3641 size_t nwsaddr,
3642 Error **errp)
3644 /* connect to viewer */
3645 QIOChannelSocket *sioc = NULL;
3646 if (nwsaddr != 0) {
3647 error_setg(errp, "Cannot use websockets in reverse mode");
3648 return -1;
3650 if (nsaddr != 1) {
3651 error_setg(errp, "Expected a single address in reverse mode");
3652 return -1;
3654 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3655 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3656 sioc = qio_channel_socket_new();
3657 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3658 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3659 return -1;
3661 vnc_connect(vd, sioc, false, false);
3662 object_unref(OBJECT(sioc));
3663 return 0;
3667 static int vnc_display_listen_addr(VncDisplay *vd,
3668 SocketAddress *addr,
3669 const char *name,
3670 QIOChannelSocket ***lsock,
3671 guint **lsock_tag,
3672 size_t *nlsock,
3673 Error **errp)
3675 QIODNSResolver *resolver = qio_dns_resolver_get_instance();
3676 SocketAddress **rawaddrs = NULL;
3677 size_t nrawaddrs = 0;
3678 Error *listenerr = NULL;
3679 bool listening = false;
3680 size_t i;
3682 if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,
3683 &rawaddrs, errp) < 0) {
3684 return -1;
3687 for (i = 0; i < nrawaddrs; i++) {
3688 QIOChannelSocket *sioc = qio_channel_socket_new();
3690 qio_channel_set_name(QIO_CHANNEL(sioc), name);
3691 if (qio_channel_socket_listen_sync(
3692 sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
3693 object_unref(OBJECT(sioc));
3694 continue;
3696 listening = true;
3697 (*nlsock)++;
3698 *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);
3699 *lsock_tag = g_renew(guint, *lsock_tag, *nlsock);
3701 (*lsock)[*nlsock - 1] = sioc;
3702 (*lsock_tag)[*nlsock - 1] = 0;
3705 for (i = 0; i < nrawaddrs; i++) {
3706 qapi_free_SocketAddress(rawaddrs[i]);
3708 g_free(rawaddrs);
3710 if (listenerr) {
3711 if (!listening) {
3712 error_propagate(errp, listenerr);
3713 return -1;
3714 } else {
3715 error_free(listenerr);
3719 for (i = 0; i < *nlsock; i++) {
3720 (*lsock_tag)[i] = qio_channel_add_watch(
3721 QIO_CHANNEL((*lsock)[i]),
3722 G_IO_IN, vnc_listen_io, vd, NULL);
3725 return 0;
3729 static int vnc_display_listen(VncDisplay *vd,
3730 SocketAddress **saddr,
3731 size_t nsaddr,
3732 SocketAddress **wsaddr,
3733 size_t nwsaddr,
3734 Error **errp)
3736 size_t i;
3738 for (i = 0; i < nsaddr; i++) {
3739 if (vnc_display_listen_addr(vd, saddr[i],
3740 "vnc-listen",
3741 &vd->lsock,
3742 &vd->lsock_tag,
3743 &vd->nlsock,
3744 errp) < 0) {
3745 return -1;
3748 for (i = 0; i < nwsaddr; i++) {
3749 if (vnc_display_listen_addr(vd, wsaddr[i],
3750 "vnc-ws-listen",
3751 &vd->lwebsock,
3752 &vd->lwebsock_tag,
3753 &vd->nlwebsock,
3754 errp) < 0) {
3755 return -1;
3759 return 0;
3763 void vnc_display_open(const char *id, Error **errp)
3765 VncDisplay *vd = vnc_display_find(id);
3766 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3767 SocketAddress **saddr = NULL, **wsaddr = NULL;
3768 size_t nsaddr, nwsaddr;
3769 const char *share, *device_id;
3770 QemuConsole *con;
3771 bool password = false;
3772 bool reverse = false;
3773 const char *credid;
3774 bool sasl = false;
3775 #ifdef CONFIG_VNC_SASL
3776 int saslErr;
3777 #endif
3778 int acl = 0;
3779 int lock_key_sync = 1;
3780 int key_delay_ms;
3782 if (!vd) {
3783 error_setg(errp, "VNC display not active");
3784 return;
3786 vnc_display_close(vd);
3788 if (!opts) {
3789 return;
3792 reverse = qemu_opt_get_bool(opts, "reverse", false);
3793 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3794 &wsaddr, &nwsaddr, errp) < 0) {
3795 goto fail;
3798 password = qemu_opt_get_bool(opts, "password", false);
3799 if (password) {
3800 if (fips_get_state()) {
3801 error_setg(errp,
3802 "VNC password auth disabled due to FIPS mode, "
3803 "consider using the VeNCrypt or SASL authentication "
3804 "methods as an alternative");
3805 goto fail;
3807 if (!qcrypto_cipher_supports(
3808 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3809 error_setg(errp,
3810 "Cipher backend does not support DES RFB algorithm");
3811 goto fail;
3815 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3816 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
3817 sasl = qemu_opt_get_bool(opts, "sasl", false);
3818 #ifndef CONFIG_VNC_SASL
3819 if (sasl) {
3820 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3821 goto fail;
3823 #endif /* CONFIG_VNC_SASL */
3824 credid = qemu_opt_get(opts, "tls-creds");
3825 if (credid) {
3826 Object *creds;
3827 if (qemu_opt_get(opts, "tls") ||
3828 qemu_opt_get(opts, "x509") ||
3829 qemu_opt_get(opts, "x509verify")) {
3830 error_setg(errp,
3831 "'tls-creds' parameter is mutually exclusive with "
3832 "'tls', 'x509' and 'x509verify' parameters");
3833 goto fail;
3836 creds = object_resolve_path_component(
3837 object_get_objects_root(), credid);
3838 if (!creds) {
3839 error_setg(errp, "No TLS credentials with id '%s'",
3840 credid);
3841 goto fail;
3843 vd->tlscreds = (QCryptoTLSCreds *)
3844 object_dynamic_cast(creds,
3845 TYPE_QCRYPTO_TLS_CREDS);
3846 if (!vd->tlscreds) {
3847 error_setg(errp, "Object with id '%s' is not TLS credentials",
3848 credid);
3849 goto fail;
3851 object_ref(OBJECT(vd->tlscreds));
3853 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3854 error_setg(errp,
3855 "Expecting TLS credentials with a server endpoint");
3856 goto fail;
3858 } else {
3859 const char *path;
3860 bool tls = false, x509 = false, x509verify = false;
3861 tls = qemu_opt_get_bool(opts, "tls", false);
3862 if (tls) {
3863 path = qemu_opt_get(opts, "x509");
3865 if (path) {
3866 x509 = true;
3867 } else {
3868 path = qemu_opt_get(opts, "x509verify");
3869 if (path) {
3870 x509 = true;
3871 x509verify = true;
3874 vd->tlscreds = vnc_display_create_creds(x509,
3875 x509verify,
3876 path,
3877 vd->id,
3878 errp);
3879 if (!vd->tlscreds) {
3880 goto fail;
3884 acl = qemu_opt_get_bool(opts, "acl", false);
3886 share = qemu_opt_get(opts, "share");
3887 if (share) {
3888 if (strcmp(share, "ignore") == 0) {
3889 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
3890 } else if (strcmp(share, "allow-exclusive") == 0) {
3891 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3892 } else if (strcmp(share, "force-shared") == 0) {
3893 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3894 } else {
3895 error_setg(errp, "unknown vnc share= option");
3896 goto fail;
3898 } else {
3899 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3901 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3903 #ifdef CONFIG_VNC_JPEG
3904 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
3905 #endif
3906 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3907 /* adaptive updates are only used with tight encoding and
3908 * if lossy updates are enabled so we can disable all the
3909 * calculations otherwise */
3910 if (!vd->lossy) {
3911 vd->non_adaptive = true;
3914 if (acl) {
3915 if (strcmp(vd->id, "default") == 0) {
3916 vd->tlsaclname = g_strdup("vnc.x509dname");
3917 } else {
3918 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
3920 qemu_acl_init(vd->tlsaclname);
3922 #ifdef CONFIG_VNC_SASL
3923 if (acl && sasl) {
3924 char *aclname;
3926 if (strcmp(vd->id, "default") == 0) {
3927 aclname = g_strdup("vnc.username");
3928 } else {
3929 aclname = g_strdup_printf("vnc.%s.username", vd->id);
3931 vd->sasl.acl = qemu_acl_init(aclname);
3932 g_free(aclname);
3934 #endif
3936 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
3937 vd->tlscreds, password,
3938 sasl, false, errp) < 0) {
3939 goto fail;
3941 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
3943 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
3944 vd->tlscreds, password,
3945 sasl, true, errp) < 0) {
3946 goto fail;
3948 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
3950 #ifdef CONFIG_VNC_SASL
3951 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3952 error_setg(errp, "Failed to initialize SASL auth: %s",
3953 sasl_errstring(saslErr, NULL, NULL));
3954 goto fail;
3956 #endif
3957 vd->lock_key_sync = lock_key_sync;
3958 if (lock_key_sync) {
3959 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
3961 vd->ledstate = 0;
3962 vd->key_delay_ms = key_delay_ms;
3964 device_id = qemu_opt_get(opts, "display");
3965 if (device_id) {
3966 int head = qemu_opt_get_number(opts, "head", 0);
3967 Error *err = NULL;
3969 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3970 if (err) {
3971 error_propagate(errp, err);
3972 goto fail;
3974 } else {
3975 con = NULL;
3978 if (con != vd->dcl.con) {
3979 unregister_displaychangelistener(&vd->dcl);
3980 vd->dcl.con = con;
3981 register_displaychangelistener(&vd->dcl);
3984 if (saddr == NULL) {
3985 goto cleanup;
3988 if (reverse) {
3989 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3990 goto fail;
3992 } else {
3993 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3994 goto fail;
3998 if (qemu_opt_get(opts, "to")) {
3999 vnc_display_print_local_addr(vd);
4002 cleanup:
4003 vnc_free_addresses(&saddr, &nsaddr);
4004 vnc_free_addresses(&wsaddr, &nwsaddr);
4005 return;
4007 fail:
4008 vnc_display_close(vd);
4009 goto cleanup;
4012 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4014 VncDisplay *vd = vnc_display_find(id);
4015 QIOChannelSocket *sioc;
4017 if (!vd) {
4018 return;
4021 sioc = qio_channel_socket_new_fd(csock, NULL);
4022 if (sioc) {
4023 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4024 vnc_connect(vd, sioc, skipauth, false);
4025 object_unref(OBJECT(sioc));
4029 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4031 int i = 2;
4032 char *id;
4034 id = g_strdup("default");
4035 while (qemu_opts_find(olist, id)) {
4036 g_free(id);
4037 id = g_strdup_printf("vnc%d", i++);
4039 qemu_opts_set_id(opts, id);
4042 QemuOpts *vnc_parse(const char *str, Error **errp)
4044 QemuOptsList *olist = qemu_find_opts("vnc");
4045 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
4046 const char *id;
4048 if (!opts) {
4049 return NULL;
4052 id = qemu_opts_id(opts);
4053 if (!id) {
4054 /* auto-assign id if not present */
4055 vnc_auto_assign_id(olist, opts);
4057 return opts;
4060 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4062 Error *local_err = NULL;
4063 char *id = (char *)qemu_opts_id(opts);
4065 assert(id);
4066 vnc_display_init(id);
4067 vnc_display_open(id, &local_err);
4068 if (local_err != NULL) {
4069 error_reportf_err(local_err, "Failed to start VNC server: ");
4070 exit(1);
4072 return 0;
4075 static void vnc_register_config(void)
4077 qemu_add_opts(&qemu_vnc_opts);
4079 opts_init(vnc_register_config);