ui: avoid crash if vnc client disconnects with writes pending
[qemu/ar7.git] / ui / vnc.c
blobe3f857cc903071ea3e5c1f51bb1ca47faf851ab2
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "vnc.h"
29 #include "vnc-jobs.h"
30 #include "trace.h"
31 #include "hw/qdev.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
36 #include "qemu/acl.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
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_KIND_INET:
116 info->host = g_strdup(addr->u.inet.data->host);
117 info->service = g_strdup(addr->u.inet.data->port);
118 if (addr->u.inet.data->ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_KIND_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.data->path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 default:
132 error_setg(errp, "Unsupported socket kind %d",
133 addr->type);
134 break;
137 return;
140 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
141 VncBasicInfo *info,
142 Error **errp)
144 SocketAddress *addr = NULL;
146 addr = qio_channel_socket_get_local_address(ioc, errp);
147 if (!addr) {
148 return;
151 vnc_init_basic_info(addr, info, errp);
152 qapi_free_SocketAddress(addr);
155 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
156 VncBasicInfo *info,
157 Error **errp)
159 SocketAddress *addr = NULL;
161 addr = qio_channel_socket_get_remote_address(ioc, errp);
162 if (!addr) {
163 return;
166 vnc_init_basic_info(addr, info, errp);
167 qapi_free_SocketAddress(addr);
170 static const char *vnc_auth_name(VncDisplay *vd) {
171 switch (vd->auth) {
172 case VNC_AUTH_INVALID:
173 return "invalid";
174 case VNC_AUTH_NONE:
175 return "none";
176 case VNC_AUTH_VNC:
177 return "vnc";
178 case VNC_AUTH_RA2:
179 return "ra2";
180 case VNC_AUTH_RA2NE:
181 return "ra2ne";
182 case VNC_AUTH_TIGHT:
183 return "tight";
184 case VNC_AUTH_ULTRA:
185 return "ultra";
186 case VNC_AUTH_TLS:
187 return "tls";
188 case VNC_AUTH_VENCRYPT:
189 switch (vd->subauth) {
190 case VNC_AUTH_VENCRYPT_PLAIN:
191 return "vencrypt+plain";
192 case VNC_AUTH_VENCRYPT_TLSNONE:
193 return "vencrypt+tls+none";
194 case VNC_AUTH_VENCRYPT_TLSVNC:
195 return "vencrypt+tls+vnc";
196 case VNC_AUTH_VENCRYPT_TLSPLAIN:
197 return "vencrypt+tls+plain";
198 case VNC_AUTH_VENCRYPT_X509NONE:
199 return "vencrypt+x509+none";
200 case VNC_AUTH_VENCRYPT_X509VNC:
201 return "vencrypt+x509+vnc";
202 case VNC_AUTH_VENCRYPT_X509PLAIN:
203 return "vencrypt+x509+plain";
204 case VNC_AUTH_VENCRYPT_TLSSASL:
205 return "vencrypt+tls+sasl";
206 case VNC_AUTH_VENCRYPT_X509SASL:
207 return "vencrypt+x509+sasl";
208 default:
209 return "vencrypt";
211 case VNC_AUTH_SASL:
212 return "sasl";
214 return "unknown";
217 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
219 VncServerInfo *info;
220 Error *err = NULL;
222 info = g_malloc(sizeof(*info));
223 vnc_init_basic_info_from_server_addr(vd->lsock,
224 qapi_VncServerInfo_base(info), &err);
225 info->has_auth = true;
226 info->auth = g_strdup(vnc_auth_name(vd));
227 if (err) {
228 qapi_free_VncServerInfo(info);
229 info = NULL;
230 error_free(err);
232 return info;
235 static void vnc_client_cache_auth(VncState *client)
237 if (!client->info) {
238 return;
241 if (client->tls) {
242 client->info->x509_dname =
243 qcrypto_tls_session_get_peer_name(client->tls);
244 client->info->has_x509_dname =
245 client->info->x509_dname != NULL;
247 #ifdef CONFIG_VNC_SASL
248 if (client->sasl.conn &&
249 client->sasl.username) {
250 client->info->has_sasl_username = true;
251 client->info->sasl_username = g_strdup(client->sasl.username);
253 #endif
256 static void vnc_client_cache_addr(VncState *client)
258 Error *err = NULL;
260 client->info = g_malloc0(sizeof(*client->info));
261 vnc_init_basic_info_from_remote_addr(client->sioc,
262 qapi_VncClientInfo_base(client->info),
263 &err);
264 if (err) {
265 qapi_free_VncClientInfo(client->info);
266 client->info = NULL;
267 error_free(err);
271 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
273 VncServerInfo *si;
275 if (!vs->info) {
276 return;
279 si = vnc_server_info_get(vs->vd);
280 if (!si) {
281 return;
284 switch (event) {
285 case QAPI_EVENT_VNC_CONNECTED:
286 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
287 &error_abort);
288 break;
289 case QAPI_EVENT_VNC_INITIALIZED:
290 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
291 break;
292 case QAPI_EVENT_VNC_DISCONNECTED:
293 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
294 break;
295 default:
296 break;
299 qapi_free_VncServerInfo(si);
302 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
304 VncClientInfo *info;
305 Error *err = NULL;
307 info = g_malloc0(sizeof(*info));
309 vnc_init_basic_info_from_remote_addr(client->sioc,
310 qapi_VncClientInfo_base(info),
311 &err);
312 if (err) {
313 error_free(err);
314 qapi_free_VncClientInfo(info);
315 return NULL;
318 info->websocket = client->websocket;
320 if (client->tls) {
321 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
322 info->has_x509_dname = info->x509_dname != NULL;
324 #ifdef CONFIG_VNC_SASL
325 if (client->sasl.conn && client->sasl.username) {
326 info->has_sasl_username = true;
327 info->sasl_username = g_strdup(client->sasl.username);
329 #endif
331 return info;
334 static VncDisplay *vnc_display_find(const char *id)
336 VncDisplay *vd;
338 if (id == NULL) {
339 return QTAILQ_FIRST(&vnc_displays);
341 QTAILQ_FOREACH(vd, &vnc_displays, next) {
342 if (strcmp(id, vd->id) == 0) {
343 return vd;
346 return NULL;
349 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
351 VncClientInfoList *cinfo, *prev = NULL;
352 VncState *client;
354 QTAILQ_FOREACH(client, &vd->clients, next) {
355 cinfo = g_new0(VncClientInfoList, 1);
356 cinfo->value = qmp_query_vnc_client(client);
357 cinfo->next = prev;
358 prev = cinfo;
360 return prev;
363 VncInfo *qmp_query_vnc(Error **errp)
365 VncInfo *info = g_malloc0(sizeof(*info));
366 VncDisplay *vd = vnc_display_find(NULL);
367 SocketAddress *addr = NULL;
369 if (vd == NULL || !vd->enabled) {
370 info->enabled = false;
371 } else {
372 info->enabled = true;
374 /* for compatibility with the original command */
375 info->has_clients = true;
376 info->clients = qmp_query_client_list(vd);
378 if (vd->lsock == NULL) {
379 return info;
382 addr = qio_channel_socket_get_local_address(vd->lsock, errp);
383 if (!addr) {
384 goto out_error;
387 switch (addr->type) {
388 case SOCKET_ADDRESS_KIND_INET:
389 info->host = g_strdup(addr->u.inet.data->host);
390 info->service = g_strdup(addr->u.inet.data->port);
391 if (addr->u.inet.data->ipv6) {
392 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
393 } else {
394 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
396 break;
398 case SOCKET_ADDRESS_KIND_UNIX:
399 info->host = g_strdup("");
400 info->service = g_strdup(addr->u.q_unix.data->path);
401 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
402 break;
404 default:
405 error_setg(errp, "Unsupported socket kind %d",
406 addr->type);
407 goto out_error;
410 info->has_host = true;
411 info->has_service = true;
412 info->has_family = true;
414 info->has_auth = true;
415 info->auth = g_strdup(vnc_auth_name(vd));
418 qapi_free_SocketAddress(addr);
419 return info;
421 out_error:
422 qapi_free_SocketAddress(addr);
423 qapi_free_VncInfo(info);
424 return NULL;
427 static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,
428 bool websocket,
429 VncBasicInfoList *prev)
431 VncBasicInfoList *list;
432 VncBasicInfo *info;
433 Error *err = NULL;
434 SocketAddress *addr;
436 addr = qio_channel_socket_get_local_address(ioc, &err);
437 if (!addr) {
438 error_free(err);
439 return prev;
442 info = g_new0(VncBasicInfo, 1);
443 vnc_init_basic_info(addr, info, &err);
444 qapi_free_SocketAddress(addr);
445 if (err) {
446 qapi_free_VncBasicInfo(info);
447 error_free(err);
448 return prev;
450 info->websocket = websocket;
452 list = g_new0(VncBasicInfoList, 1);
453 list->value = info;
454 list->next = prev;
455 return list;
458 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
460 switch (vd->auth) {
461 case VNC_AUTH_VNC:
462 info->auth = VNC_PRIMARY_AUTH_VNC;
463 break;
464 case VNC_AUTH_RA2:
465 info->auth = VNC_PRIMARY_AUTH_RA2;
466 break;
467 case VNC_AUTH_RA2NE:
468 info->auth = VNC_PRIMARY_AUTH_RA2NE;
469 break;
470 case VNC_AUTH_TIGHT:
471 info->auth = VNC_PRIMARY_AUTH_TIGHT;
472 break;
473 case VNC_AUTH_ULTRA:
474 info->auth = VNC_PRIMARY_AUTH_ULTRA;
475 break;
476 case VNC_AUTH_TLS:
477 info->auth = VNC_PRIMARY_AUTH_TLS;
478 break;
479 case VNC_AUTH_VENCRYPT:
480 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
481 info->has_vencrypt = true;
482 switch (vd->subauth) {
483 case VNC_AUTH_VENCRYPT_PLAIN:
484 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
485 break;
486 case VNC_AUTH_VENCRYPT_TLSNONE:
487 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
488 break;
489 case VNC_AUTH_VENCRYPT_TLSVNC:
490 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
491 break;
492 case VNC_AUTH_VENCRYPT_TLSPLAIN:
493 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
494 break;
495 case VNC_AUTH_VENCRYPT_X509NONE:
496 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
497 break;
498 case VNC_AUTH_VENCRYPT_X509VNC:
499 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
500 break;
501 case VNC_AUTH_VENCRYPT_X509PLAIN:
502 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
503 break;
504 case VNC_AUTH_VENCRYPT_TLSSASL:
505 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
506 break;
507 case VNC_AUTH_VENCRYPT_X509SASL:
508 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
509 break;
510 default:
511 info->has_vencrypt = false;
512 break;
514 break;
515 case VNC_AUTH_SASL:
516 info->auth = VNC_PRIMARY_AUTH_SASL;
517 break;
518 case VNC_AUTH_NONE:
519 default:
520 info->auth = VNC_PRIMARY_AUTH_NONE;
521 break;
525 VncInfo2List *qmp_query_vnc_servers(Error **errp)
527 VncInfo2List *item, *prev = NULL;
528 VncInfo2 *info;
529 VncDisplay *vd;
530 DeviceState *dev;
532 QTAILQ_FOREACH(vd, &vnc_displays, next) {
533 info = g_new0(VncInfo2, 1);
534 info->id = g_strdup(vd->id);
535 info->clients = qmp_query_client_list(vd);
536 qmp_query_auth(vd, info);
537 if (vd->dcl.con) {
538 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
539 "device", NULL));
540 info->has_display = true;
541 info->display = g_strdup(dev->id);
543 if (vd->lsock != NULL) {
544 info->server = qmp_query_server_entry(
545 vd->lsock, false, info->server);
547 if (vd->lwebsock != NULL) {
548 info->server = qmp_query_server_entry(
549 vd->lwebsock, true, info->server);
552 item = g_new0(VncInfo2List, 1);
553 item->value = info;
554 item->next = prev;
555 prev = item;
557 return prev;
560 /* TODO
561 1) Get the queue working for IO.
562 2) there is some weirdness when using the -S option (the screen is grey
563 and not totally invalidated
564 3) resolutions > 1024
567 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
568 static void vnc_disconnect_start(VncState *vs);
570 static void vnc_colordepth(VncState *vs);
571 static void framebuffer_update_request(VncState *vs, int incremental,
572 int x_position, int y_position,
573 int w, int h);
574 static void vnc_refresh(DisplayChangeListener *dcl);
575 static int vnc_refresh_server_surface(VncDisplay *vd);
577 static int vnc_width(VncDisplay *vd)
579 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
580 VNC_DIRTY_PIXELS_PER_BIT));
583 static int vnc_height(VncDisplay *vd)
585 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
588 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
589 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
590 VncDisplay *vd,
591 int x, int y, int w, int h)
593 int width = vnc_width(vd);
594 int height = vnc_height(vd);
596 /* this is needed this to ensure we updated all affected
597 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
598 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
599 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
601 x = MIN(x, width);
602 y = MIN(y, height);
603 w = MIN(x + w, width) - x;
604 h = MIN(y + h, height);
606 for (; y < h; y++) {
607 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
608 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
612 static void vnc_dpy_update(DisplayChangeListener *dcl,
613 int x, int y, int w, int h)
615 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
616 struct VncSurface *s = &vd->guest;
618 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
621 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
622 int32_t encoding)
624 vnc_write_u16(vs, x);
625 vnc_write_u16(vs, y);
626 vnc_write_u16(vs, w);
627 vnc_write_u16(vs, h);
629 vnc_write_s32(vs, encoding);
633 static void vnc_desktop_resize(VncState *vs)
635 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
636 return;
638 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
639 vs->client_height == pixman_image_get_height(vs->vd->server)) {
640 return;
642 vs->client_width = pixman_image_get_width(vs->vd->server);
643 vs->client_height = pixman_image_get_height(vs->vd->server);
644 vnc_lock_output(vs);
645 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
646 vnc_write_u8(vs, 0);
647 vnc_write_u16(vs, 1); /* number of rects */
648 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
649 VNC_ENCODING_DESKTOPRESIZE);
650 vnc_unlock_output(vs);
651 vnc_flush(vs);
654 static void vnc_abort_display_jobs(VncDisplay *vd)
656 VncState *vs;
658 QTAILQ_FOREACH(vs, &vd->clients, next) {
659 vnc_lock_output(vs);
660 vs->abort = true;
661 vnc_unlock_output(vs);
663 QTAILQ_FOREACH(vs, &vd->clients, next) {
664 vnc_jobs_join(vs);
666 QTAILQ_FOREACH(vs, &vd->clients, next) {
667 vnc_lock_output(vs);
668 vs->abort = false;
669 vnc_unlock_output(vs);
673 int vnc_server_fb_stride(VncDisplay *vd)
675 return pixman_image_get_stride(vd->server);
678 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
680 uint8_t *ptr;
682 ptr = (uint8_t *)pixman_image_get_data(vd->server);
683 ptr += y * vnc_server_fb_stride(vd);
684 ptr += x * VNC_SERVER_FB_BYTES;
685 return ptr;
688 static void vnc_update_server_surface(VncDisplay *vd)
690 qemu_pixman_image_unref(vd->server);
691 vd->server = NULL;
693 if (QTAILQ_EMPTY(&vd->clients)) {
694 return;
697 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
698 vnc_width(vd),
699 vnc_height(vd),
700 NULL, 0);
703 static void vnc_dpy_switch(DisplayChangeListener *dcl,
704 DisplaySurface *surface)
706 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
707 VncState *vs;
708 int width, height;
710 vnc_abort_display_jobs(vd);
711 vd->ds = surface;
713 /* server surface */
714 vnc_update_server_surface(vd);
716 /* guest surface */
717 qemu_pixman_image_unref(vd->guest.fb);
718 vd->guest.fb = pixman_image_ref(surface->image);
719 vd->guest.format = surface->format;
720 width = vnc_width(vd);
721 height = vnc_height(vd);
722 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
723 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
724 width, height);
726 QTAILQ_FOREACH(vs, &vd->clients, next) {
727 vnc_colordepth(vs);
728 vnc_desktop_resize(vs);
729 if (vs->vd->cursor) {
730 vnc_cursor_define(vs);
732 memset(vs->dirty, 0x00, sizeof(vs->dirty));
733 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
734 width, height);
738 /* fastest code */
739 static void vnc_write_pixels_copy(VncState *vs,
740 void *pixels, int size)
742 vnc_write(vs, pixels, size);
745 /* slowest but generic code. */
746 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
748 uint8_t r, g, b;
750 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
751 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
752 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
753 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
754 #else
755 # error need some bits here if you change VNC_SERVER_FB_FORMAT
756 #endif
757 v = (r << vs->client_pf.rshift) |
758 (g << vs->client_pf.gshift) |
759 (b << vs->client_pf.bshift);
760 switch (vs->client_pf.bytes_per_pixel) {
761 case 1:
762 buf[0] = v;
763 break;
764 case 2:
765 if (vs->client_be) {
766 buf[0] = v >> 8;
767 buf[1] = v;
768 } else {
769 buf[1] = v >> 8;
770 buf[0] = v;
772 break;
773 default:
774 case 4:
775 if (vs->client_be) {
776 buf[0] = v >> 24;
777 buf[1] = v >> 16;
778 buf[2] = v >> 8;
779 buf[3] = v;
780 } else {
781 buf[3] = v >> 24;
782 buf[2] = v >> 16;
783 buf[1] = v >> 8;
784 buf[0] = v;
786 break;
790 static void vnc_write_pixels_generic(VncState *vs,
791 void *pixels1, int size)
793 uint8_t buf[4];
795 if (VNC_SERVER_FB_BYTES == 4) {
796 uint32_t *pixels = pixels1;
797 int n, i;
798 n = size >> 2;
799 for (i = 0; i < n; i++) {
800 vnc_convert_pixel(vs, buf, pixels[i]);
801 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
806 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
808 int i;
809 uint8_t *row;
810 VncDisplay *vd = vs->vd;
812 row = vnc_server_fb_ptr(vd, x, y);
813 for (i = 0; i < h; i++) {
814 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
815 row += vnc_server_fb_stride(vd);
817 return 1;
820 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
822 int n = 0;
823 bool encode_raw = false;
824 size_t saved_offs = vs->output.offset;
826 switch(vs->vnc_encoding) {
827 case VNC_ENCODING_ZLIB:
828 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
829 break;
830 case VNC_ENCODING_HEXTILE:
831 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
832 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
833 break;
834 case VNC_ENCODING_TIGHT:
835 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
836 break;
837 case VNC_ENCODING_TIGHT_PNG:
838 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
839 break;
840 case VNC_ENCODING_ZRLE:
841 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
842 break;
843 case VNC_ENCODING_ZYWRLE:
844 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
845 break;
846 default:
847 encode_raw = true;
848 break;
851 /* If the client has the same pixel format as our internal buffer and
852 * a RAW encoding would need less space fall back to RAW encoding to
853 * save bandwidth and processing power in the client. */
854 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
855 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
856 vs->output.offset = saved_offs;
857 encode_raw = true;
860 if (encode_raw) {
861 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
862 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
865 return n;
868 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
870 /* send bitblit op to the vnc client */
871 vnc_lock_output(vs);
872 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
873 vnc_write_u8(vs, 0);
874 vnc_write_u16(vs, 1); /* number of rects */
875 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
876 vnc_write_u16(vs, src_x);
877 vnc_write_u16(vs, src_y);
878 vnc_unlock_output(vs);
879 vnc_flush(vs);
882 static void vnc_dpy_copy(DisplayChangeListener *dcl,
883 int src_x, int src_y,
884 int dst_x, int dst_y, int w, int h)
886 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
887 VncState *vs, *vn;
888 uint8_t *src_row;
889 uint8_t *dst_row;
890 int i, x, y, pitch, inc, w_lim, s;
891 int cmp_bytes;
893 if (!vd->server) {
894 /* no client connected */
895 return;
898 vnc_refresh_server_surface(vd);
899 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
900 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
901 vs->force_update = 1;
902 vnc_update_client(vs, 1, true);
903 /* vs might be free()ed here */
907 /* do bitblit op on the local surface too */
908 pitch = vnc_server_fb_stride(vd);
909 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
910 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
911 y = dst_y;
912 inc = 1;
913 if (dst_y > src_y) {
914 /* copy backwards */
915 src_row += pitch * (h-1);
916 dst_row += pitch * (h-1);
917 pitch = -pitch;
918 y = dst_y + h - 1;
919 inc = -1;
921 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
922 if (w_lim < 0) {
923 w_lim = w;
924 } else {
925 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
927 for (i = 0; i < h; i++) {
928 for (x = 0; x <= w_lim;
929 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
930 if (x == w_lim) {
931 if ((s = w - w_lim) == 0)
932 break;
933 } else if (!x) {
934 s = (VNC_DIRTY_PIXELS_PER_BIT -
935 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
936 s = MIN(s, w_lim);
937 } else {
938 s = VNC_DIRTY_PIXELS_PER_BIT;
940 cmp_bytes = s * VNC_SERVER_FB_BYTES;
941 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
942 continue;
943 memmove(dst_row, src_row, cmp_bytes);
944 QTAILQ_FOREACH(vs, &vd->clients, next) {
945 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
946 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
947 vs->dirty[y]);
951 src_row += pitch - w * VNC_SERVER_FB_BYTES;
952 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
953 y += inc;
956 QTAILQ_FOREACH(vs, &vd->clients, next) {
957 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
958 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
963 static void vnc_mouse_set(DisplayChangeListener *dcl,
964 int x, int y, int visible)
966 /* can we ask the client(s) to move the pointer ??? */
969 static int vnc_cursor_define(VncState *vs)
971 QEMUCursor *c = vs->vd->cursor;
972 int isize;
974 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
975 vnc_lock_output(vs);
976 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
977 vnc_write_u8(vs, 0); /* padding */
978 vnc_write_u16(vs, 1); /* # of rects */
979 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
980 VNC_ENCODING_RICH_CURSOR);
981 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
982 vnc_write_pixels_generic(vs, c->data, isize);
983 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
984 vnc_unlock_output(vs);
985 return 0;
987 return -1;
990 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
991 QEMUCursor *c)
993 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
994 VncState *vs;
996 cursor_put(vd->cursor);
997 g_free(vd->cursor_mask);
999 vd->cursor = c;
1000 cursor_get(vd->cursor);
1001 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1002 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1003 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1005 QTAILQ_FOREACH(vs, &vd->clients, next) {
1006 vnc_cursor_define(vs);
1010 static int find_and_clear_dirty_height(VncState *vs,
1011 int y, int last_x, int x, int height)
1013 int h;
1015 for (h = 1; h < (height - y); h++) {
1016 if (!test_bit(last_x, vs->dirty[y + h])) {
1017 break;
1019 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1022 return h;
1025 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1027 vs->has_dirty += has_dirty;
1028 if (vs->need_update && !vs->disconnecting) {
1029 VncDisplay *vd = vs->vd;
1030 VncJob *job;
1031 int y;
1032 int height, width;
1033 int n = 0;
1035 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1036 /* kernel send buffers are full -> drop frames to throttle */
1037 return 0;
1039 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1040 return 0;
1043 * Send screen updates to the vnc client using the server
1044 * surface and server dirty map. guest surface updates
1045 * happening in parallel don't disturb us, the next pass will
1046 * send them to the client.
1048 job = vnc_job_new(vs);
1050 height = pixman_image_get_height(vd->server);
1051 width = pixman_image_get_width(vd->server);
1053 y = 0;
1054 for (;;) {
1055 int x, h;
1056 unsigned long x2;
1057 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1058 height * VNC_DIRTY_BPL(vs),
1059 y * VNC_DIRTY_BPL(vs));
1060 if (offset == height * VNC_DIRTY_BPL(vs)) {
1061 /* no more dirty bits */
1062 break;
1064 y = offset / VNC_DIRTY_BPL(vs);
1065 x = offset % VNC_DIRTY_BPL(vs);
1066 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1067 VNC_DIRTY_BPL(vs), x);
1068 bitmap_clear(vs->dirty[y], x, x2 - x);
1069 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1070 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1071 if (x2 > x) {
1072 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1073 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1075 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1076 y += h;
1077 if (y == height) {
1078 break;
1083 vnc_job_push(job);
1084 if (sync) {
1085 vnc_jobs_join(vs);
1087 vs->force_update = 0;
1088 vs->has_dirty = 0;
1089 return n;
1092 if (vs->disconnecting) {
1093 vnc_disconnect_finish(vs);
1094 } else if (sync) {
1095 vnc_jobs_join(vs);
1098 return 0;
1101 /* audio */
1102 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1104 VncState *vs = opaque;
1106 switch (cmd) {
1107 case AUD_CNOTIFY_DISABLE:
1108 vnc_lock_output(vs);
1109 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1110 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1111 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1112 vnc_unlock_output(vs);
1113 vnc_flush(vs);
1114 break;
1116 case AUD_CNOTIFY_ENABLE:
1117 vnc_lock_output(vs);
1118 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1119 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1120 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1121 vnc_unlock_output(vs);
1122 vnc_flush(vs);
1123 break;
1127 static void audio_capture_destroy(void *opaque)
1131 static void audio_capture(void *opaque, void *buf, int size)
1133 VncState *vs = opaque;
1135 vnc_lock_output(vs);
1136 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1137 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1138 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1139 vnc_write_u32(vs, size);
1140 vnc_write(vs, buf, size);
1141 vnc_unlock_output(vs);
1142 vnc_flush(vs);
1145 static void audio_add(VncState *vs)
1147 struct audio_capture_ops ops;
1149 if (vs->audio_cap) {
1150 error_report("audio already running");
1151 return;
1154 ops.notify = audio_capture_notify;
1155 ops.destroy = audio_capture_destroy;
1156 ops.capture = audio_capture;
1158 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1159 if (!vs->audio_cap) {
1160 error_report("Failed to add audio capture");
1164 static void audio_del(VncState *vs)
1166 if (vs->audio_cap) {
1167 AUD_del_capture(vs->audio_cap, vs);
1168 vs->audio_cap = NULL;
1172 static void vnc_disconnect_start(VncState *vs)
1174 if (vs->disconnecting) {
1175 return;
1177 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1178 if (vs->ioc_tag) {
1179 g_source_remove(vs->ioc_tag);
1181 qio_channel_close(vs->ioc, NULL);
1182 vs->disconnecting = TRUE;
1185 void vnc_disconnect_finish(VncState *vs)
1187 int i;
1189 vnc_jobs_join(vs); /* Wait encoding jobs */
1191 vnc_lock_output(vs);
1192 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1194 buffer_free(&vs->input);
1195 buffer_free(&vs->output);
1197 qapi_free_VncClientInfo(vs->info);
1199 vnc_zlib_clear(vs);
1200 vnc_tight_clear(vs);
1201 vnc_zrle_clear(vs);
1203 #ifdef CONFIG_VNC_SASL
1204 vnc_sasl_client_cleanup(vs);
1205 #endif /* CONFIG_VNC_SASL */
1206 audio_del(vs);
1207 vnc_release_modifiers(vs);
1209 if (vs->initialized) {
1210 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1211 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1212 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1213 /* last client gone */
1214 vnc_update_server_surface(vs->vd);
1218 if (vs->vd->lock_key_sync)
1219 qemu_remove_led_event_handler(vs->led);
1220 vnc_unlock_output(vs);
1222 qemu_mutex_destroy(&vs->output_mutex);
1223 if (vs->bh != NULL) {
1224 qemu_bh_delete(vs->bh);
1226 buffer_free(&vs->jobs_buffer);
1228 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1229 g_free(vs->lossy_rect[i]);
1231 g_free(vs->lossy_rect);
1233 object_unref(OBJECT(vs->ioc));
1234 vs->ioc = NULL;
1235 object_unref(OBJECT(vs->sioc));
1236 vs->sioc = NULL;
1237 g_free(vs);
1240 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1242 if (ret <= 0) {
1243 if (ret == 0) {
1244 VNC_DEBUG("Closing down client sock: EOF\n");
1245 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1246 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1247 ret, errp ? error_get_pretty(*errp) : "Unknown");
1250 vnc_disconnect_start(vs);
1251 if (errp) {
1252 error_free(*errp);
1253 *errp = NULL;
1255 return 0;
1257 return ret;
1261 void vnc_client_error(VncState *vs)
1263 VNC_DEBUG("Closing down client sock: protocol error\n");
1264 vnc_disconnect_start(vs);
1269 * Called to write a chunk of data to the client socket. The data may
1270 * be the raw data, or may have already been encoded by SASL.
1271 * The data will be written either straight onto the socket, or
1272 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1274 * NB, it is theoretically possible to have 2 layers of encryption,
1275 * both SASL, and this TLS layer. It is highly unlikely in practice
1276 * though, since SASL encryption will typically be a no-op if TLS
1277 * is active
1279 * Returns the number of bytes written, which may be less than
1280 * the requested 'datalen' if the socket would block. Returns
1281 * -1 on error, and disconnects the client socket.
1283 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1285 Error *err = NULL;
1286 ssize_t ret;
1287 ret = qio_channel_write(
1288 vs->ioc, (const char *)data, datalen, &err);
1289 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1290 return vnc_client_io_error(vs, ret, &err);
1295 * Called to write buffered data to the client socket, when not
1296 * using any SASL SSF encryption layers. Will write as much data
1297 * as possible without blocking. If all buffered data is written,
1298 * will switch the FD poll() handler back to read monitoring.
1300 * Returns the number of bytes written, which may be less than
1301 * the buffered output data if the socket would block. Returns
1302 * -1 on error, and disconnects the client socket.
1304 static ssize_t vnc_client_write_plain(VncState *vs)
1306 ssize_t ret;
1308 #ifdef CONFIG_VNC_SASL
1309 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1310 vs->output.buffer, vs->output.capacity, vs->output.offset,
1311 vs->sasl.waitWriteSSF);
1313 if (vs->sasl.conn &&
1314 vs->sasl.runSSF &&
1315 vs->sasl.waitWriteSSF) {
1316 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1317 if (ret)
1318 vs->sasl.waitWriteSSF -= ret;
1319 } else
1320 #endif /* CONFIG_VNC_SASL */
1321 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1322 if (!ret)
1323 return 0;
1325 buffer_advance(&vs->output, ret);
1327 if (vs->output.offset == 0) {
1328 if (vs->ioc_tag) {
1329 g_source_remove(vs->ioc_tag);
1331 vs->ioc_tag = qio_channel_add_watch(
1332 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1335 return ret;
1340 * First function called whenever there is data to be written to
1341 * the client socket. Will delegate actual work according to whether
1342 * SASL SSF layers are enabled (thus requiring encryption calls)
1344 static void vnc_client_write_locked(VncState *vs)
1346 #ifdef CONFIG_VNC_SASL
1347 if (vs->sasl.conn &&
1348 vs->sasl.runSSF &&
1349 !vs->sasl.waitWriteSSF) {
1350 vnc_client_write_sasl(vs);
1351 } else
1352 #endif /* CONFIG_VNC_SASL */
1354 vnc_client_write_plain(vs);
1358 static void vnc_client_write(VncState *vs)
1361 vnc_lock_output(vs);
1362 if (vs->output.offset) {
1363 vnc_client_write_locked(vs);
1364 } else if (vs->ioc != NULL) {
1365 if (vs->ioc_tag) {
1366 g_source_remove(vs->ioc_tag);
1368 vs->ioc_tag = qio_channel_add_watch(
1369 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1371 vnc_unlock_output(vs);
1374 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1376 vs->read_handler = func;
1377 vs->read_handler_expect = expecting;
1382 * Called to read a chunk of data from the client socket. The data may
1383 * be the raw data, or may need to be further decoded by SASL.
1384 * The data will be read either straight from to the socket, or
1385 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1387 * NB, it is theoretically possible to have 2 layers of encryption,
1388 * both SASL, and this TLS layer. It is highly unlikely in practice
1389 * though, since SASL encryption will typically be a no-op if TLS
1390 * is active
1392 * Returns the number of bytes read, which may be less than
1393 * the requested 'datalen' if the socket would block. Returns
1394 * -1 on error, and disconnects the client socket.
1396 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1398 ssize_t ret;
1399 Error *err = NULL;
1400 ret = qio_channel_read(
1401 vs->ioc, (char *)data, datalen, &err);
1402 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1403 return vnc_client_io_error(vs, ret, &err);
1408 * Called to read data from the client socket to the input buffer,
1409 * when not using any SASL SSF encryption layers. Will read as much
1410 * data as possible without blocking.
1412 * Returns the number of bytes read. Returns -1 on error, and
1413 * disconnects the client socket.
1415 static ssize_t vnc_client_read_plain(VncState *vs)
1417 ssize_t ret;
1418 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1419 vs->input.buffer, vs->input.capacity, vs->input.offset);
1420 buffer_reserve(&vs->input, 4096);
1421 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1422 if (!ret)
1423 return 0;
1424 vs->input.offset += ret;
1425 return ret;
1428 static void vnc_jobs_bh(void *opaque)
1430 VncState *vs = opaque;
1432 vnc_jobs_consume_buffer(vs);
1436 * First function called whenever there is more data to be read from
1437 * the client socket. Will delegate actual work according to whether
1438 * SASL SSF layers are enabled (thus requiring decryption calls)
1439 * Returns 0 on success, -1 if client disconnected
1441 static int vnc_client_read(VncState *vs)
1443 ssize_t ret;
1445 #ifdef CONFIG_VNC_SASL
1446 if (vs->sasl.conn && vs->sasl.runSSF)
1447 ret = vnc_client_read_sasl(vs);
1448 else
1449 #endif /* CONFIG_VNC_SASL */
1450 ret = vnc_client_read_plain(vs);
1451 if (!ret) {
1452 if (vs->disconnecting) {
1453 vnc_disconnect_finish(vs);
1454 return -1;
1456 return 0;
1459 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1460 size_t len = vs->read_handler_expect;
1461 int ret;
1463 ret = vs->read_handler(vs, vs->input.buffer, len);
1464 if (vs->disconnecting) {
1465 vnc_disconnect_finish(vs);
1466 return -1;
1469 if (!ret) {
1470 buffer_advance(&vs->input, len);
1471 } else {
1472 vs->read_handler_expect = ret;
1475 return 0;
1478 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1479 GIOCondition condition, void *opaque)
1481 VncState *vs = opaque;
1482 if (condition & G_IO_IN) {
1483 if (vnc_client_read(vs) < 0) {
1484 return TRUE;
1487 if (condition & G_IO_OUT) {
1488 vnc_client_write(vs);
1490 return TRUE;
1494 void vnc_write(VncState *vs, const void *data, size_t len)
1496 buffer_reserve(&vs->output, len);
1498 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1499 if (vs->ioc_tag) {
1500 g_source_remove(vs->ioc_tag);
1502 vs->ioc_tag = qio_channel_add_watch(
1503 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1506 buffer_append(&vs->output, data, len);
1509 void vnc_write_s32(VncState *vs, int32_t value)
1511 vnc_write_u32(vs, *(uint32_t *)&value);
1514 void vnc_write_u32(VncState *vs, uint32_t value)
1516 uint8_t buf[4];
1518 buf[0] = (value >> 24) & 0xFF;
1519 buf[1] = (value >> 16) & 0xFF;
1520 buf[2] = (value >> 8) & 0xFF;
1521 buf[3] = value & 0xFF;
1523 vnc_write(vs, buf, 4);
1526 void vnc_write_u16(VncState *vs, uint16_t value)
1528 uint8_t buf[2];
1530 buf[0] = (value >> 8) & 0xFF;
1531 buf[1] = value & 0xFF;
1533 vnc_write(vs, buf, 2);
1536 void vnc_write_u8(VncState *vs, uint8_t value)
1538 vnc_write(vs, (char *)&value, 1);
1541 void vnc_flush(VncState *vs)
1543 vnc_lock_output(vs);
1544 if (vs->ioc != NULL && vs->output.offset) {
1545 vnc_client_write_locked(vs);
1547 vnc_unlock_output(vs);
1550 static uint8_t read_u8(uint8_t *data, size_t offset)
1552 return data[offset];
1555 static uint16_t read_u16(uint8_t *data, size_t offset)
1557 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1560 static int32_t read_s32(uint8_t *data, size_t offset)
1562 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1563 (data[offset + 2] << 8) | data[offset + 3]);
1566 uint32_t read_u32(uint8_t *data, size_t offset)
1568 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1569 (data[offset + 2] << 8) | data[offset + 3]);
1572 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1576 static void check_pointer_type_change(Notifier *notifier, void *data)
1578 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1579 int absolute = qemu_input_is_absolute();
1581 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1582 vnc_lock_output(vs);
1583 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1584 vnc_write_u8(vs, 0);
1585 vnc_write_u16(vs, 1);
1586 vnc_framebuffer_update(vs, absolute, 0,
1587 pixman_image_get_width(vs->vd->server),
1588 pixman_image_get_height(vs->vd->server),
1589 VNC_ENCODING_POINTER_TYPE_CHANGE);
1590 vnc_unlock_output(vs);
1591 vnc_flush(vs);
1593 vs->absolute = absolute;
1596 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1598 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1599 [INPUT_BUTTON_LEFT] = 0x01,
1600 [INPUT_BUTTON_MIDDLE] = 0x02,
1601 [INPUT_BUTTON_RIGHT] = 0x04,
1602 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1603 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1605 QemuConsole *con = vs->vd->dcl.con;
1606 int width = pixman_image_get_width(vs->vd->server);
1607 int height = pixman_image_get_height(vs->vd->server);
1609 if (vs->last_bmask != button_mask) {
1610 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1611 vs->last_bmask = button_mask;
1614 if (vs->absolute) {
1615 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1616 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1617 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1618 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1619 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1620 } else {
1621 if (vs->last_x != -1) {
1622 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1623 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1625 vs->last_x = x;
1626 vs->last_y = y;
1628 qemu_input_event_sync();
1631 static void reset_keys(VncState *vs)
1633 int i;
1634 for(i = 0; i < 256; i++) {
1635 if (vs->modifiers_state[i]) {
1636 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1637 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1638 vs->modifiers_state[i] = 0;
1643 static void press_key(VncState *vs, int keysym)
1645 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1646 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1647 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1648 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1649 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1652 static int current_led_state(VncState *vs)
1654 int ledstate = 0;
1656 if (vs->modifiers_state[0x46]) {
1657 ledstate |= QEMU_SCROLL_LOCK_LED;
1659 if (vs->modifiers_state[0x45]) {
1660 ledstate |= QEMU_NUM_LOCK_LED;
1662 if (vs->modifiers_state[0x3a]) {
1663 ledstate |= QEMU_CAPS_LOCK_LED;
1666 return ledstate;
1669 static void vnc_led_state_change(VncState *vs)
1671 int ledstate = 0;
1673 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1674 return;
1677 ledstate = current_led_state(vs);
1678 vnc_lock_output(vs);
1679 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1680 vnc_write_u8(vs, 0);
1681 vnc_write_u16(vs, 1);
1682 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1683 vnc_write_u8(vs, ledstate);
1684 vnc_unlock_output(vs);
1685 vnc_flush(vs);
1688 static void kbd_leds(void *opaque, int ledstate)
1690 VncState *vs = opaque;
1691 int caps, num, scr;
1692 bool has_changed = (ledstate != current_led_state(vs));
1694 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1695 (ledstate & QEMU_NUM_LOCK_LED),
1696 (ledstate & QEMU_SCROLL_LOCK_LED));
1698 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1699 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1700 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1702 if (vs->modifiers_state[0x3a] != caps) {
1703 vs->modifiers_state[0x3a] = caps;
1705 if (vs->modifiers_state[0x45] != num) {
1706 vs->modifiers_state[0x45] = num;
1708 if (vs->modifiers_state[0x46] != scr) {
1709 vs->modifiers_state[0x46] = scr;
1712 /* Sending the current led state message to the client */
1713 if (has_changed) {
1714 vnc_led_state_change(vs);
1718 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1720 /* QEMU console switch */
1721 switch(keycode) {
1722 case 0x2a: /* Left Shift */
1723 case 0x36: /* Right Shift */
1724 case 0x1d: /* Left CTRL */
1725 case 0x9d: /* Right CTRL */
1726 case 0x38: /* Left ALT */
1727 case 0xb8: /* Right ALT */
1728 if (down)
1729 vs->modifiers_state[keycode] = 1;
1730 else
1731 vs->modifiers_state[keycode] = 0;
1732 break;
1733 case 0x02 ... 0x0a: /* '1' to '9' keys */
1734 if (vs->vd->dcl.con == NULL &&
1735 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1736 /* Reset the modifiers sent to the current console */
1737 reset_keys(vs);
1738 console_select(keycode - 0x02);
1739 return;
1741 break;
1742 case 0x3a: /* CapsLock */
1743 case 0x45: /* NumLock */
1744 if (down)
1745 vs->modifiers_state[keycode] ^= 1;
1746 break;
1749 /* Turn off the lock state sync logic if the client support the led
1750 state extension.
1752 if (down && vs->vd->lock_key_sync &&
1753 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1754 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1755 /* If the numlock state needs to change then simulate an additional
1756 keypress before sending this one. This will happen if the user
1757 toggles numlock away from the VNC window.
1759 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1760 if (!vs->modifiers_state[0x45]) {
1761 trace_vnc_key_sync_numlock(true);
1762 vs->modifiers_state[0x45] = 1;
1763 press_key(vs, 0xff7f);
1765 } else {
1766 if (vs->modifiers_state[0x45]) {
1767 trace_vnc_key_sync_numlock(false);
1768 vs->modifiers_state[0x45] = 0;
1769 press_key(vs, 0xff7f);
1774 if (down && vs->vd->lock_key_sync &&
1775 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1776 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1777 /* If the capslock state needs to change then simulate an additional
1778 keypress before sending this one. This will happen if the user
1779 toggles capslock away from the VNC window.
1781 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1782 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1783 int capslock = !!(vs->modifiers_state[0x3a]);
1784 if (capslock) {
1785 if (uppercase == shift) {
1786 trace_vnc_key_sync_capslock(false);
1787 vs->modifiers_state[0x3a] = 0;
1788 press_key(vs, 0xffe5);
1790 } else {
1791 if (uppercase != shift) {
1792 trace_vnc_key_sync_capslock(true);
1793 vs->modifiers_state[0x3a] = 1;
1794 press_key(vs, 0xffe5);
1799 if (qemu_console_is_graphic(NULL)) {
1800 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1801 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1802 } else {
1803 bool numlock = vs->modifiers_state[0x45];
1804 bool control = (vs->modifiers_state[0x1d] ||
1805 vs->modifiers_state[0x9d]);
1806 /* QEMU console emulation */
1807 if (down) {
1808 switch (keycode) {
1809 case 0x2a: /* Left Shift */
1810 case 0x36: /* Right Shift */
1811 case 0x1d: /* Left CTRL */
1812 case 0x9d: /* Right CTRL */
1813 case 0x38: /* Left ALT */
1814 case 0xb8: /* Right ALT */
1815 break;
1816 case 0xc8:
1817 kbd_put_keysym(QEMU_KEY_UP);
1818 break;
1819 case 0xd0:
1820 kbd_put_keysym(QEMU_KEY_DOWN);
1821 break;
1822 case 0xcb:
1823 kbd_put_keysym(QEMU_KEY_LEFT);
1824 break;
1825 case 0xcd:
1826 kbd_put_keysym(QEMU_KEY_RIGHT);
1827 break;
1828 case 0xd3:
1829 kbd_put_keysym(QEMU_KEY_DELETE);
1830 break;
1831 case 0xc7:
1832 kbd_put_keysym(QEMU_KEY_HOME);
1833 break;
1834 case 0xcf:
1835 kbd_put_keysym(QEMU_KEY_END);
1836 break;
1837 case 0xc9:
1838 kbd_put_keysym(QEMU_KEY_PAGEUP);
1839 break;
1840 case 0xd1:
1841 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1842 break;
1844 case 0x47:
1845 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1846 break;
1847 case 0x48:
1848 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1849 break;
1850 case 0x49:
1851 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1852 break;
1853 case 0x4b:
1854 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1855 break;
1856 case 0x4c:
1857 kbd_put_keysym('5');
1858 break;
1859 case 0x4d:
1860 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1861 break;
1862 case 0x4f:
1863 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1864 break;
1865 case 0x50:
1866 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1867 break;
1868 case 0x51:
1869 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1870 break;
1871 case 0x52:
1872 kbd_put_keysym('0');
1873 break;
1874 case 0x53:
1875 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1876 break;
1878 case 0xb5:
1879 kbd_put_keysym('/');
1880 break;
1881 case 0x37:
1882 kbd_put_keysym('*');
1883 break;
1884 case 0x4a:
1885 kbd_put_keysym('-');
1886 break;
1887 case 0x4e:
1888 kbd_put_keysym('+');
1889 break;
1890 case 0x9c:
1891 kbd_put_keysym('\n');
1892 break;
1894 default:
1895 if (control) {
1896 kbd_put_keysym(sym & 0x1f);
1897 } else {
1898 kbd_put_keysym(sym);
1900 break;
1906 static void vnc_release_modifiers(VncState *vs)
1908 static const int keycodes[] = {
1909 /* shift, control, alt keys, both left & right */
1910 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1912 int i, keycode;
1914 if (!qemu_console_is_graphic(NULL)) {
1915 return;
1917 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1918 keycode = keycodes[i];
1919 if (!vs->modifiers_state[keycode]) {
1920 continue;
1922 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1923 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1927 static const char *code2name(int keycode)
1929 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1932 static void key_event(VncState *vs, int down, uint32_t sym)
1934 int keycode;
1935 int lsym = sym;
1937 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1938 lsym = lsym - 'A' + 'a';
1941 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1942 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1943 do_key_event(vs, down, keycode, sym);
1946 static void ext_key_event(VncState *vs, int down,
1947 uint32_t sym, uint16_t keycode)
1949 /* if the user specifies a keyboard layout, always use it */
1950 if (keyboard_layout) {
1951 key_event(vs, down, sym);
1952 } else {
1953 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1954 do_key_event(vs, down, keycode, sym);
1958 static void framebuffer_update_request(VncState *vs, int incremental,
1959 int x, int y, int w, int h)
1961 vs->need_update = 1;
1963 if (incremental) {
1964 return;
1967 vs->force_update = 1;
1968 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1971 static void send_ext_key_event_ack(VncState *vs)
1973 vnc_lock_output(vs);
1974 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1975 vnc_write_u8(vs, 0);
1976 vnc_write_u16(vs, 1);
1977 vnc_framebuffer_update(vs, 0, 0,
1978 pixman_image_get_width(vs->vd->server),
1979 pixman_image_get_height(vs->vd->server),
1980 VNC_ENCODING_EXT_KEY_EVENT);
1981 vnc_unlock_output(vs);
1982 vnc_flush(vs);
1985 static void send_ext_audio_ack(VncState *vs)
1987 vnc_lock_output(vs);
1988 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1989 vnc_write_u8(vs, 0);
1990 vnc_write_u16(vs, 1);
1991 vnc_framebuffer_update(vs, 0, 0,
1992 pixman_image_get_width(vs->vd->server),
1993 pixman_image_get_height(vs->vd->server),
1994 VNC_ENCODING_AUDIO);
1995 vnc_unlock_output(vs);
1996 vnc_flush(vs);
1999 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2001 int i;
2002 unsigned int enc = 0;
2004 vs->features = 0;
2005 vs->vnc_encoding = 0;
2006 vs->tight.compression = 9;
2007 vs->tight.quality = -1; /* Lossless by default */
2008 vs->absolute = -1;
2011 * Start from the end because the encodings are sent in order of preference.
2012 * This way the preferred encoding (first encoding defined in the array)
2013 * will be set at the end of the loop.
2015 for (i = n_encodings - 1; i >= 0; i--) {
2016 enc = encodings[i];
2017 switch (enc) {
2018 case VNC_ENCODING_RAW:
2019 vs->vnc_encoding = enc;
2020 break;
2021 case VNC_ENCODING_COPYRECT:
2022 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2023 break;
2024 case VNC_ENCODING_HEXTILE:
2025 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2026 vs->vnc_encoding = enc;
2027 break;
2028 case VNC_ENCODING_TIGHT:
2029 vs->features |= VNC_FEATURE_TIGHT_MASK;
2030 vs->vnc_encoding = enc;
2031 break;
2032 #ifdef CONFIG_VNC_PNG
2033 case VNC_ENCODING_TIGHT_PNG:
2034 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2035 vs->vnc_encoding = enc;
2036 break;
2037 #endif
2038 case VNC_ENCODING_ZLIB:
2039 vs->features |= VNC_FEATURE_ZLIB_MASK;
2040 vs->vnc_encoding = enc;
2041 break;
2042 case VNC_ENCODING_ZRLE:
2043 vs->features |= VNC_FEATURE_ZRLE_MASK;
2044 vs->vnc_encoding = enc;
2045 break;
2046 case VNC_ENCODING_ZYWRLE:
2047 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2048 vs->vnc_encoding = enc;
2049 break;
2050 case VNC_ENCODING_DESKTOPRESIZE:
2051 vs->features |= VNC_FEATURE_RESIZE_MASK;
2052 break;
2053 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2054 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2055 break;
2056 case VNC_ENCODING_RICH_CURSOR:
2057 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2058 if (vs->vd->cursor) {
2059 vnc_cursor_define(vs);
2061 break;
2062 case VNC_ENCODING_EXT_KEY_EVENT:
2063 send_ext_key_event_ack(vs);
2064 break;
2065 case VNC_ENCODING_AUDIO:
2066 send_ext_audio_ack(vs);
2067 break;
2068 case VNC_ENCODING_WMVi:
2069 vs->features |= VNC_FEATURE_WMVI_MASK;
2070 break;
2071 case VNC_ENCODING_LED_STATE:
2072 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2073 break;
2074 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2075 vs->tight.compression = (enc & 0x0F);
2076 break;
2077 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2078 if (vs->vd->lossy) {
2079 vs->tight.quality = (enc & 0x0F);
2081 break;
2082 default:
2083 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2084 break;
2087 vnc_desktop_resize(vs);
2088 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2089 vnc_led_state_change(vs);
2092 static void set_pixel_conversion(VncState *vs)
2094 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2096 if (fmt == VNC_SERVER_FB_FORMAT) {
2097 vs->write_pixels = vnc_write_pixels_copy;
2098 vnc_hextile_set_pixel_conversion(vs, 0);
2099 } else {
2100 vs->write_pixels = vnc_write_pixels_generic;
2101 vnc_hextile_set_pixel_conversion(vs, 1);
2105 static void send_color_map(VncState *vs)
2107 int i;
2109 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2110 vnc_write_u8(vs, 0); /* padding */
2111 vnc_write_u16(vs, 0); /* first color */
2112 vnc_write_u16(vs, 256); /* # of colors */
2114 for (i = 0; i < 256; i++) {
2115 PixelFormat *pf = &vs->client_pf;
2117 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2118 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2119 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2123 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2124 int big_endian_flag, int true_color_flag,
2125 int red_max, int green_max, int blue_max,
2126 int red_shift, int green_shift, int blue_shift)
2128 if (!true_color_flag) {
2129 /* Expose a reasonable default 256 color map */
2130 bits_per_pixel = 8;
2131 red_max = 7;
2132 green_max = 7;
2133 blue_max = 3;
2134 red_shift = 0;
2135 green_shift = 3;
2136 blue_shift = 6;
2139 switch (bits_per_pixel) {
2140 case 8:
2141 case 16:
2142 case 32:
2143 break;
2144 default:
2145 vnc_client_error(vs);
2146 return;
2149 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2150 vs->client_pf.rbits = hweight_long(red_max);
2151 vs->client_pf.rshift = red_shift;
2152 vs->client_pf.rmask = red_max << red_shift;
2153 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2154 vs->client_pf.gbits = hweight_long(green_max);
2155 vs->client_pf.gshift = green_shift;
2156 vs->client_pf.gmask = green_max << green_shift;
2157 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2158 vs->client_pf.bbits = hweight_long(blue_max);
2159 vs->client_pf.bshift = blue_shift;
2160 vs->client_pf.bmask = blue_max << blue_shift;
2161 vs->client_pf.bits_per_pixel = bits_per_pixel;
2162 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2163 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2164 vs->client_be = big_endian_flag;
2166 if (!true_color_flag) {
2167 send_color_map(vs);
2170 set_pixel_conversion(vs);
2172 graphic_hw_invalidate(vs->vd->dcl.con);
2173 graphic_hw_update(vs->vd->dcl.con);
2176 static void pixel_format_message (VncState *vs) {
2177 char pad[3] = { 0, 0, 0 };
2179 vs->client_pf = qemu_default_pixelformat(32);
2181 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2182 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2184 #ifdef HOST_WORDS_BIGENDIAN
2185 vnc_write_u8(vs, 1); /* big-endian-flag */
2186 #else
2187 vnc_write_u8(vs, 0); /* big-endian-flag */
2188 #endif
2189 vnc_write_u8(vs, 1); /* true-color-flag */
2190 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2191 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2192 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2193 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2194 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2195 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2196 vnc_write(vs, pad, 3); /* padding */
2198 vnc_hextile_set_pixel_conversion(vs, 0);
2199 vs->write_pixels = vnc_write_pixels_copy;
2202 static void vnc_colordepth(VncState *vs)
2204 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2205 /* Sending a WMVi message to notify the client*/
2206 vnc_lock_output(vs);
2207 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2208 vnc_write_u8(vs, 0);
2209 vnc_write_u16(vs, 1); /* number of rects */
2210 vnc_framebuffer_update(vs, 0, 0,
2211 pixman_image_get_width(vs->vd->server),
2212 pixman_image_get_height(vs->vd->server),
2213 VNC_ENCODING_WMVi);
2214 pixel_format_message(vs);
2215 vnc_unlock_output(vs);
2216 vnc_flush(vs);
2217 } else {
2218 set_pixel_conversion(vs);
2222 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2224 int i;
2225 uint16_t limit;
2226 VncDisplay *vd = vs->vd;
2228 if (data[0] > 3) {
2229 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2232 switch (data[0]) {
2233 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2234 if (len == 1)
2235 return 20;
2237 set_pixel_format(vs, read_u8(data, 4),
2238 read_u8(data, 6), read_u8(data, 7),
2239 read_u16(data, 8), read_u16(data, 10),
2240 read_u16(data, 12), read_u8(data, 14),
2241 read_u8(data, 15), read_u8(data, 16));
2242 break;
2243 case VNC_MSG_CLIENT_SET_ENCODINGS:
2244 if (len == 1)
2245 return 4;
2247 if (len == 4) {
2248 limit = read_u16(data, 2);
2249 if (limit > 0)
2250 return 4 + (limit * 4);
2251 } else
2252 limit = read_u16(data, 2);
2254 for (i = 0; i < limit; i++) {
2255 int32_t val = read_s32(data, 4 + (i * 4));
2256 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2259 set_encodings(vs, (int32_t *)(data + 4), limit);
2260 break;
2261 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2262 if (len == 1)
2263 return 10;
2265 framebuffer_update_request(vs,
2266 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2267 read_u16(data, 6), read_u16(data, 8));
2268 break;
2269 case VNC_MSG_CLIENT_KEY_EVENT:
2270 if (len == 1)
2271 return 8;
2273 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2274 break;
2275 case VNC_MSG_CLIENT_POINTER_EVENT:
2276 if (len == 1)
2277 return 6;
2279 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2280 break;
2281 case VNC_MSG_CLIENT_CUT_TEXT:
2282 if (len == 1) {
2283 return 8;
2285 if (len == 8) {
2286 uint32_t dlen = read_u32(data, 4);
2287 if (dlen > (1 << 20)) {
2288 error_report("vnc: client_cut_text msg payload has %u bytes"
2289 " which exceeds our limit of 1MB.", dlen);
2290 vnc_client_error(vs);
2291 break;
2293 if (dlen > 0) {
2294 return 8 + dlen;
2298 client_cut_text(vs, read_u32(data, 4), data + 8);
2299 break;
2300 case VNC_MSG_CLIENT_QEMU:
2301 if (len == 1)
2302 return 2;
2304 switch (read_u8(data, 1)) {
2305 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2306 if (len == 2)
2307 return 12;
2309 ext_key_event(vs, read_u16(data, 2),
2310 read_u32(data, 4), read_u32(data, 8));
2311 break;
2312 case VNC_MSG_CLIENT_QEMU_AUDIO:
2313 if (len == 2)
2314 return 4;
2316 switch (read_u16 (data, 2)) {
2317 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2318 audio_add(vs);
2319 break;
2320 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2321 audio_del(vs);
2322 break;
2323 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2324 if (len == 4)
2325 return 10;
2326 switch (read_u8(data, 4)) {
2327 case 0: vs->as.fmt = AUD_FMT_U8; break;
2328 case 1: vs->as.fmt = AUD_FMT_S8; break;
2329 case 2: vs->as.fmt = AUD_FMT_U16; break;
2330 case 3: vs->as.fmt = AUD_FMT_S16; break;
2331 case 4: vs->as.fmt = AUD_FMT_U32; break;
2332 case 5: vs->as.fmt = AUD_FMT_S32; break;
2333 default:
2334 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2335 vnc_client_error(vs);
2336 break;
2338 vs->as.nchannels = read_u8(data, 5);
2339 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2340 VNC_DEBUG("Invalid audio channel coount %d\n",
2341 read_u8(data, 5));
2342 vnc_client_error(vs);
2343 break;
2345 vs->as.freq = read_u32(data, 6);
2346 break;
2347 default:
2348 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2349 vnc_client_error(vs);
2350 break;
2352 break;
2354 default:
2355 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2356 vnc_client_error(vs);
2357 break;
2359 break;
2360 default:
2361 VNC_DEBUG("Msg: %d\n", data[0]);
2362 vnc_client_error(vs);
2363 break;
2366 vnc_read_when(vs, protocol_client_msg, 1);
2367 return 0;
2370 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2372 char buf[1024];
2373 VncShareMode mode;
2374 int size;
2376 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2377 switch (vs->vd->share_policy) {
2378 case VNC_SHARE_POLICY_IGNORE:
2380 * Ignore the shared flag. Nothing to do here.
2382 * Doesn't conform to the rfb spec but is traditional qemu
2383 * behavior, thus left here as option for compatibility
2384 * reasons.
2386 break;
2387 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2389 * Policy: Allow clients ask for exclusive access.
2391 * Implementation: When a client asks for exclusive access,
2392 * disconnect all others. Shared connects are allowed as long
2393 * as no exclusive connection exists.
2395 * This is how the rfb spec suggests to handle the shared flag.
2397 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2398 VncState *client;
2399 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2400 if (vs == client) {
2401 continue;
2403 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2404 client->share_mode != VNC_SHARE_MODE_SHARED) {
2405 continue;
2407 vnc_disconnect_start(client);
2410 if (mode == VNC_SHARE_MODE_SHARED) {
2411 if (vs->vd->num_exclusive > 0) {
2412 vnc_disconnect_start(vs);
2413 return 0;
2416 break;
2417 case VNC_SHARE_POLICY_FORCE_SHARED:
2419 * Policy: Shared connects only.
2420 * Implementation: Disallow clients asking for exclusive access.
2422 * Useful for shared desktop sessions where you don't want
2423 * someone forgetting to say -shared when running the vnc
2424 * client disconnect everybody else.
2426 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2427 vnc_disconnect_start(vs);
2428 return 0;
2430 break;
2432 vnc_set_share_mode(vs, mode);
2434 if (vs->vd->num_shared > vs->vd->connections_limit) {
2435 vnc_disconnect_start(vs);
2436 return 0;
2439 vs->client_width = pixman_image_get_width(vs->vd->server);
2440 vs->client_height = pixman_image_get_height(vs->vd->server);
2441 vnc_write_u16(vs, vs->client_width);
2442 vnc_write_u16(vs, vs->client_height);
2444 pixel_format_message(vs);
2446 if (qemu_name)
2447 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2448 else
2449 size = snprintf(buf, sizeof(buf), "QEMU");
2451 vnc_write_u32(vs, size);
2452 vnc_write(vs, buf, size);
2453 vnc_flush(vs);
2455 vnc_client_cache_auth(vs);
2456 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2458 vnc_read_when(vs, protocol_client_msg, 1);
2460 return 0;
2463 void start_client_init(VncState *vs)
2465 vnc_read_when(vs, protocol_client_init, 1);
2468 static void make_challenge(VncState *vs)
2470 int i;
2472 srand(time(NULL)+getpid()+getpid()*987654+rand());
2474 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2475 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2478 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2480 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2481 size_t i, pwlen;
2482 unsigned char key[8];
2483 time_t now = time(NULL);
2484 QCryptoCipher *cipher = NULL;
2485 Error *err = NULL;
2487 if (!vs->vd->password) {
2488 VNC_DEBUG("No password configured on server");
2489 goto reject;
2491 if (vs->vd->expires < now) {
2492 VNC_DEBUG("Password is expired");
2493 goto reject;
2496 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2498 /* Calculate the expected challenge response */
2499 pwlen = strlen(vs->vd->password);
2500 for (i=0; i<sizeof(key); i++)
2501 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2503 cipher = qcrypto_cipher_new(
2504 QCRYPTO_CIPHER_ALG_DES_RFB,
2505 QCRYPTO_CIPHER_MODE_ECB,
2506 key, G_N_ELEMENTS(key),
2507 &err);
2508 if (!cipher) {
2509 VNC_DEBUG("Cannot initialize cipher %s",
2510 error_get_pretty(err));
2511 error_free(err);
2512 goto reject;
2515 if (qcrypto_cipher_encrypt(cipher,
2516 vs->challenge,
2517 response,
2518 VNC_AUTH_CHALLENGE_SIZE,
2519 &err) < 0) {
2520 VNC_DEBUG("Cannot encrypt challenge %s",
2521 error_get_pretty(err));
2522 error_free(err);
2523 goto reject;
2526 /* Compare expected vs actual challenge response */
2527 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2528 VNC_DEBUG("Client challenge response did not match\n");
2529 goto reject;
2530 } else {
2531 VNC_DEBUG("Accepting VNC challenge response\n");
2532 vnc_write_u32(vs, 0); /* Accept auth */
2533 vnc_flush(vs);
2535 start_client_init(vs);
2538 qcrypto_cipher_free(cipher);
2539 return 0;
2541 reject:
2542 vnc_write_u32(vs, 1); /* Reject auth */
2543 if (vs->minor >= 8) {
2544 static const char err[] = "Authentication failed";
2545 vnc_write_u32(vs, sizeof(err));
2546 vnc_write(vs, err, sizeof(err));
2548 vnc_flush(vs);
2549 vnc_client_error(vs);
2550 qcrypto_cipher_free(cipher);
2551 return 0;
2554 void start_auth_vnc(VncState *vs)
2556 make_challenge(vs);
2557 /* Send client a 'random' challenge */
2558 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2559 vnc_flush(vs);
2561 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2565 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2567 /* We only advertise 1 auth scheme at a time, so client
2568 * must pick the one we sent. Verify this */
2569 if (data[0] != vs->auth) { /* Reject auth */
2570 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2571 vnc_write_u32(vs, 1);
2572 if (vs->minor >= 8) {
2573 static const char err[] = "Authentication failed";
2574 vnc_write_u32(vs, sizeof(err));
2575 vnc_write(vs, err, sizeof(err));
2577 vnc_client_error(vs);
2578 } else { /* Accept requested auth */
2579 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2580 switch (vs->auth) {
2581 case VNC_AUTH_NONE:
2582 VNC_DEBUG("Accept auth none\n");
2583 if (vs->minor >= 8) {
2584 vnc_write_u32(vs, 0); /* Accept auth completion */
2585 vnc_flush(vs);
2587 start_client_init(vs);
2588 break;
2590 case VNC_AUTH_VNC:
2591 VNC_DEBUG("Start VNC auth\n");
2592 start_auth_vnc(vs);
2593 break;
2595 case VNC_AUTH_VENCRYPT:
2596 VNC_DEBUG("Accept VeNCrypt auth\n");
2597 start_auth_vencrypt(vs);
2598 break;
2600 #ifdef CONFIG_VNC_SASL
2601 case VNC_AUTH_SASL:
2602 VNC_DEBUG("Accept SASL auth\n");
2603 start_auth_sasl(vs);
2604 break;
2605 #endif /* CONFIG_VNC_SASL */
2607 default: /* Should not be possible, but just in case */
2608 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2609 vnc_write_u8(vs, 1);
2610 if (vs->minor >= 8) {
2611 static const char err[] = "Authentication failed";
2612 vnc_write_u32(vs, sizeof(err));
2613 vnc_write(vs, err, sizeof(err));
2615 vnc_client_error(vs);
2618 return 0;
2621 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2623 char local[13];
2625 memcpy(local, version, 12);
2626 local[12] = 0;
2628 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2629 VNC_DEBUG("Malformed protocol version %s\n", local);
2630 vnc_client_error(vs);
2631 return 0;
2633 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2634 if (vs->major != 3 ||
2635 (vs->minor != 3 &&
2636 vs->minor != 4 &&
2637 vs->minor != 5 &&
2638 vs->minor != 7 &&
2639 vs->minor != 8)) {
2640 VNC_DEBUG("Unsupported client version\n");
2641 vnc_write_u32(vs, VNC_AUTH_INVALID);
2642 vnc_flush(vs);
2643 vnc_client_error(vs);
2644 return 0;
2646 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2647 * as equivalent to v3.3 by servers
2649 if (vs->minor == 4 || vs->minor == 5)
2650 vs->minor = 3;
2652 if (vs->minor == 3) {
2653 if (vs->auth == VNC_AUTH_NONE) {
2654 VNC_DEBUG("Tell client auth none\n");
2655 vnc_write_u32(vs, vs->auth);
2656 vnc_flush(vs);
2657 start_client_init(vs);
2658 } else if (vs->auth == VNC_AUTH_VNC) {
2659 VNC_DEBUG("Tell client VNC auth\n");
2660 vnc_write_u32(vs, vs->auth);
2661 vnc_flush(vs);
2662 start_auth_vnc(vs);
2663 } else {
2664 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2665 vnc_write_u32(vs, VNC_AUTH_INVALID);
2666 vnc_flush(vs);
2667 vnc_client_error(vs);
2669 } else {
2670 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2671 vnc_write_u8(vs, 1); /* num auth */
2672 vnc_write_u8(vs, vs->auth);
2673 vnc_read_when(vs, protocol_client_auth, 1);
2674 vnc_flush(vs);
2677 return 0;
2680 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2682 struct VncSurface *vs = &vd->guest;
2684 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2687 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2689 int i, j;
2691 w = (x + w) / VNC_STAT_RECT;
2692 h = (y + h) / VNC_STAT_RECT;
2693 x /= VNC_STAT_RECT;
2694 y /= VNC_STAT_RECT;
2696 for (j = y; j <= h; j++) {
2697 for (i = x; i <= w; i++) {
2698 vs->lossy_rect[j][i] = 1;
2703 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2705 VncState *vs;
2706 int sty = y / VNC_STAT_RECT;
2707 int stx = x / VNC_STAT_RECT;
2708 int has_dirty = 0;
2710 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2711 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2713 QTAILQ_FOREACH(vs, &vd->clients, next) {
2714 int j;
2716 /* kernel send buffers are full -> refresh later */
2717 if (vs->output.offset) {
2718 continue;
2721 if (!vs->lossy_rect[sty][stx]) {
2722 continue;
2725 vs->lossy_rect[sty][stx] = 0;
2726 for (j = 0; j < VNC_STAT_RECT; ++j) {
2727 bitmap_set(vs->dirty[y + j],
2728 x / VNC_DIRTY_PIXELS_PER_BIT,
2729 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2731 has_dirty++;
2734 return has_dirty;
2737 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2739 int width = pixman_image_get_width(vd->guest.fb);
2740 int height = pixman_image_get_height(vd->guest.fb);
2741 int x, y;
2742 struct timeval res;
2743 int has_dirty = 0;
2745 for (y = 0; y < height; y += VNC_STAT_RECT) {
2746 for (x = 0; x < width; x += VNC_STAT_RECT) {
2747 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2749 rect->updated = false;
2753 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2755 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2756 return has_dirty;
2758 vd->guest.last_freq_check = *tv;
2760 for (y = 0; y < height; y += VNC_STAT_RECT) {
2761 for (x = 0; x < width; x += VNC_STAT_RECT) {
2762 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2763 int count = ARRAY_SIZE(rect->times);
2764 struct timeval min, max;
2766 if (!timerisset(&rect->times[count - 1])) {
2767 continue ;
2770 max = rect->times[(rect->idx + count - 1) % count];
2771 qemu_timersub(tv, &max, &res);
2773 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2774 rect->freq = 0;
2775 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2776 memset(rect->times, 0, sizeof (rect->times));
2777 continue ;
2780 min = rect->times[rect->idx];
2781 max = rect->times[(rect->idx + count - 1) % count];
2782 qemu_timersub(&max, &min, &res);
2784 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2785 rect->freq /= count;
2786 rect->freq = 1. / rect->freq;
2789 return has_dirty;
2792 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2794 int i, j;
2795 double total = 0;
2796 int num = 0;
2798 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2799 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2801 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2802 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2803 total += vnc_stat_rect(vs->vd, i, j)->freq;
2804 num++;
2808 if (num) {
2809 return total / num;
2810 } else {
2811 return 0;
2815 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2817 VncRectStat *rect;
2819 rect = vnc_stat_rect(vd, x, y);
2820 if (rect->updated) {
2821 return ;
2823 rect->times[rect->idx] = *tv;
2824 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2825 rect->updated = true;
2828 static int vnc_refresh_server_surface(VncDisplay *vd)
2830 int width = MIN(pixman_image_get_width(vd->guest.fb),
2831 pixman_image_get_width(vd->server));
2832 int height = MIN(pixman_image_get_height(vd->guest.fb),
2833 pixman_image_get_height(vd->server));
2834 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2835 uint8_t *guest_row0 = NULL, *server_row0;
2836 VncState *vs;
2837 int has_dirty = 0;
2838 pixman_image_t *tmpbuf = NULL;
2840 struct timeval tv = { 0, 0 };
2842 if (!vd->non_adaptive) {
2843 gettimeofday(&tv, NULL);
2844 has_dirty = vnc_update_stats(vd, &tv);
2848 * Walk through the guest dirty map.
2849 * Check and copy modified bits from guest to server surface.
2850 * Update server dirty map.
2852 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2853 server_stride = guest_stride = guest_ll =
2854 pixman_image_get_stride(vd->server);
2855 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2856 server_stride);
2857 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2858 int width = pixman_image_get_width(vd->server);
2859 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2860 } else {
2861 int guest_bpp =
2862 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2863 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2864 guest_stride = pixman_image_get_stride(vd->guest.fb);
2865 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2867 line_bytes = MIN(server_stride, guest_ll);
2869 for (;;) {
2870 int x;
2871 uint8_t *guest_ptr, *server_ptr;
2872 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2873 height * VNC_DIRTY_BPL(&vd->guest),
2874 y * VNC_DIRTY_BPL(&vd->guest));
2875 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2876 /* no more dirty bits */
2877 break;
2879 y = offset / VNC_DIRTY_BPL(&vd->guest);
2880 x = offset % VNC_DIRTY_BPL(&vd->guest);
2882 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2884 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2885 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2886 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2887 } else {
2888 guest_ptr = guest_row0 + y * guest_stride;
2890 guest_ptr += x * cmp_bytes;
2892 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2893 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2894 int _cmp_bytes = cmp_bytes;
2895 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2896 continue;
2898 if ((x + 1) * cmp_bytes > line_bytes) {
2899 _cmp_bytes = line_bytes - x * cmp_bytes;
2901 assert(_cmp_bytes >= 0);
2902 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2903 continue;
2905 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2906 if (!vd->non_adaptive) {
2907 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2908 y, &tv);
2910 QTAILQ_FOREACH(vs, &vd->clients, next) {
2911 set_bit(x, vs->dirty[y]);
2913 has_dirty++;
2916 y++;
2918 qemu_pixman_image_unref(tmpbuf);
2919 return has_dirty;
2922 static void vnc_refresh(DisplayChangeListener *dcl)
2924 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2925 VncState *vs, *vn;
2926 int has_dirty, rects = 0;
2928 if (QTAILQ_EMPTY(&vd->clients)) {
2929 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2930 return;
2933 graphic_hw_update(vd->dcl.con);
2935 if (vnc_trylock_display(vd)) {
2936 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2937 return;
2940 has_dirty = vnc_refresh_server_surface(vd);
2941 vnc_unlock_display(vd);
2943 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2944 rects += vnc_update_client(vs, has_dirty, false);
2945 /* vs might be free()ed here */
2948 if (has_dirty && rects) {
2949 vd->dcl.update_interval /= 2;
2950 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2951 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2953 } else {
2954 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2955 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2956 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2961 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2962 bool skipauth, bool websocket)
2964 VncState *vs = g_new0(VncState, 1);
2965 int i;
2967 vs->sioc = sioc;
2968 object_ref(OBJECT(vs->sioc));
2969 vs->ioc = QIO_CHANNEL(sioc);
2970 object_ref(OBJECT(vs->ioc));
2971 vs->vd = vd;
2973 buffer_init(&vs->input, "vnc-input/%p", sioc);
2974 buffer_init(&vs->output, "vnc-output/%p", sioc);
2975 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2977 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2978 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2979 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2980 #ifdef CONFIG_VNC_JPEG
2981 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2982 #endif
2983 #ifdef CONFIG_VNC_PNG
2984 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2985 #endif
2986 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2987 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2988 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2989 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2991 if (skipauth) {
2992 vs->auth = VNC_AUTH_NONE;
2993 vs->subauth = VNC_AUTH_INVALID;
2994 } else {
2995 if (websocket) {
2996 vs->auth = vd->ws_auth;
2997 vs->subauth = VNC_AUTH_INVALID;
2998 } else {
2999 vs->auth = vd->auth;
3000 vs->subauth = vd->subauth;
3003 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3004 sioc, websocket, vs->auth, vs->subauth);
3006 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3007 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3008 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3011 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3012 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3013 qio_channel_set_blocking(vs->ioc, false, NULL);
3014 if (websocket) {
3015 vs->websocket = 1;
3016 if (vd->ws_tls) {
3017 vs->ioc_tag = qio_channel_add_watch(
3018 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3019 } else {
3020 vs->ioc_tag = qio_channel_add_watch(
3021 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
3023 } else {
3024 vs->ioc_tag = qio_channel_add_watch(
3025 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
3028 vnc_client_cache_addr(vs);
3029 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3030 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3032 if (!vs->websocket) {
3033 vnc_init_state(vs);
3036 if (vd->num_connecting > vd->connections_limit) {
3037 QTAILQ_FOREACH(vs, &vd->clients, next) {
3038 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3039 vnc_disconnect_start(vs);
3040 return;
3046 void vnc_init_state(VncState *vs)
3048 vs->initialized = true;
3049 VncDisplay *vd = vs->vd;
3050 bool first_client = QTAILQ_EMPTY(&vd->clients);
3052 vs->last_x = -1;
3053 vs->last_y = -1;
3055 vs->as.freq = 44100;
3056 vs->as.nchannels = 2;
3057 vs->as.fmt = AUD_FMT_S16;
3058 vs->as.endianness = 0;
3060 qemu_mutex_init(&vs->output_mutex);
3061 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3063 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3064 if (first_client) {
3065 vnc_update_server_surface(vd);
3068 graphic_hw_update(vd->dcl.con);
3070 vnc_write(vs, "RFB 003.008\n", 12);
3071 vnc_flush(vs);
3072 vnc_read_when(vs, protocol_version, 12);
3073 reset_keys(vs);
3074 if (vs->vd->lock_key_sync)
3075 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3077 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3078 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3080 /* vs might be free()ed here */
3083 static gboolean vnc_listen_io(QIOChannel *ioc,
3084 GIOCondition condition,
3085 void *opaque)
3087 VncDisplay *vs = opaque;
3088 QIOChannelSocket *sioc = NULL;
3089 Error *err = NULL;
3091 /* Catch-up */
3092 graphic_hw_update(vs->dcl.con);
3093 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3094 if (sioc != NULL) {
3095 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3096 vnc_connect(vs, sioc, false,
3097 ioc != QIO_CHANNEL(vs->lsock));
3098 object_unref(OBJECT(sioc));
3099 } else {
3100 /* client probably closed connection before we got there */
3101 error_free(err);
3104 return TRUE;
3107 static const DisplayChangeListenerOps dcl_ops = {
3108 .dpy_name = "vnc",
3109 .dpy_refresh = vnc_refresh,
3110 .dpy_gfx_copy = vnc_dpy_copy,
3111 .dpy_gfx_update = vnc_dpy_update,
3112 .dpy_gfx_switch = vnc_dpy_switch,
3113 .dpy_gfx_check_format = qemu_pixman_check_format,
3114 .dpy_mouse_set = vnc_mouse_set,
3115 .dpy_cursor_define = vnc_dpy_cursor_define,
3118 void vnc_display_init(const char *id)
3120 VncDisplay *vs;
3122 if (vnc_display_find(id) != NULL) {
3123 return;
3125 vs = g_malloc0(sizeof(*vs));
3127 vs->id = strdup(id);
3128 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3130 QTAILQ_INIT(&vs->clients);
3131 vs->expires = TIME_MAX;
3133 if (keyboard_layout) {
3134 trace_vnc_key_map_init(keyboard_layout);
3135 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3136 } else {
3137 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3140 if (!vs->kbd_layout)
3141 exit(1);
3143 qemu_mutex_init(&vs->mutex);
3144 vnc_start_worker_thread();
3146 vs->dcl.ops = &dcl_ops;
3147 register_displaychangelistener(&vs->dcl);
3151 static void vnc_display_close(VncDisplay *vs)
3153 if (!vs)
3154 return;
3155 vs->enabled = false;
3156 vs->is_unix = false;
3157 if (vs->lsock != NULL) {
3158 if (vs->lsock_tag) {
3159 g_source_remove(vs->lsock_tag);
3161 object_unref(OBJECT(vs->lsock));
3162 vs->lsock = NULL;
3164 vs->ws_enabled = false;
3165 if (vs->lwebsock != NULL) {
3166 if (vs->lwebsock_tag) {
3167 g_source_remove(vs->lwebsock_tag);
3169 object_unref(OBJECT(vs->lwebsock));
3170 vs->lwebsock = NULL;
3172 vs->auth = VNC_AUTH_INVALID;
3173 vs->subauth = VNC_AUTH_INVALID;
3174 if (vs->tlscreds) {
3175 object_unparent(OBJECT(vs->tlscreds));
3176 vs->tlscreds = NULL;
3178 g_free(vs->tlsaclname);
3179 vs->tlsaclname = NULL;
3182 int vnc_display_password(const char *id, const char *password)
3184 VncDisplay *vs = vnc_display_find(id);
3186 if (!vs) {
3187 return -EINVAL;
3189 if (vs->auth == VNC_AUTH_NONE) {
3190 error_printf_unless_qmp("If you want use passwords please enable "
3191 "password auth using '-vnc ${dpy},password'.");
3192 return -EINVAL;
3195 g_free(vs->password);
3196 vs->password = g_strdup(password);
3198 return 0;
3201 int vnc_display_pw_expire(const char *id, time_t expires)
3203 VncDisplay *vs = vnc_display_find(id);
3205 if (!vs) {
3206 return -EINVAL;
3209 vs->expires = expires;
3210 return 0;
3213 static void vnc_display_print_local_addr(VncDisplay *vs)
3215 SocketAddress *addr;
3216 Error *err = NULL;
3218 addr = qio_channel_socket_get_local_address(vs->lsock, &err);
3219 if (!addr) {
3220 return;
3223 if (addr->type != SOCKET_ADDRESS_KIND_INET) {
3224 qapi_free_SocketAddress(addr);
3225 return;
3227 error_printf_unless_qmp("VNC server running on %s:%s\n",
3228 addr->u.inet.data->host,
3229 addr->u.inet.data->port);
3230 qapi_free_SocketAddress(addr);
3233 static QemuOptsList qemu_vnc_opts = {
3234 .name = "vnc",
3235 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3236 .implied_opt_name = "vnc",
3237 .desc = {
3239 .name = "vnc",
3240 .type = QEMU_OPT_STRING,
3242 .name = "websocket",
3243 .type = QEMU_OPT_STRING,
3245 .name = "tls-creds",
3246 .type = QEMU_OPT_STRING,
3248 /* Deprecated in favour of tls-creds */
3249 .name = "x509",
3250 .type = QEMU_OPT_STRING,
3252 .name = "share",
3253 .type = QEMU_OPT_STRING,
3255 .name = "display",
3256 .type = QEMU_OPT_STRING,
3258 .name = "head",
3259 .type = QEMU_OPT_NUMBER,
3261 .name = "connections",
3262 .type = QEMU_OPT_NUMBER,
3264 .name = "to",
3265 .type = QEMU_OPT_NUMBER,
3267 .name = "ipv4",
3268 .type = QEMU_OPT_BOOL,
3270 .name = "ipv6",
3271 .type = QEMU_OPT_BOOL,
3273 .name = "password",
3274 .type = QEMU_OPT_BOOL,
3276 .name = "reverse",
3277 .type = QEMU_OPT_BOOL,
3279 .name = "lock-key-sync",
3280 .type = QEMU_OPT_BOOL,
3282 .name = "key-delay-ms",
3283 .type = QEMU_OPT_NUMBER,
3285 .name = "sasl",
3286 .type = QEMU_OPT_BOOL,
3288 /* Deprecated in favour of tls-creds */
3289 .name = "tls",
3290 .type = QEMU_OPT_BOOL,
3292 /* Deprecated in favour of tls-creds */
3293 .name = "x509verify",
3294 .type = QEMU_OPT_STRING,
3296 .name = "acl",
3297 .type = QEMU_OPT_BOOL,
3299 .name = "lossy",
3300 .type = QEMU_OPT_BOOL,
3302 .name = "non-adaptive",
3303 .type = QEMU_OPT_BOOL,
3305 { /* end of list */ }
3310 static int
3311 vnc_display_setup_auth(VncDisplay *vs,
3312 bool password,
3313 bool sasl,
3314 bool websocket,
3315 Error **errp)
3318 * We have a choice of 3 authentication options
3320 * 1. none
3321 * 2. vnc
3322 * 3. sasl
3324 * The channel can be run in 2 modes
3326 * 1. clear
3327 * 2. tls
3329 * And TLS can use 2 types of credentials
3331 * 1. anon
3332 * 2. x509
3334 * We thus have 9 possible logical combinations
3336 * 1. clear + none
3337 * 2. clear + vnc
3338 * 3. clear + sasl
3339 * 4. tls + anon + none
3340 * 5. tls + anon + vnc
3341 * 6. tls + anon + sasl
3342 * 7. tls + x509 + none
3343 * 8. tls + x509 + vnc
3344 * 9. tls + x509 + sasl
3346 * These need to be mapped into the VNC auth schemes
3347 * in an appropriate manner. In regular VNC, all the
3348 * TLS options get mapped into VNC_AUTH_VENCRYPT
3349 * sub-auth types.
3351 * In websockets, the https:// protocol already provides
3352 * TLS support, so there is no need to make use of the
3353 * VeNCrypt extension. Furthermore, websockets browser
3354 * clients could not use VeNCrypt even if they wanted to,
3355 * as they cannot control when the TLS handshake takes
3356 * place. Thus there is no option but to rely on https://,
3357 * meaning combinations 4->6 and 7->9 will be mapped to
3358 * VNC auth schemes in the same way as combos 1->3.
3360 * Regardless of fact that we have a different mapping to
3361 * VNC auth mechs for plain VNC vs websockets VNC, the end
3362 * result has the same security characteristics.
3364 if (password) {
3365 if (vs->tlscreds) {
3366 vs->auth = VNC_AUTH_VENCRYPT;
3367 if (websocket) {
3368 vs->ws_tls = true;
3370 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3371 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3372 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3373 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3374 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3375 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3376 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3377 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3378 } else {
3379 error_setg(errp,
3380 "Unsupported TLS cred type %s",
3381 object_get_typename(OBJECT(vs->tlscreds)));
3382 return -1;
3384 } else {
3385 VNC_DEBUG("Initializing VNC server with password auth\n");
3386 vs->auth = VNC_AUTH_VNC;
3387 vs->subauth = VNC_AUTH_INVALID;
3389 if (websocket) {
3390 vs->ws_auth = VNC_AUTH_VNC;
3391 } else {
3392 vs->ws_auth = VNC_AUTH_INVALID;
3394 } else if (sasl) {
3395 if (vs->tlscreds) {
3396 vs->auth = VNC_AUTH_VENCRYPT;
3397 if (websocket) {
3398 vs->ws_tls = true;
3400 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3401 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3402 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3403 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3404 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3405 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3406 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3407 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3408 } else {
3409 error_setg(errp,
3410 "Unsupported TLS cred type %s",
3411 object_get_typename(OBJECT(vs->tlscreds)));
3412 return -1;
3414 } else {
3415 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3416 vs->auth = VNC_AUTH_SASL;
3417 vs->subauth = VNC_AUTH_INVALID;
3419 if (websocket) {
3420 vs->ws_auth = VNC_AUTH_SASL;
3421 } else {
3422 vs->ws_auth = VNC_AUTH_INVALID;
3424 } else {
3425 if (vs->tlscreds) {
3426 vs->auth = VNC_AUTH_VENCRYPT;
3427 if (websocket) {
3428 vs->ws_tls = true;
3430 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3431 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3432 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3433 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3434 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3435 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3436 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3437 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3438 } else {
3439 error_setg(errp,
3440 "Unsupported TLS cred type %s",
3441 object_get_typename(OBJECT(vs->tlscreds)));
3442 return -1;
3444 } else {
3445 VNC_DEBUG("Initializing VNC server with no auth\n");
3446 vs->auth = VNC_AUTH_NONE;
3447 vs->subauth = VNC_AUTH_INVALID;
3449 if (websocket) {
3450 vs->ws_auth = VNC_AUTH_NONE;
3451 } else {
3452 vs->ws_auth = VNC_AUTH_INVALID;
3455 return 0;
3460 * Handle back compat with old CLI syntax by creating some
3461 * suitable QCryptoTLSCreds objects
3463 static QCryptoTLSCreds *
3464 vnc_display_create_creds(bool x509,
3465 bool x509verify,
3466 const char *dir,
3467 const char *id,
3468 Error **errp)
3470 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3471 Object *parent = object_get_objects_root();
3472 Object *creds;
3473 Error *err = NULL;
3475 if (x509) {
3476 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3477 parent,
3478 credsid,
3479 &err,
3480 "endpoint", "server",
3481 "dir", dir,
3482 "verify-peer", x509verify ? "yes" : "no",
3483 NULL);
3484 } else {
3485 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3486 parent,
3487 credsid,
3488 &err,
3489 "endpoint", "server",
3490 NULL);
3493 g_free(credsid);
3495 if (err) {
3496 error_propagate(errp, err);
3497 return NULL;
3500 return QCRYPTO_TLS_CREDS(creds);
3504 void vnc_display_open(const char *id, Error **errp)
3506 VncDisplay *vs = vnc_display_find(id);
3507 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3508 SocketAddress *saddr = NULL, *wsaddr = NULL;
3509 const char *share, *device_id;
3510 QemuConsole *con;
3511 bool password = false;
3512 bool reverse = false;
3513 const char *vnc;
3514 char *h;
3515 const char *credid;
3516 int show_vnc_port = 0;
3517 bool sasl = false;
3518 #ifdef CONFIG_VNC_SASL
3519 int saslErr;
3520 #endif
3521 int acl = 0;
3522 int lock_key_sync = 1;
3523 int key_delay_ms;
3525 if (!vs) {
3526 error_setg(errp, "VNC display not active");
3527 return;
3529 vnc_display_close(vs);
3531 if (!opts) {
3532 return;
3534 vnc = qemu_opt_get(opts, "vnc");
3535 if (!vnc || strcmp(vnc, "none") == 0) {
3536 return;
3539 h = strrchr(vnc, ':');
3540 if (h) {
3541 size_t hlen = h - vnc;
3543 const char *websocket = qemu_opt_get(opts, "websocket");
3544 int to = qemu_opt_get_number(opts, "to", 0);
3545 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3546 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3547 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3548 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3550 saddr = g_new0(SocketAddress, 1);
3551 if (websocket) {
3552 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3553 error_setg(errp,
3554 "SHA1 hash support is required for websockets");
3555 goto fail;
3558 wsaddr = g_new0(SocketAddress, 1);
3559 vs->ws_enabled = true;
3562 if (strncmp(vnc, "unix:", 5) == 0) {
3563 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3564 saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
3565 saddr->u.q_unix.data->path = g_strdup(vnc + 5);
3567 if (vs->ws_enabled) {
3568 error_setg(errp, "UNIX sockets not supported with websock");
3569 goto fail;
3571 } else {
3572 unsigned long long baseport;
3573 InetSocketAddress *inet;
3574 saddr->type = SOCKET_ADDRESS_KIND_INET;
3575 inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
3576 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3577 inet->host = g_strndup(vnc + 1, hlen - 2);
3578 } else {
3579 inet->host = g_strndup(vnc, hlen);
3581 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3582 error_setg(errp, "can't convert to a number: %s", h + 1);
3583 goto fail;
3585 if (baseport > 65535 ||
3586 baseport + 5900 > 65535) {
3587 error_setg(errp, "port %s out of range", h + 1);
3588 goto fail;
3590 inet->port = g_strdup_printf(
3591 "%d", (int)baseport + 5900);
3593 if (to) {
3594 inet->has_to = true;
3595 inet->to = to + 5900;
3596 show_vnc_port = 1;
3598 inet->ipv4 = ipv4;
3599 inet->has_ipv4 = has_ipv4;
3600 inet->ipv6 = ipv6;
3601 inet->has_ipv6 = has_ipv6;
3603 if (vs->ws_enabled) {
3604 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3605 inet = wsaddr->u.inet.data = g_new0(InetSocketAddress, 1);
3606 inet->host = g_strdup(saddr->u.inet.data->host);
3607 inet->port = g_strdup(websocket);
3609 if (to) {
3610 inet->has_to = true;
3611 inet->to = to;
3613 inet->ipv4 = ipv4;
3614 inet->has_ipv4 = has_ipv4;
3615 inet->ipv6 = ipv6;
3616 inet->has_ipv6 = has_ipv6;
3619 } else {
3620 error_setg(errp, "no vnc port specified");
3621 goto fail;
3624 password = qemu_opt_get_bool(opts, "password", false);
3625 if (password) {
3626 if (fips_get_state()) {
3627 error_setg(errp,
3628 "VNC password auth disabled due to FIPS mode, "
3629 "consider using the VeNCrypt or SASL authentication "
3630 "methods as an alternative");
3631 goto fail;
3633 if (!qcrypto_cipher_supports(
3634 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3635 error_setg(errp,
3636 "Cipher backend does not support DES RFB algorithm");
3637 goto fail;
3641 reverse = qemu_opt_get_bool(opts, "reverse", false);
3642 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3643 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
3644 sasl = qemu_opt_get_bool(opts, "sasl", false);
3645 #ifndef CONFIG_VNC_SASL
3646 if (sasl) {
3647 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3648 goto fail;
3650 #endif /* CONFIG_VNC_SASL */
3651 credid = qemu_opt_get(opts, "tls-creds");
3652 if (credid) {
3653 Object *creds;
3654 if (qemu_opt_get(opts, "tls") ||
3655 qemu_opt_get(opts, "x509") ||
3656 qemu_opt_get(opts, "x509verify")) {
3657 error_setg(errp,
3658 "'tls-creds' parameter is mutually exclusive with "
3659 "'tls', 'x509' and 'x509verify' parameters");
3660 goto fail;
3663 creds = object_resolve_path_component(
3664 object_get_objects_root(), credid);
3665 if (!creds) {
3666 error_setg(errp, "No TLS credentials with id '%s'",
3667 credid);
3668 goto fail;
3670 vs->tlscreds = (QCryptoTLSCreds *)
3671 object_dynamic_cast(creds,
3672 TYPE_QCRYPTO_TLS_CREDS);
3673 if (!vs->tlscreds) {
3674 error_setg(errp, "Object with id '%s' is not TLS credentials",
3675 credid);
3676 goto fail;
3678 object_ref(OBJECT(vs->tlscreds));
3680 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3681 error_setg(errp,
3682 "Expecting TLS credentials with a server endpoint");
3683 goto fail;
3685 } else {
3686 const char *path;
3687 bool tls = false, x509 = false, x509verify = false;
3688 tls = qemu_opt_get_bool(opts, "tls", false);
3689 if (tls) {
3690 path = qemu_opt_get(opts, "x509");
3692 if (path) {
3693 x509 = true;
3694 } else {
3695 path = qemu_opt_get(opts, "x509verify");
3696 if (path) {
3697 x509 = true;
3698 x509verify = true;
3701 vs->tlscreds = vnc_display_create_creds(x509,
3702 x509verify,
3703 path,
3704 vs->id,
3705 errp);
3706 if (!vs->tlscreds) {
3707 goto fail;
3711 acl = qemu_opt_get_bool(opts, "acl", false);
3713 share = qemu_opt_get(opts, "share");
3714 if (share) {
3715 if (strcmp(share, "ignore") == 0) {
3716 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3717 } else if (strcmp(share, "allow-exclusive") == 0) {
3718 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3719 } else if (strcmp(share, "force-shared") == 0) {
3720 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3721 } else {
3722 error_setg(errp, "unknown vnc share= option");
3723 goto fail;
3725 } else {
3726 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3728 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3730 #ifdef CONFIG_VNC_JPEG
3731 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3732 #endif
3733 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3734 /* adaptive updates are only used with tight encoding and
3735 * if lossy updates are enabled so we can disable all the
3736 * calculations otherwise */
3737 if (!vs->lossy) {
3738 vs->non_adaptive = true;
3741 if (acl) {
3742 if (strcmp(vs->id, "default") == 0) {
3743 vs->tlsaclname = g_strdup("vnc.x509dname");
3744 } else {
3745 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3747 qemu_acl_init(vs->tlsaclname);
3749 #ifdef CONFIG_VNC_SASL
3750 if (acl && sasl) {
3751 char *aclname;
3753 if (strcmp(vs->id, "default") == 0) {
3754 aclname = g_strdup("vnc.username");
3755 } else {
3756 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3758 vs->sasl.acl = qemu_acl_init(aclname);
3759 g_free(aclname);
3761 #endif
3763 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3764 goto fail;
3767 #ifdef CONFIG_VNC_SASL
3768 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3769 error_setg(errp, "Failed to initialize SASL auth: %s",
3770 sasl_errstring(saslErr, NULL, NULL));
3771 goto fail;
3773 #endif
3774 vs->lock_key_sync = lock_key_sync;
3775 vs->key_delay_ms = key_delay_ms;
3777 device_id = qemu_opt_get(opts, "display");
3778 if (device_id) {
3779 int head = qemu_opt_get_number(opts, "head", 0);
3780 Error *err = NULL;
3782 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3783 if (err) {
3784 error_propagate(errp, err);
3785 goto fail;
3787 } else {
3788 con = NULL;
3791 if (con != vs->dcl.con) {
3792 unregister_displaychangelistener(&vs->dcl);
3793 vs->dcl.con = con;
3794 register_displaychangelistener(&vs->dcl);
3797 if (reverse) {
3798 /* connect to viewer */
3799 QIOChannelSocket *sioc = NULL;
3800 vs->lsock = NULL;
3801 vs->lwebsock = NULL;
3802 if (vs->ws_enabled) {
3803 error_setg(errp, "Cannot use websockets in reverse mode");
3804 goto fail;
3806 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3807 sioc = qio_channel_socket_new();
3808 if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
3809 goto fail;
3811 vnc_connect(vs, sioc, false, false);
3812 object_unref(OBJECT(sioc));
3813 } else {
3814 vs->lsock = qio_channel_socket_new();
3815 if (qio_channel_socket_listen_sync(vs->lsock, saddr, errp) < 0) {
3816 goto fail;
3818 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3819 vs->enabled = true;
3821 if (vs->ws_enabled) {
3822 vs->lwebsock = qio_channel_socket_new();
3823 if (qio_channel_socket_listen_sync(vs->lwebsock,
3824 wsaddr, errp) < 0) {
3825 object_unref(OBJECT(vs->lsock));
3826 vs->lsock = NULL;
3827 goto fail;
3831 vs->lsock_tag = qio_channel_add_watch(
3832 QIO_CHANNEL(vs->lsock),
3833 G_IO_IN, vnc_listen_io, vs, NULL);
3834 if (vs->ws_enabled) {
3835 vs->lwebsock_tag = qio_channel_add_watch(
3836 QIO_CHANNEL(vs->lwebsock),
3837 G_IO_IN, vnc_listen_io, vs, NULL);
3841 if (show_vnc_port) {
3842 vnc_display_print_local_addr(vs);
3845 qapi_free_SocketAddress(saddr);
3846 qapi_free_SocketAddress(wsaddr);
3847 return;
3849 fail:
3850 qapi_free_SocketAddress(saddr);
3851 qapi_free_SocketAddress(wsaddr);
3852 vs->enabled = false;
3853 vs->ws_enabled = false;
3856 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3858 VncDisplay *vs = vnc_display_find(id);
3859 QIOChannelSocket *sioc;
3861 if (!vs) {
3862 return;
3865 sioc = qio_channel_socket_new_fd(csock, NULL);
3866 if (sioc) {
3867 vnc_connect(vs, sioc, skipauth, false);
3868 object_unref(OBJECT(sioc));
3872 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3874 int i = 2;
3875 char *id;
3877 id = g_strdup("default");
3878 while (qemu_opts_find(olist, id)) {
3879 g_free(id);
3880 id = g_strdup_printf("vnc%d", i++);
3882 qemu_opts_set_id(opts, id);
3885 QemuOpts *vnc_parse(const char *str, Error **errp)
3887 QemuOptsList *olist = qemu_find_opts("vnc");
3888 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3889 const char *id;
3891 if (!opts) {
3892 return NULL;
3895 id = qemu_opts_id(opts);
3896 if (!id) {
3897 /* auto-assign id if not present */
3898 vnc_auto_assign_id(olist, opts);
3900 return opts;
3903 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3905 Error *local_err = NULL;
3906 char *id = (char *)qemu_opts_id(opts);
3908 assert(id);
3909 vnc_display_init(id);
3910 vnc_display_open(id, &local_err);
3911 if (local_err != NULL) {
3912 error_reportf_err(local_err, "Failed to start VNC server: ");
3913 exit(1);
3915 return 0;
3918 static void vnc_register_config(void)
3920 qemu_add_opts(&qemu_vnc_opts);
3922 opts_init(vnc_register_config);