tests: Resort check-qtest entries in Makefile.include
[qemu/rayw.git] / ui / vnc.c
blobd1087c93a5968614b88ae0e373e2960e634d127f
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 if (!ioc) {
147 error_setg(errp, "No listener socket available");
148 return;
151 addr = qio_channel_socket_get_local_address(ioc, errp);
152 if (!addr) {
153 return;
156 vnc_init_basic_info(addr, info, errp);
157 qapi_free_SocketAddress(addr);
160 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
161 VncBasicInfo *info,
162 Error **errp)
164 SocketAddress *addr = NULL;
166 addr = qio_channel_socket_get_remote_address(ioc, errp);
167 if (!addr) {
168 return;
171 vnc_init_basic_info(addr, info, errp);
172 qapi_free_SocketAddress(addr);
175 static const char *vnc_auth_name(VncDisplay *vd) {
176 switch (vd->auth) {
177 case VNC_AUTH_INVALID:
178 return "invalid";
179 case VNC_AUTH_NONE:
180 return "none";
181 case VNC_AUTH_VNC:
182 return "vnc";
183 case VNC_AUTH_RA2:
184 return "ra2";
185 case VNC_AUTH_RA2NE:
186 return "ra2ne";
187 case VNC_AUTH_TIGHT:
188 return "tight";
189 case VNC_AUTH_ULTRA:
190 return "ultra";
191 case VNC_AUTH_TLS:
192 return "tls";
193 case VNC_AUTH_VENCRYPT:
194 switch (vd->subauth) {
195 case VNC_AUTH_VENCRYPT_PLAIN:
196 return "vencrypt+plain";
197 case VNC_AUTH_VENCRYPT_TLSNONE:
198 return "vencrypt+tls+none";
199 case VNC_AUTH_VENCRYPT_TLSVNC:
200 return "vencrypt+tls+vnc";
201 case VNC_AUTH_VENCRYPT_TLSPLAIN:
202 return "vencrypt+tls+plain";
203 case VNC_AUTH_VENCRYPT_X509NONE:
204 return "vencrypt+x509+none";
205 case VNC_AUTH_VENCRYPT_X509VNC:
206 return "vencrypt+x509+vnc";
207 case VNC_AUTH_VENCRYPT_X509PLAIN:
208 return "vencrypt+x509+plain";
209 case VNC_AUTH_VENCRYPT_TLSSASL:
210 return "vencrypt+tls+sasl";
211 case VNC_AUTH_VENCRYPT_X509SASL:
212 return "vencrypt+x509+sasl";
213 default:
214 return "vencrypt";
216 case VNC_AUTH_SASL:
217 return "sasl";
219 return "unknown";
222 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
224 VncServerInfo *info;
225 Error *err = NULL;
227 info = g_malloc0(sizeof(*info));
228 vnc_init_basic_info_from_server_addr(vd->lsock,
229 qapi_VncServerInfo_base(info), &err);
230 info->has_auth = true;
231 info->auth = g_strdup(vnc_auth_name(vd));
232 if (err) {
233 qapi_free_VncServerInfo(info);
234 info = NULL;
235 error_free(err);
237 return info;
240 static void vnc_client_cache_auth(VncState *client)
242 if (!client->info) {
243 return;
246 if (client->tls) {
247 client->info->x509_dname =
248 qcrypto_tls_session_get_peer_name(client->tls);
249 client->info->has_x509_dname =
250 client->info->x509_dname != NULL;
252 #ifdef CONFIG_VNC_SASL
253 if (client->sasl.conn &&
254 client->sasl.username) {
255 client->info->has_sasl_username = true;
256 client->info->sasl_username = g_strdup(client->sasl.username);
258 #endif
261 static void vnc_client_cache_addr(VncState *client)
263 Error *err = NULL;
265 client->info = g_malloc0(sizeof(*client->info));
266 vnc_init_basic_info_from_remote_addr(client->sioc,
267 qapi_VncClientInfo_base(client->info),
268 &err);
269 if (err) {
270 qapi_free_VncClientInfo(client->info);
271 client->info = NULL;
272 error_free(err);
276 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
278 VncServerInfo *si;
280 if (!vs->info) {
281 return;
284 si = vnc_server_info_get(vs->vd);
285 if (!si) {
286 return;
289 switch (event) {
290 case QAPI_EVENT_VNC_CONNECTED:
291 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
292 &error_abort);
293 break;
294 case QAPI_EVENT_VNC_INITIALIZED:
295 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
296 break;
297 case QAPI_EVENT_VNC_DISCONNECTED:
298 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
299 break;
300 default:
301 break;
304 qapi_free_VncServerInfo(si);
307 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
309 VncClientInfo *info;
310 Error *err = NULL;
312 info = g_malloc0(sizeof(*info));
314 vnc_init_basic_info_from_remote_addr(client->sioc,
315 qapi_VncClientInfo_base(info),
316 &err);
317 if (err) {
318 error_free(err);
319 qapi_free_VncClientInfo(info);
320 return NULL;
323 info->websocket = client->websocket;
325 if (client->tls) {
326 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
327 info->has_x509_dname = info->x509_dname != NULL;
329 #ifdef CONFIG_VNC_SASL
330 if (client->sasl.conn && client->sasl.username) {
331 info->has_sasl_username = true;
332 info->sasl_username = g_strdup(client->sasl.username);
334 #endif
336 return info;
339 static VncDisplay *vnc_display_find(const char *id)
341 VncDisplay *vd;
343 if (id == NULL) {
344 return QTAILQ_FIRST(&vnc_displays);
346 QTAILQ_FOREACH(vd, &vnc_displays, next) {
347 if (strcmp(id, vd->id) == 0) {
348 return vd;
351 return NULL;
354 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
356 VncClientInfoList *cinfo, *prev = NULL;
357 VncState *client;
359 QTAILQ_FOREACH(client, &vd->clients, next) {
360 cinfo = g_new0(VncClientInfoList, 1);
361 cinfo->value = qmp_query_vnc_client(client);
362 cinfo->next = prev;
363 prev = cinfo;
365 return prev;
368 VncInfo *qmp_query_vnc(Error **errp)
370 VncInfo *info = g_malloc0(sizeof(*info));
371 VncDisplay *vd = vnc_display_find(NULL);
372 SocketAddress *addr = NULL;
374 if (vd == NULL || !vd->enabled) {
375 info->enabled = false;
376 } else {
377 info->enabled = true;
379 /* for compatibility with the original command */
380 info->has_clients = true;
381 info->clients = qmp_query_client_list(vd);
383 if (vd->lsock == NULL) {
384 return info;
387 addr = qio_channel_socket_get_local_address(vd->lsock, errp);
388 if (!addr) {
389 goto out_error;
392 switch (addr->type) {
393 case SOCKET_ADDRESS_KIND_INET:
394 info->host = g_strdup(addr->u.inet.data->host);
395 info->service = g_strdup(addr->u.inet.data->port);
396 if (addr->u.inet.data->ipv6) {
397 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
398 } else {
399 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
401 break;
403 case SOCKET_ADDRESS_KIND_UNIX:
404 info->host = g_strdup("");
405 info->service = g_strdup(addr->u.q_unix.data->path);
406 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
407 break;
409 default:
410 error_setg(errp, "Unsupported socket kind %d",
411 addr->type);
412 goto out_error;
415 info->has_host = true;
416 info->has_service = true;
417 info->has_family = true;
419 info->has_auth = true;
420 info->auth = g_strdup(vnc_auth_name(vd));
423 qapi_free_SocketAddress(addr);
424 return info;
426 out_error:
427 qapi_free_SocketAddress(addr);
428 qapi_free_VncInfo(info);
429 return NULL;
432 static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,
433 bool websocket,
434 VncBasicInfoList *prev)
436 VncBasicInfoList *list;
437 VncBasicInfo *info;
438 Error *err = NULL;
439 SocketAddress *addr;
441 addr = qio_channel_socket_get_local_address(ioc, &err);
442 if (!addr) {
443 error_free(err);
444 return prev;
447 info = g_new0(VncBasicInfo, 1);
448 vnc_init_basic_info(addr, info, &err);
449 qapi_free_SocketAddress(addr);
450 if (err) {
451 qapi_free_VncBasicInfo(info);
452 error_free(err);
453 return prev;
455 info->websocket = websocket;
457 list = g_new0(VncBasicInfoList, 1);
458 list->value = info;
459 list->next = prev;
460 return list;
463 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
465 switch (vd->auth) {
466 case VNC_AUTH_VNC:
467 info->auth = VNC_PRIMARY_AUTH_VNC;
468 break;
469 case VNC_AUTH_RA2:
470 info->auth = VNC_PRIMARY_AUTH_RA2;
471 break;
472 case VNC_AUTH_RA2NE:
473 info->auth = VNC_PRIMARY_AUTH_RA2NE;
474 break;
475 case VNC_AUTH_TIGHT:
476 info->auth = VNC_PRIMARY_AUTH_TIGHT;
477 break;
478 case VNC_AUTH_ULTRA:
479 info->auth = VNC_PRIMARY_AUTH_ULTRA;
480 break;
481 case VNC_AUTH_TLS:
482 info->auth = VNC_PRIMARY_AUTH_TLS;
483 break;
484 case VNC_AUTH_VENCRYPT:
485 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
486 info->has_vencrypt = true;
487 switch (vd->subauth) {
488 case VNC_AUTH_VENCRYPT_PLAIN:
489 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
490 break;
491 case VNC_AUTH_VENCRYPT_TLSNONE:
492 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
493 break;
494 case VNC_AUTH_VENCRYPT_TLSVNC:
495 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
496 break;
497 case VNC_AUTH_VENCRYPT_TLSPLAIN:
498 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
499 break;
500 case VNC_AUTH_VENCRYPT_X509NONE:
501 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
502 break;
503 case VNC_AUTH_VENCRYPT_X509VNC:
504 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
505 break;
506 case VNC_AUTH_VENCRYPT_X509PLAIN:
507 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
508 break;
509 case VNC_AUTH_VENCRYPT_TLSSASL:
510 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
511 break;
512 case VNC_AUTH_VENCRYPT_X509SASL:
513 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
514 break;
515 default:
516 info->has_vencrypt = false;
517 break;
519 break;
520 case VNC_AUTH_SASL:
521 info->auth = VNC_PRIMARY_AUTH_SASL;
522 break;
523 case VNC_AUTH_NONE:
524 default:
525 info->auth = VNC_PRIMARY_AUTH_NONE;
526 break;
530 VncInfo2List *qmp_query_vnc_servers(Error **errp)
532 VncInfo2List *item, *prev = NULL;
533 VncInfo2 *info;
534 VncDisplay *vd;
535 DeviceState *dev;
537 QTAILQ_FOREACH(vd, &vnc_displays, next) {
538 info = g_new0(VncInfo2, 1);
539 info->id = g_strdup(vd->id);
540 info->clients = qmp_query_client_list(vd);
541 qmp_query_auth(vd, info);
542 if (vd->dcl.con) {
543 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
544 "device", NULL));
545 info->has_display = true;
546 info->display = g_strdup(dev->id);
548 if (vd->lsock != NULL) {
549 info->server = qmp_query_server_entry(
550 vd->lsock, false, info->server);
552 if (vd->lwebsock != NULL) {
553 info->server = qmp_query_server_entry(
554 vd->lwebsock, true, info->server);
557 item = g_new0(VncInfo2List, 1);
558 item->value = info;
559 item->next = prev;
560 prev = item;
562 return prev;
565 /* TODO
566 1) Get the queue working for IO.
567 2) there is some weirdness when using the -S option (the screen is grey
568 and not totally invalidated
569 3) resolutions > 1024
572 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
573 static void vnc_disconnect_start(VncState *vs);
575 static void vnc_colordepth(VncState *vs);
576 static void framebuffer_update_request(VncState *vs, int incremental,
577 int x_position, int y_position,
578 int w, int h);
579 static void vnc_refresh(DisplayChangeListener *dcl);
580 static int vnc_refresh_server_surface(VncDisplay *vd);
582 static int vnc_width(VncDisplay *vd)
584 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
585 VNC_DIRTY_PIXELS_PER_BIT));
588 static int vnc_height(VncDisplay *vd)
590 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
593 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
594 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
595 VncDisplay *vd,
596 int x, int y, int w, int h)
598 int width = vnc_width(vd);
599 int height = vnc_height(vd);
601 /* this is needed this to ensure we updated all affected
602 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
603 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
604 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
606 x = MIN(x, width);
607 y = MIN(y, height);
608 w = MIN(x + w, width) - x;
609 h = MIN(y + h, height);
611 for (; y < h; y++) {
612 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
613 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
617 static void vnc_dpy_update(DisplayChangeListener *dcl,
618 int x, int y, int w, int h)
620 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
621 struct VncSurface *s = &vd->guest;
623 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
626 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
627 int32_t encoding)
629 vnc_write_u16(vs, x);
630 vnc_write_u16(vs, y);
631 vnc_write_u16(vs, w);
632 vnc_write_u16(vs, h);
634 vnc_write_s32(vs, encoding);
638 static void vnc_desktop_resize(VncState *vs)
640 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
641 return;
643 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
644 vs->client_height == pixman_image_get_height(vs->vd->server)) {
645 return;
647 vs->client_width = pixman_image_get_width(vs->vd->server);
648 vs->client_height = pixman_image_get_height(vs->vd->server);
649 vnc_lock_output(vs);
650 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
651 vnc_write_u8(vs, 0);
652 vnc_write_u16(vs, 1); /* number of rects */
653 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
654 VNC_ENCODING_DESKTOPRESIZE);
655 vnc_unlock_output(vs);
656 vnc_flush(vs);
659 static void vnc_abort_display_jobs(VncDisplay *vd)
661 VncState *vs;
663 QTAILQ_FOREACH(vs, &vd->clients, next) {
664 vnc_lock_output(vs);
665 vs->abort = true;
666 vnc_unlock_output(vs);
668 QTAILQ_FOREACH(vs, &vd->clients, next) {
669 vnc_jobs_join(vs);
671 QTAILQ_FOREACH(vs, &vd->clients, next) {
672 vnc_lock_output(vs);
673 vs->abort = false;
674 vnc_unlock_output(vs);
678 int vnc_server_fb_stride(VncDisplay *vd)
680 return pixman_image_get_stride(vd->server);
683 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
685 uint8_t *ptr;
687 ptr = (uint8_t *)pixman_image_get_data(vd->server);
688 ptr += y * vnc_server_fb_stride(vd);
689 ptr += x * VNC_SERVER_FB_BYTES;
690 return ptr;
693 static void vnc_update_server_surface(VncDisplay *vd)
695 int width, height;
697 qemu_pixman_image_unref(vd->server);
698 vd->server = NULL;
700 if (QTAILQ_EMPTY(&vd->clients)) {
701 return;
704 width = vnc_width(vd);
705 height = vnc_height(vd);
706 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
707 width, height,
708 NULL, 0);
710 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
711 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
712 width, height);
715 static void vnc_dpy_switch(DisplayChangeListener *dcl,
716 DisplaySurface *surface)
718 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
719 VncState *vs;
721 vnc_abort_display_jobs(vd);
722 vd->ds = surface;
724 /* server surface */
725 vnc_update_server_surface(vd);
727 /* guest surface */
728 qemu_pixman_image_unref(vd->guest.fb);
729 vd->guest.fb = pixman_image_ref(surface->image);
730 vd->guest.format = surface->format;
732 QTAILQ_FOREACH(vs, &vd->clients, next) {
733 vnc_colordepth(vs);
734 vnc_desktop_resize(vs);
735 if (vs->vd->cursor) {
736 vnc_cursor_define(vs);
738 memset(vs->dirty, 0x00, sizeof(vs->dirty));
739 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
740 vnc_width(vd),
741 vnc_height(vd));
745 /* fastest code */
746 static void vnc_write_pixels_copy(VncState *vs,
747 void *pixels, int size)
749 vnc_write(vs, pixels, size);
752 /* slowest but generic code. */
753 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
755 uint8_t r, g, b;
757 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
758 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
759 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
760 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
761 #else
762 # error need some bits here if you change VNC_SERVER_FB_FORMAT
763 #endif
764 v = (r << vs->client_pf.rshift) |
765 (g << vs->client_pf.gshift) |
766 (b << vs->client_pf.bshift);
767 switch (vs->client_pf.bytes_per_pixel) {
768 case 1:
769 buf[0] = v;
770 break;
771 case 2:
772 if (vs->client_be) {
773 buf[0] = v >> 8;
774 buf[1] = v;
775 } else {
776 buf[1] = v >> 8;
777 buf[0] = v;
779 break;
780 default:
781 case 4:
782 if (vs->client_be) {
783 buf[0] = v >> 24;
784 buf[1] = v >> 16;
785 buf[2] = v >> 8;
786 buf[3] = v;
787 } else {
788 buf[3] = v >> 24;
789 buf[2] = v >> 16;
790 buf[1] = v >> 8;
791 buf[0] = v;
793 break;
797 static void vnc_write_pixels_generic(VncState *vs,
798 void *pixels1, int size)
800 uint8_t buf[4];
802 if (VNC_SERVER_FB_BYTES == 4) {
803 uint32_t *pixels = pixels1;
804 int n, i;
805 n = size >> 2;
806 for (i = 0; i < n; i++) {
807 vnc_convert_pixel(vs, buf, pixels[i]);
808 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
813 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
815 int i;
816 uint8_t *row;
817 VncDisplay *vd = vs->vd;
819 row = vnc_server_fb_ptr(vd, x, y);
820 for (i = 0; i < h; i++) {
821 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
822 row += vnc_server_fb_stride(vd);
824 return 1;
827 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
829 int n = 0;
830 bool encode_raw = false;
831 size_t saved_offs = vs->output.offset;
833 switch(vs->vnc_encoding) {
834 case VNC_ENCODING_ZLIB:
835 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
836 break;
837 case VNC_ENCODING_HEXTILE:
838 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
839 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
840 break;
841 case VNC_ENCODING_TIGHT:
842 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
843 break;
844 case VNC_ENCODING_TIGHT_PNG:
845 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
846 break;
847 case VNC_ENCODING_ZRLE:
848 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
849 break;
850 case VNC_ENCODING_ZYWRLE:
851 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
852 break;
853 default:
854 encode_raw = true;
855 break;
858 /* If the client has the same pixel format as our internal buffer and
859 * a RAW encoding would need less space fall back to RAW encoding to
860 * save bandwidth and processing power in the client. */
861 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
862 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
863 vs->output.offset = saved_offs;
864 encode_raw = true;
867 if (encode_raw) {
868 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
869 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
872 return n;
875 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
877 /* send bitblit op to the vnc client */
878 vnc_lock_output(vs);
879 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
880 vnc_write_u8(vs, 0);
881 vnc_write_u16(vs, 1); /* number of rects */
882 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
883 vnc_write_u16(vs, src_x);
884 vnc_write_u16(vs, src_y);
885 vnc_unlock_output(vs);
886 vnc_flush(vs);
889 static void vnc_dpy_copy(DisplayChangeListener *dcl,
890 int src_x, int src_y,
891 int dst_x, int dst_y, int w, int h)
893 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
894 VncState *vs, *vn;
895 uint8_t *src_row;
896 uint8_t *dst_row;
897 int i, x, y, pitch, inc, w_lim, s;
898 int cmp_bytes;
900 if (!vd->server) {
901 /* no client connected */
902 return;
905 vnc_refresh_server_surface(vd);
906 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
907 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
908 vs->force_update = 1;
909 vnc_update_client(vs, 1, true);
910 /* vs might be free()ed here */
914 /* do bitblit op on the local surface too */
915 pitch = vnc_server_fb_stride(vd);
916 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
917 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
918 y = dst_y;
919 inc = 1;
920 if (dst_y > src_y) {
921 /* copy backwards */
922 src_row += pitch * (h-1);
923 dst_row += pitch * (h-1);
924 pitch = -pitch;
925 y = dst_y + h - 1;
926 inc = -1;
928 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
929 if (w_lim < 0) {
930 w_lim = w;
931 } else {
932 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
934 for (i = 0; i < h; i++) {
935 for (x = 0; x <= w_lim;
936 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
937 if (x == w_lim) {
938 if ((s = w - w_lim) == 0)
939 break;
940 } else if (!x) {
941 s = (VNC_DIRTY_PIXELS_PER_BIT -
942 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
943 s = MIN(s, w_lim);
944 } else {
945 s = VNC_DIRTY_PIXELS_PER_BIT;
947 cmp_bytes = s * VNC_SERVER_FB_BYTES;
948 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
949 continue;
950 memmove(dst_row, src_row, cmp_bytes);
951 QTAILQ_FOREACH(vs, &vd->clients, next) {
952 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
953 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
954 vs->dirty[y]);
958 src_row += pitch - w * VNC_SERVER_FB_BYTES;
959 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
960 y += inc;
963 QTAILQ_FOREACH(vs, &vd->clients, next) {
964 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
965 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
970 static void vnc_mouse_set(DisplayChangeListener *dcl,
971 int x, int y, int visible)
973 /* can we ask the client(s) to move the pointer ??? */
976 static int vnc_cursor_define(VncState *vs)
978 QEMUCursor *c = vs->vd->cursor;
979 int isize;
981 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
982 vnc_lock_output(vs);
983 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
984 vnc_write_u8(vs, 0); /* padding */
985 vnc_write_u16(vs, 1); /* # of rects */
986 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
987 VNC_ENCODING_RICH_CURSOR);
988 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
989 vnc_write_pixels_generic(vs, c->data, isize);
990 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
991 vnc_unlock_output(vs);
992 return 0;
994 return -1;
997 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
998 QEMUCursor *c)
1000 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1001 VncState *vs;
1003 cursor_put(vd->cursor);
1004 g_free(vd->cursor_mask);
1006 vd->cursor = c;
1007 cursor_get(vd->cursor);
1008 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1009 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1010 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1012 QTAILQ_FOREACH(vs, &vd->clients, next) {
1013 vnc_cursor_define(vs);
1017 static int find_and_clear_dirty_height(VncState *vs,
1018 int y, int last_x, int x, int height)
1020 int h;
1022 for (h = 1; h < (height - y); h++) {
1023 if (!test_bit(last_x, vs->dirty[y + h])) {
1024 break;
1026 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1029 return h;
1032 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1034 if (vs->disconnecting) {
1035 vnc_disconnect_finish(vs);
1036 return 0;
1039 vs->has_dirty += has_dirty;
1040 if (vs->need_update && !vs->disconnecting) {
1041 VncDisplay *vd = vs->vd;
1042 VncJob *job;
1043 int y;
1044 int height, width;
1045 int n = 0;
1047 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1048 /* kernel send buffers are full -> drop frames to throttle */
1049 return 0;
1051 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1052 return 0;
1055 * Send screen updates to the vnc client using the server
1056 * surface and server dirty map. guest surface updates
1057 * happening in parallel don't disturb us, the next pass will
1058 * send them to the client.
1060 job = vnc_job_new(vs);
1062 height = pixman_image_get_height(vd->server);
1063 width = pixman_image_get_width(vd->server);
1065 y = 0;
1066 for (;;) {
1067 int x, h;
1068 unsigned long x2;
1069 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1070 height * VNC_DIRTY_BPL(vs),
1071 y * VNC_DIRTY_BPL(vs));
1072 if (offset == height * VNC_DIRTY_BPL(vs)) {
1073 /* no more dirty bits */
1074 break;
1076 y = offset / VNC_DIRTY_BPL(vs);
1077 x = offset % VNC_DIRTY_BPL(vs);
1078 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1079 VNC_DIRTY_BPL(vs), x);
1080 bitmap_clear(vs->dirty[y], x, x2 - x);
1081 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1082 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1083 if (x2 > x) {
1084 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1085 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1087 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1088 y += h;
1089 if (y == height) {
1090 break;
1095 vnc_job_push(job);
1096 if (sync) {
1097 vnc_jobs_join(vs);
1099 vs->force_update = 0;
1100 vs->has_dirty = 0;
1101 return n;
1104 if (vs->disconnecting) {
1105 vnc_disconnect_finish(vs);
1106 } else if (sync) {
1107 vnc_jobs_join(vs);
1110 return 0;
1113 /* audio */
1114 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1116 VncState *vs = opaque;
1118 switch (cmd) {
1119 case AUD_CNOTIFY_DISABLE:
1120 vnc_lock_output(vs);
1121 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1122 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1123 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1124 vnc_unlock_output(vs);
1125 vnc_flush(vs);
1126 break;
1128 case AUD_CNOTIFY_ENABLE:
1129 vnc_lock_output(vs);
1130 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1131 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1132 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1133 vnc_unlock_output(vs);
1134 vnc_flush(vs);
1135 break;
1139 static void audio_capture_destroy(void *opaque)
1143 static void audio_capture(void *opaque, void *buf, int size)
1145 VncState *vs = opaque;
1147 vnc_lock_output(vs);
1148 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1149 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1150 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1151 vnc_write_u32(vs, size);
1152 vnc_write(vs, buf, size);
1153 vnc_unlock_output(vs);
1154 vnc_flush(vs);
1157 static void audio_add(VncState *vs)
1159 struct audio_capture_ops ops;
1161 if (vs->audio_cap) {
1162 error_report("audio already running");
1163 return;
1166 ops.notify = audio_capture_notify;
1167 ops.destroy = audio_capture_destroy;
1168 ops.capture = audio_capture;
1170 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1171 if (!vs->audio_cap) {
1172 error_report("Failed to add audio capture");
1176 static void audio_del(VncState *vs)
1178 if (vs->audio_cap) {
1179 AUD_del_capture(vs->audio_cap, vs);
1180 vs->audio_cap = NULL;
1184 static void vnc_disconnect_start(VncState *vs)
1186 if (vs->disconnecting) {
1187 return;
1189 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1190 if (vs->ioc_tag) {
1191 g_source_remove(vs->ioc_tag);
1193 qio_channel_close(vs->ioc, NULL);
1194 vs->disconnecting = TRUE;
1197 void vnc_disconnect_finish(VncState *vs)
1199 int i;
1201 vnc_jobs_join(vs); /* Wait encoding jobs */
1203 vnc_lock_output(vs);
1204 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1206 buffer_free(&vs->input);
1207 buffer_free(&vs->output);
1209 qapi_free_VncClientInfo(vs->info);
1211 vnc_zlib_clear(vs);
1212 vnc_tight_clear(vs);
1213 vnc_zrle_clear(vs);
1215 #ifdef CONFIG_VNC_SASL
1216 vnc_sasl_client_cleanup(vs);
1217 #endif /* CONFIG_VNC_SASL */
1218 audio_del(vs);
1219 vnc_release_modifiers(vs);
1221 if (vs->initialized) {
1222 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1223 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1224 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1225 /* last client gone */
1226 vnc_update_server_surface(vs->vd);
1230 if (vs->vd->lock_key_sync)
1231 qemu_remove_led_event_handler(vs->led);
1232 vnc_unlock_output(vs);
1234 qemu_mutex_destroy(&vs->output_mutex);
1235 if (vs->bh != NULL) {
1236 qemu_bh_delete(vs->bh);
1238 buffer_free(&vs->jobs_buffer);
1240 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1241 g_free(vs->lossy_rect[i]);
1243 g_free(vs->lossy_rect);
1245 object_unref(OBJECT(vs->ioc));
1246 vs->ioc = NULL;
1247 object_unref(OBJECT(vs->sioc));
1248 vs->sioc = NULL;
1249 g_free(vs);
1252 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1254 if (ret <= 0) {
1255 if (ret == 0) {
1256 VNC_DEBUG("Closing down client sock: EOF\n");
1257 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1258 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1259 ret, errp ? error_get_pretty(*errp) : "Unknown");
1262 vnc_disconnect_start(vs);
1263 if (errp) {
1264 error_free(*errp);
1265 *errp = NULL;
1267 return 0;
1269 return ret;
1273 void vnc_client_error(VncState *vs)
1275 VNC_DEBUG("Closing down client sock: protocol error\n");
1276 vnc_disconnect_start(vs);
1281 * Called to write a chunk of data to the client socket. The data may
1282 * be the raw data, or may have already been encoded by SASL.
1283 * The data will be written either straight onto the socket, or
1284 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1286 * NB, it is theoretically possible to have 2 layers of encryption,
1287 * both SASL, and this TLS layer. It is highly unlikely in practice
1288 * though, since SASL encryption will typically be a no-op if TLS
1289 * is active
1291 * Returns the number of bytes written, which may be less than
1292 * the requested 'datalen' if the socket would block. Returns
1293 * -1 on error, and disconnects the client socket.
1295 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1297 Error *err = NULL;
1298 ssize_t ret;
1299 ret = qio_channel_write(
1300 vs->ioc, (const char *)data, datalen, &err);
1301 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1302 return vnc_client_io_error(vs, ret, &err);
1307 * Called to write buffered data to the client socket, when not
1308 * using any SASL SSF encryption layers. Will write as much data
1309 * as possible without blocking. If all buffered data is written,
1310 * will switch the FD poll() handler back to read monitoring.
1312 * Returns the number of bytes written, which may be less than
1313 * the buffered output data if the socket would block. Returns
1314 * -1 on error, and disconnects the client socket.
1316 static ssize_t vnc_client_write_plain(VncState *vs)
1318 ssize_t ret;
1320 #ifdef CONFIG_VNC_SASL
1321 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1322 vs->output.buffer, vs->output.capacity, vs->output.offset,
1323 vs->sasl.waitWriteSSF);
1325 if (vs->sasl.conn &&
1326 vs->sasl.runSSF &&
1327 vs->sasl.waitWriteSSF) {
1328 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1329 if (ret)
1330 vs->sasl.waitWriteSSF -= ret;
1331 } else
1332 #endif /* CONFIG_VNC_SASL */
1333 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1334 if (!ret)
1335 return 0;
1337 buffer_advance(&vs->output, ret);
1339 if (vs->output.offset == 0) {
1340 if (vs->ioc_tag) {
1341 g_source_remove(vs->ioc_tag);
1343 vs->ioc_tag = qio_channel_add_watch(
1344 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1347 return ret;
1352 * First function called whenever there is data to be written to
1353 * the client socket. Will delegate actual work according to whether
1354 * SASL SSF layers are enabled (thus requiring encryption calls)
1356 static void vnc_client_write_locked(VncState *vs)
1358 #ifdef CONFIG_VNC_SASL
1359 if (vs->sasl.conn &&
1360 vs->sasl.runSSF &&
1361 !vs->sasl.waitWriteSSF) {
1362 vnc_client_write_sasl(vs);
1363 } else
1364 #endif /* CONFIG_VNC_SASL */
1366 vnc_client_write_plain(vs);
1370 static void vnc_client_write(VncState *vs)
1373 vnc_lock_output(vs);
1374 if (vs->output.offset) {
1375 vnc_client_write_locked(vs);
1376 } else if (vs->ioc != NULL) {
1377 if (vs->ioc_tag) {
1378 g_source_remove(vs->ioc_tag);
1380 vs->ioc_tag = qio_channel_add_watch(
1381 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1383 vnc_unlock_output(vs);
1386 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1388 vs->read_handler = func;
1389 vs->read_handler_expect = expecting;
1394 * Called to read a chunk of data from the client socket. The data may
1395 * be the raw data, or may need to be further decoded by SASL.
1396 * The data will be read either straight from to the socket, or
1397 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1399 * NB, it is theoretically possible to have 2 layers of encryption,
1400 * both SASL, and this TLS layer. It is highly unlikely in practice
1401 * though, since SASL encryption will typically be a no-op if TLS
1402 * is active
1404 * Returns the number of bytes read, which may be less than
1405 * the requested 'datalen' if the socket would block. Returns
1406 * -1 on error, and disconnects the client socket.
1408 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1410 ssize_t ret;
1411 Error *err = NULL;
1412 ret = qio_channel_read(
1413 vs->ioc, (char *)data, datalen, &err);
1414 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1415 return vnc_client_io_error(vs, ret, &err);
1420 * Called to read data from the client socket to the input buffer,
1421 * when not using any SASL SSF encryption layers. Will read as much
1422 * data as possible without blocking.
1424 * Returns the number of bytes read. Returns -1 on error, and
1425 * disconnects the client socket.
1427 static ssize_t vnc_client_read_plain(VncState *vs)
1429 ssize_t ret;
1430 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1431 vs->input.buffer, vs->input.capacity, vs->input.offset);
1432 buffer_reserve(&vs->input, 4096);
1433 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1434 if (!ret)
1435 return 0;
1436 vs->input.offset += ret;
1437 return ret;
1440 static void vnc_jobs_bh(void *opaque)
1442 VncState *vs = opaque;
1444 vnc_jobs_consume_buffer(vs);
1448 * First function called whenever there is more data to be read from
1449 * the client socket. Will delegate actual work according to whether
1450 * SASL SSF layers are enabled (thus requiring decryption calls)
1451 * Returns 0 on success, -1 if client disconnected
1453 static int vnc_client_read(VncState *vs)
1455 ssize_t ret;
1457 #ifdef CONFIG_VNC_SASL
1458 if (vs->sasl.conn && vs->sasl.runSSF)
1459 ret = vnc_client_read_sasl(vs);
1460 else
1461 #endif /* CONFIG_VNC_SASL */
1462 ret = vnc_client_read_plain(vs);
1463 if (!ret) {
1464 if (vs->disconnecting) {
1465 vnc_disconnect_finish(vs);
1466 return -1;
1468 return 0;
1471 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1472 size_t len = vs->read_handler_expect;
1473 int ret;
1475 ret = vs->read_handler(vs, vs->input.buffer, len);
1476 if (vs->disconnecting) {
1477 vnc_disconnect_finish(vs);
1478 return -1;
1481 if (!ret) {
1482 buffer_advance(&vs->input, len);
1483 } else {
1484 vs->read_handler_expect = ret;
1487 return 0;
1490 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1491 GIOCondition condition, void *opaque)
1493 VncState *vs = opaque;
1494 if (condition & G_IO_IN) {
1495 if (vnc_client_read(vs) < 0) {
1496 return TRUE;
1499 if (condition & G_IO_OUT) {
1500 vnc_client_write(vs);
1502 return TRUE;
1506 void vnc_write(VncState *vs, const void *data, size_t len)
1508 buffer_reserve(&vs->output, len);
1510 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1511 if (vs->ioc_tag) {
1512 g_source_remove(vs->ioc_tag);
1514 vs->ioc_tag = qio_channel_add_watch(
1515 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1518 buffer_append(&vs->output, data, len);
1521 void vnc_write_s32(VncState *vs, int32_t value)
1523 vnc_write_u32(vs, *(uint32_t *)&value);
1526 void vnc_write_u32(VncState *vs, uint32_t value)
1528 uint8_t buf[4];
1530 buf[0] = (value >> 24) & 0xFF;
1531 buf[1] = (value >> 16) & 0xFF;
1532 buf[2] = (value >> 8) & 0xFF;
1533 buf[3] = value & 0xFF;
1535 vnc_write(vs, buf, 4);
1538 void vnc_write_u16(VncState *vs, uint16_t value)
1540 uint8_t buf[2];
1542 buf[0] = (value >> 8) & 0xFF;
1543 buf[1] = value & 0xFF;
1545 vnc_write(vs, buf, 2);
1548 void vnc_write_u8(VncState *vs, uint8_t value)
1550 vnc_write(vs, (char *)&value, 1);
1553 void vnc_flush(VncState *vs)
1555 vnc_lock_output(vs);
1556 if (vs->ioc != NULL && vs->output.offset) {
1557 vnc_client_write_locked(vs);
1559 vnc_unlock_output(vs);
1562 static uint8_t read_u8(uint8_t *data, size_t offset)
1564 return data[offset];
1567 static uint16_t read_u16(uint8_t *data, size_t offset)
1569 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1572 static int32_t read_s32(uint8_t *data, size_t offset)
1574 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1575 (data[offset + 2] << 8) | data[offset + 3]);
1578 uint32_t read_u32(uint8_t *data, size_t offset)
1580 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1581 (data[offset + 2] << 8) | data[offset + 3]);
1584 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1588 static void check_pointer_type_change(Notifier *notifier, void *data)
1590 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1591 int absolute = qemu_input_is_absolute();
1593 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1594 vnc_lock_output(vs);
1595 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1596 vnc_write_u8(vs, 0);
1597 vnc_write_u16(vs, 1);
1598 vnc_framebuffer_update(vs, absolute, 0,
1599 pixman_image_get_width(vs->vd->server),
1600 pixman_image_get_height(vs->vd->server),
1601 VNC_ENCODING_POINTER_TYPE_CHANGE);
1602 vnc_unlock_output(vs);
1603 vnc_flush(vs);
1605 vs->absolute = absolute;
1608 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1610 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1611 [INPUT_BUTTON_LEFT] = 0x01,
1612 [INPUT_BUTTON_MIDDLE] = 0x02,
1613 [INPUT_BUTTON_RIGHT] = 0x04,
1614 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1615 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1617 QemuConsole *con = vs->vd->dcl.con;
1618 int width = pixman_image_get_width(vs->vd->server);
1619 int height = pixman_image_get_height(vs->vd->server);
1621 if (vs->last_bmask != button_mask) {
1622 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1623 vs->last_bmask = button_mask;
1626 if (vs->absolute) {
1627 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1628 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1629 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1630 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1631 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1632 } else {
1633 if (vs->last_x != -1) {
1634 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1635 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1637 vs->last_x = x;
1638 vs->last_y = y;
1640 qemu_input_event_sync();
1643 static void reset_keys(VncState *vs)
1645 int i;
1646 for(i = 0; i < 256; i++) {
1647 if (vs->modifiers_state[i]) {
1648 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1649 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1650 vs->modifiers_state[i] = 0;
1655 static void press_key(VncState *vs, int keysym)
1657 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1658 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1659 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1660 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1661 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1664 static int current_led_state(VncState *vs)
1666 int ledstate = 0;
1668 if (vs->modifiers_state[0x46]) {
1669 ledstate |= QEMU_SCROLL_LOCK_LED;
1671 if (vs->modifiers_state[0x45]) {
1672 ledstate |= QEMU_NUM_LOCK_LED;
1674 if (vs->modifiers_state[0x3a]) {
1675 ledstate |= QEMU_CAPS_LOCK_LED;
1678 return ledstate;
1681 static void vnc_led_state_change(VncState *vs)
1683 int ledstate = 0;
1685 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1686 return;
1689 ledstate = current_led_state(vs);
1690 vnc_lock_output(vs);
1691 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1692 vnc_write_u8(vs, 0);
1693 vnc_write_u16(vs, 1);
1694 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1695 vnc_write_u8(vs, ledstate);
1696 vnc_unlock_output(vs);
1697 vnc_flush(vs);
1700 static void kbd_leds(void *opaque, int ledstate)
1702 VncState *vs = opaque;
1703 int caps, num, scr;
1704 bool has_changed = (ledstate != current_led_state(vs));
1706 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1707 (ledstate & QEMU_NUM_LOCK_LED),
1708 (ledstate & QEMU_SCROLL_LOCK_LED));
1710 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1711 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1712 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1714 if (vs->modifiers_state[0x3a] != caps) {
1715 vs->modifiers_state[0x3a] = caps;
1717 if (vs->modifiers_state[0x45] != num) {
1718 vs->modifiers_state[0x45] = num;
1720 if (vs->modifiers_state[0x46] != scr) {
1721 vs->modifiers_state[0x46] = scr;
1724 /* Sending the current led state message to the client */
1725 if (has_changed) {
1726 vnc_led_state_change(vs);
1730 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1732 /* QEMU console switch */
1733 switch(keycode) {
1734 case 0x2a: /* Left Shift */
1735 case 0x36: /* Right Shift */
1736 case 0x1d: /* Left CTRL */
1737 case 0x9d: /* Right CTRL */
1738 case 0x38: /* Left ALT */
1739 case 0xb8: /* Right ALT */
1740 if (down)
1741 vs->modifiers_state[keycode] = 1;
1742 else
1743 vs->modifiers_state[keycode] = 0;
1744 break;
1745 case 0x02 ... 0x0a: /* '1' to '9' keys */
1746 if (vs->vd->dcl.con == NULL &&
1747 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1748 /* Reset the modifiers sent to the current console */
1749 reset_keys(vs);
1750 console_select(keycode - 0x02);
1751 return;
1753 break;
1754 case 0x3a: /* CapsLock */
1755 case 0x45: /* NumLock */
1756 if (down)
1757 vs->modifiers_state[keycode] ^= 1;
1758 break;
1761 /* Turn off the lock state sync logic if the client support the led
1762 state extension.
1764 if (down && vs->vd->lock_key_sync &&
1765 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1766 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1767 /* If the numlock state needs to change then simulate an additional
1768 keypress before sending this one. This will happen if the user
1769 toggles numlock away from the VNC window.
1771 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1772 if (!vs->modifiers_state[0x45]) {
1773 trace_vnc_key_sync_numlock(true);
1774 vs->modifiers_state[0x45] = 1;
1775 press_key(vs, 0xff7f);
1777 } else {
1778 if (vs->modifiers_state[0x45]) {
1779 trace_vnc_key_sync_numlock(false);
1780 vs->modifiers_state[0x45] = 0;
1781 press_key(vs, 0xff7f);
1786 if (down && vs->vd->lock_key_sync &&
1787 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1788 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1789 /* If the capslock state needs to change then simulate an additional
1790 keypress before sending this one. This will happen if the user
1791 toggles capslock away from the VNC window.
1793 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1794 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1795 int capslock = !!(vs->modifiers_state[0x3a]);
1796 if (capslock) {
1797 if (uppercase == shift) {
1798 trace_vnc_key_sync_capslock(false);
1799 vs->modifiers_state[0x3a] = 0;
1800 press_key(vs, 0xffe5);
1802 } else {
1803 if (uppercase != shift) {
1804 trace_vnc_key_sync_capslock(true);
1805 vs->modifiers_state[0x3a] = 1;
1806 press_key(vs, 0xffe5);
1811 if (qemu_console_is_graphic(NULL)) {
1812 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1813 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1814 } else {
1815 bool numlock = vs->modifiers_state[0x45];
1816 bool control = (vs->modifiers_state[0x1d] ||
1817 vs->modifiers_state[0x9d]);
1818 /* QEMU console emulation */
1819 if (down) {
1820 switch (keycode) {
1821 case 0x2a: /* Left Shift */
1822 case 0x36: /* Right Shift */
1823 case 0x1d: /* Left CTRL */
1824 case 0x9d: /* Right CTRL */
1825 case 0x38: /* Left ALT */
1826 case 0xb8: /* Right ALT */
1827 break;
1828 case 0xc8:
1829 kbd_put_keysym(QEMU_KEY_UP);
1830 break;
1831 case 0xd0:
1832 kbd_put_keysym(QEMU_KEY_DOWN);
1833 break;
1834 case 0xcb:
1835 kbd_put_keysym(QEMU_KEY_LEFT);
1836 break;
1837 case 0xcd:
1838 kbd_put_keysym(QEMU_KEY_RIGHT);
1839 break;
1840 case 0xd3:
1841 kbd_put_keysym(QEMU_KEY_DELETE);
1842 break;
1843 case 0xc7:
1844 kbd_put_keysym(QEMU_KEY_HOME);
1845 break;
1846 case 0xcf:
1847 kbd_put_keysym(QEMU_KEY_END);
1848 break;
1849 case 0xc9:
1850 kbd_put_keysym(QEMU_KEY_PAGEUP);
1851 break;
1852 case 0xd1:
1853 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1854 break;
1856 case 0x47:
1857 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1858 break;
1859 case 0x48:
1860 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1861 break;
1862 case 0x49:
1863 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1864 break;
1865 case 0x4b:
1866 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1867 break;
1868 case 0x4c:
1869 kbd_put_keysym('5');
1870 break;
1871 case 0x4d:
1872 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1873 break;
1874 case 0x4f:
1875 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1876 break;
1877 case 0x50:
1878 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1879 break;
1880 case 0x51:
1881 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1882 break;
1883 case 0x52:
1884 kbd_put_keysym('0');
1885 break;
1886 case 0x53:
1887 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1888 break;
1890 case 0xb5:
1891 kbd_put_keysym('/');
1892 break;
1893 case 0x37:
1894 kbd_put_keysym('*');
1895 break;
1896 case 0x4a:
1897 kbd_put_keysym('-');
1898 break;
1899 case 0x4e:
1900 kbd_put_keysym('+');
1901 break;
1902 case 0x9c:
1903 kbd_put_keysym('\n');
1904 break;
1906 default:
1907 if (control) {
1908 kbd_put_keysym(sym & 0x1f);
1909 } else {
1910 kbd_put_keysym(sym);
1912 break;
1918 static void vnc_release_modifiers(VncState *vs)
1920 static const int keycodes[] = {
1921 /* shift, control, alt keys, both left & right */
1922 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1924 int i, keycode;
1926 if (!qemu_console_is_graphic(NULL)) {
1927 return;
1929 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1930 keycode = keycodes[i];
1931 if (!vs->modifiers_state[keycode]) {
1932 continue;
1934 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1935 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1939 static const char *code2name(int keycode)
1941 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1944 static void key_event(VncState *vs, int down, uint32_t sym)
1946 int keycode;
1947 int lsym = sym;
1949 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1950 lsym = lsym - 'A' + 'a';
1953 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1954 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1955 do_key_event(vs, down, keycode, sym);
1958 static void ext_key_event(VncState *vs, int down,
1959 uint32_t sym, uint16_t keycode)
1961 /* if the user specifies a keyboard layout, always use it */
1962 if (keyboard_layout) {
1963 key_event(vs, down, sym);
1964 } else {
1965 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1966 do_key_event(vs, down, keycode, sym);
1970 static void framebuffer_update_request(VncState *vs, int incremental,
1971 int x, int y, int w, int h)
1973 vs->need_update = 1;
1975 if (incremental) {
1976 return;
1979 vs->force_update = 1;
1980 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1983 static void send_ext_key_event_ack(VncState *vs)
1985 vnc_lock_output(vs);
1986 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1987 vnc_write_u8(vs, 0);
1988 vnc_write_u16(vs, 1);
1989 vnc_framebuffer_update(vs, 0, 0,
1990 pixman_image_get_width(vs->vd->server),
1991 pixman_image_get_height(vs->vd->server),
1992 VNC_ENCODING_EXT_KEY_EVENT);
1993 vnc_unlock_output(vs);
1994 vnc_flush(vs);
1997 static void send_ext_audio_ack(VncState *vs)
1999 vnc_lock_output(vs);
2000 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2001 vnc_write_u8(vs, 0);
2002 vnc_write_u16(vs, 1);
2003 vnc_framebuffer_update(vs, 0, 0,
2004 pixman_image_get_width(vs->vd->server),
2005 pixman_image_get_height(vs->vd->server),
2006 VNC_ENCODING_AUDIO);
2007 vnc_unlock_output(vs);
2008 vnc_flush(vs);
2011 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2013 int i;
2014 unsigned int enc = 0;
2016 vs->features = 0;
2017 vs->vnc_encoding = 0;
2018 vs->tight.compression = 9;
2019 vs->tight.quality = -1; /* Lossless by default */
2020 vs->absolute = -1;
2023 * Start from the end because the encodings are sent in order of preference.
2024 * This way the preferred encoding (first encoding defined in the array)
2025 * will be set at the end of the loop.
2027 for (i = n_encodings - 1; i >= 0; i--) {
2028 enc = encodings[i];
2029 switch (enc) {
2030 case VNC_ENCODING_RAW:
2031 vs->vnc_encoding = enc;
2032 break;
2033 case VNC_ENCODING_COPYRECT:
2034 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2035 break;
2036 case VNC_ENCODING_HEXTILE:
2037 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2038 vs->vnc_encoding = enc;
2039 break;
2040 case VNC_ENCODING_TIGHT:
2041 vs->features |= VNC_FEATURE_TIGHT_MASK;
2042 vs->vnc_encoding = enc;
2043 break;
2044 #ifdef CONFIG_VNC_PNG
2045 case VNC_ENCODING_TIGHT_PNG:
2046 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2047 vs->vnc_encoding = enc;
2048 break;
2049 #endif
2050 case VNC_ENCODING_ZLIB:
2051 vs->features |= VNC_FEATURE_ZLIB_MASK;
2052 vs->vnc_encoding = enc;
2053 break;
2054 case VNC_ENCODING_ZRLE:
2055 vs->features |= VNC_FEATURE_ZRLE_MASK;
2056 vs->vnc_encoding = enc;
2057 break;
2058 case VNC_ENCODING_ZYWRLE:
2059 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2060 vs->vnc_encoding = enc;
2061 break;
2062 case VNC_ENCODING_DESKTOPRESIZE:
2063 vs->features |= VNC_FEATURE_RESIZE_MASK;
2064 break;
2065 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2066 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2067 break;
2068 case VNC_ENCODING_RICH_CURSOR:
2069 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2070 if (vs->vd->cursor) {
2071 vnc_cursor_define(vs);
2073 break;
2074 case VNC_ENCODING_EXT_KEY_EVENT:
2075 send_ext_key_event_ack(vs);
2076 break;
2077 case VNC_ENCODING_AUDIO:
2078 send_ext_audio_ack(vs);
2079 break;
2080 case VNC_ENCODING_WMVi:
2081 vs->features |= VNC_FEATURE_WMVI_MASK;
2082 break;
2083 case VNC_ENCODING_LED_STATE:
2084 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2085 break;
2086 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2087 vs->tight.compression = (enc & 0x0F);
2088 break;
2089 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2090 if (vs->vd->lossy) {
2091 vs->tight.quality = (enc & 0x0F);
2093 break;
2094 default:
2095 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2096 break;
2099 vnc_desktop_resize(vs);
2100 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2101 vnc_led_state_change(vs);
2104 static void set_pixel_conversion(VncState *vs)
2106 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2108 if (fmt == VNC_SERVER_FB_FORMAT) {
2109 vs->write_pixels = vnc_write_pixels_copy;
2110 vnc_hextile_set_pixel_conversion(vs, 0);
2111 } else {
2112 vs->write_pixels = vnc_write_pixels_generic;
2113 vnc_hextile_set_pixel_conversion(vs, 1);
2117 static void send_color_map(VncState *vs)
2119 int i;
2121 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2122 vnc_write_u8(vs, 0); /* padding */
2123 vnc_write_u16(vs, 0); /* first color */
2124 vnc_write_u16(vs, 256); /* # of colors */
2126 for (i = 0; i < 256; i++) {
2127 PixelFormat *pf = &vs->client_pf;
2129 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2130 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2131 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2135 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2136 int big_endian_flag, int true_color_flag,
2137 int red_max, int green_max, int blue_max,
2138 int red_shift, int green_shift, int blue_shift)
2140 if (!true_color_flag) {
2141 /* Expose a reasonable default 256 color map */
2142 bits_per_pixel = 8;
2143 red_max = 7;
2144 green_max = 7;
2145 blue_max = 3;
2146 red_shift = 0;
2147 green_shift = 3;
2148 blue_shift = 6;
2151 switch (bits_per_pixel) {
2152 case 8:
2153 case 16:
2154 case 32:
2155 break;
2156 default:
2157 vnc_client_error(vs);
2158 return;
2161 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2162 vs->client_pf.rbits = hweight_long(red_max);
2163 vs->client_pf.rshift = red_shift;
2164 vs->client_pf.rmask = red_max << red_shift;
2165 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2166 vs->client_pf.gbits = hweight_long(green_max);
2167 vs->client_pf.gshift = green_shift;
2168 vs->client_pf.gmask = green_max << green_shift;
2169 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2170 vs->client_pf.bbits = hweight_long(blue_max);
2171 vs->client_pf.bshift = blue_shift;
2172 vs->client_pf.bmask = blue_max << blue_shift;
2173 vs->client_pf.bits_per_pixel = bits_per_pixel;
2174 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2175 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2176 vs->client_be = big_endian_flag;
2178 if (!true_color_flag) {
2179 send_color_map(vs);
2182 set_pixel_conversion(vs);
2184 graphic_hw_invalidate(vs->vd->dcl.con);
2185 graphic_hw_update(vs->vd->dcl.con);
2188 static void pixel_format_message (VncState *vs) {
2189 char pad[3] = { 0, 0, 0 };
2191 vs->client_pf = qemu_default_pixelformat(32);
2193 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2194 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2196 #ifdef HOST_WORDS_BIGENDIAN
2197 vnc_write_u8(vs, 1); /* big-endian-flag */
2198 #else
2199 vnc_write_u8(vs, 0); /* big-endian-flag */
2200 #endif
2201 vnc_write_u8(vs, 1); /* true-color-flag */
2202 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2203 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2204 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2205 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2206 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2207 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2208 vnc_write(vs, pad, 3); /* padding */
2210 vnc_hextile_set_pixel_conversion(vs, 0);
2211 vs->write_pixels = vnc_write_pixels_copy;
2214 static void vnc_colordepth(VncState *vs)
2216 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2217 /* Sending a WMVi message to notify the client*/
2218 vnc_lock_output(vs);
2219 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2220 vnc_write_u8(vs, 0);
2221 vnc_write_u16(vs, 1); /* number of rects */
2222 vnc_framebuffer_update(vs, 0, 0,
2223 pixman_image_get_width(vs->vd->server),
2224 pixman_image_get_height(vs->vd->server),
2225 VNC_ENCODING_WMVi);
2226 pixel_format_message(vs);
2227 vnc_unlock_output(vs);
2228 vnc_flush(vs);
2229 } else {
2230 set_pixel_conversion(vs);
2234 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2236 int i;
2237 uint16_t limit;
2238 VncDisplay *vd = vs->vd;
2240 if (data[0] > 3) {
2241 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2244 switch (data[0]) {
2245 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2246 if (len == 1)
2247 return 20;
2249 set_pixel_format(vs, read_u8(data, 4),
2250 read_u8(data, 6), read_u8(data, 7),
2251 read_u16(data, 8), read_u16(data, 10),
2252 read_u16(data, 12), read_u8(data, 14),
2253 read_u8(data, 15), read_u8(data, 16));
2254 break;
2255 case VNC_MSG_CLIENT_SET_ENCODINGS:
2256 if (len == 1)
2257 return 4;
2259 if (len == 4) {
2260 limit = read_u16(data, 2);
2261 if (limit > 0)
2262 return 4 + (limit * 4);
2263 } else
2264 limit = read_u16(data, 2);
2266 for (i = 0; i < limit; i++) {
2267 int32_t val = read_s32(data, 4 + (i * 4));
2268 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2271 set_encodings(vs, (int32_t *)(data + 4), limit);
2272 break;
2273 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2274 if (len == 1)
2275 return 10;
2277 framebuffer_update_request(vs,
2278 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2279 read_u16(data, 6), read_u16(data, 8));
2280 break;
2281 case VNC_MSG_CLIENT_KEY_EVENT:
2282 if (len == 1)
2283 return 8;
2285 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2286 break;
2287 case VNC_MSG_CLIENT_POINTER_EVENT:
2288 if (len == 1)
2289 return 6;
2291 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2292 break;
2293 case VNC_MSG_CLIENT_CUT_TEXT:
2294 if (len == 1) {
2295 return 8;
2297 if (len == 8) {
2298 uint32_t dlen = read_u32(data, 4);
2299 if (dlen > (1 << 20)) {
2300 error_report("vnc: client_cut_text msg payload has %u bytes"
2301 " which exceeds our limit of 1MB.", dlen);
2302 vnc_client_error(vs);
2303 break;
2305 if (dlen > 0) {
2306 return 8 + dlen;
2310 client_cut_text(vs, read_u32(data, 4), data + 8);
2311 break;
2312 case VNC_MSG_CLIENT_QEMU:
2313 if (len == 1)
2314 return 2;
2316 switch (read_u8(data, 1)) {
2317 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2318 if (len == 2)
2319 return 12;
2321 ext_key_event(vs, read_u16(data, 2),
2322 read_u32(data, 4), read_u32(data, 8));
2323 break;
2324 case VNC_MSG_CLIENT_QEMU_AUDIO:
2325 if (len == 2)
2326 return 4;
2328 switch (read_u16 (data, 2)) {
2329 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2330 audio_add(vs);
2331 break;
2332 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2333 audio_del(vs);
2334 break;
2335 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2336 if (len == 4)
2337 return 10;
2338 switch (read_u8(data, 4)) {
2339 case 0: vs->as.fmt = AUD_FMT_U8; break;
2340 case 1: vs->as.fmt = AUD_FMT_S8; break;
2341 case 2: vs->as.fmt = AUD_FMT_U16; break;
2342 case 3: vs->as.fmt = AUD_FMT_S16; break;
2343 case 4: vs->as.fmt = AUD_FMT_U32; break;
2344 case 5: vs->as.fmt = AUD_FMT_S32; break;
2345 default:
2346 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2347 vnc_client_error(vs);
2348 break;
2350 vs->as.nchannels = read_u8(data, 5);
2351 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2352 VNC_DEBUG("Invalid audio channel coount %d\n",
2353 read_u8(data, 5));
2354 vnc_client_error(vs);
2355 break;
2357 vs->as.freq = read_u32(data, 6);
2358 break;
2359 default:
2360 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2361 vnc_client_error(vs);
2362 break;
2364 break;
2366 default:
2367 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2368 vnc_client_error(vs);
2369 break;
2371 break;
2372 default:
2373 VNC_DEBUG("Msg: %d\n", data[0]);
2374 vnc_client_error(vs);
2375 break;
2378 vnc_read_when(vs, protocol_client_msg, 1);
2379 return 0;
2382 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2384 char buf[1024];
2385 VncShareMode mode;
2386 int size;
2388 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2389 switch (vs->vd->share_policy) {
2390 case VNC_SHARE_POLICY_IGNORE:
2392 * Ignore the shared flag. Nothing to do here.
2394 * Doesn't conform to the rfb spec but is traditional qemu
2395 * behavior, thus left here as option for compatibility
2396 * reasons.
2398 break;
2399 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2401 * Policy: Allow clients ask for exclusive access.
2403 * Implementation: When a client asks for exclusive access,
2404 * disconnect all others. Shared connects are allowed as long
2405 * as no exclusive connection exists.
2407 * This is how the rfb spec suggests to handle the shared flag.
2409 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2410 VncState *client;
2411 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2412 if (vs == client) {
2413 continue;
2415 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2416 client->share_mode != VNC_SHARE_MODE_SHARED) {
2417 continue;
2419 vnc_disconnect_start(client);
2422 if (mode == VNC_SHARE_MODE_SHARED) {
2423 if (vs->vd->num_exclusive > 0) {
2424 vnc_disconnect_start(vs);
2425 return 0;
2428 break;
2429 case VNC_SHARE_POLICY_FORCE_SHARED:
2431 * Policy: Shared connects only.
2432 * Implementation: Disallow clients asking for exclusive access.
2434 * Useful for shared desktop sessions where you don't want
2435 * someone forgetting to say -shared when running the vnc
2436 * client disconnect everybody else.
2438 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2439 vnc_disconnect_start(vs);
2440 return 0;
2442 break;
2444 vnc_set_share_mode(vs, mode);
2446 if (vs->vd->num_shared > vs->vd->connections_limit) {
2447 vnc_disconnect_start(vs);
2448 return 0;
2451 vs->client_width = pixman_image_get_width(vs->vd->server);
2452 vs->client_height = pixman_image_get_height(vs->vd->server);
2453 vnc_write_u16(vs, vs->client_width);
2454 vnc_write_u16(vs, vs->client_height);
2456 pixel_format_message(vs);
2458 if (qemu_name)
2459 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2460 else
2461 size = snprintf(buf, sizeof(buf), "QEMU");
2463 vnc_write_u32(vs, size);
2464 vnc_write(vs, buf, size);
2465 vnc_flush(vs);
2467 vnc_client_cache_auth(vs);
2468 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2470 vnc_read_when(vs, protocol_client_msg, 1);
2472 return 0;
2475 void start_client_init(VncState *vs)
2477 vnc_read_when(vs, protocol_client_init, 1);
2480 static void make_challenge(VncState *vs)
2482 int i;
2484 srand(time(NULL)+getpid()+getpid()*987654+rand());
2486 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2487 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2490 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2492 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2493 size_t i, pwlen;
2494 unsigned char key[8];
2495 time_t now = time(NULL);
2496 QCryptoCipher *cipher = NULL;
2497 Error *err = NULL;
2499 if (!vs->vd->password) {
2500 VNC_DEBUG("No password configured on server");
2501 goto reject;
2503 if (vs->vd->expires < now) {
2504 VNC_DEBUG("Password is expired");
2505 goto reject;
2508 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2510 /* Calculate the expected challenge response */
2511 pwlen = strlen(vs->vd->password);
2512 for (i=0; i<sizeof(key); i++)
2513 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2515 cipher = qcrypto_cipher_new(
2516 QCRYPTO_CIPHER_ALG_DES_RFB,
2517 QCRYPTO_CIPHER_MODE_ECB,
2518 key, G_N_ELEMENTS(key),
2519 &err);
2520 if (!cipher) {
2521 VNC_DEBUG("Cannot initialize cipher %s",
2522 error_get_pretty(err));
2523 error_free(err);
2524 goto reject;
2527 if (qcrypto_cipher_encrypt(cipher,
2528 vs->challenge,
2529 response,
2530 VNC_AUTH_CHALLENGE_SIZE,
2531 &err) < 0) {
2532 VNC_DEBUG("Cannot encrypt challenge %s",
2533 error_get_pretty(err));
2534 error_free(err);
2535 goto reject;
2538 /* Compare expected vs actual challenge response */
2539 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2540 VNC_DEBUG("Client challenge response did not match\n");
2541 goto reject;
2542 } else {
2543 VNC_DEBUG("Accepting VNC challenge response\n");
2544 vnc_write_u32(vs, 0); /* Accept auth */
2545 vnc_flush(vs);
2547 start_client_init(vs);
2550 qcrypto_cipher_free(cipher);
2551 return 0;
2553 reject:
2554 vnc_write_u32(vs, 1); /* Reject auth */
2555 if (vs->minor >= 8) {
2556 static const char err[] = "Authentication failed";
2557 vnc_write_u32(vs, sizeof(err));
2558 vnc_write(vs, err, sizeof(err));
2560 vnc_flush(vs);
2561 vnc_client_error(vs);
2562 qcrypto_cipher_free(cipher);
2563 return 0;
2566 void start_auth_vnc(VncState *vs)
2568 make_challenge(vs);
2569 /* Send client a 'random' challenge */
2570 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2571 vnc_flush(vs);
2573 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2577 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2579 /* We only advertise 1 auth scheme at a time, so client
2580 * must pick the one we sent. Verify this */
2581 if (data[0] != vs->auth) { /* Reject auth */
2582 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2583 vnc_write_u32(vs, 1);
2584 if (vs->minor >= 8) {
2585 static const char err[] = "Authentication failed";
2586 vnc_write_u32(vs, sizeof(err));
2587 vnc_write(vs, err, sizeof(err));
2589 vnc_client_error(vs);
2590 } else { /* Accept requested auth */
2591 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2592 switch (vs->auth) {
2593 case VNC_AUTH_NONE:
2594 VNC_DEBUG("Accept auth none\n");
2595 if (vs->minor >= 8) {
2596 vnc_write_u32(vs, 0); /* Accept auth completion */
2597 vnc_flush(vs);
2599 start_client_init(vs);
2600 break;
2602 case VNC_AUTH_VNC:
2603 VNC_DEBUG("Start VNC auth\n");
2604 start_auth_vnc(vs);
2605 break;
2607 case VNC_AUTH_VENCRYPT:
2608 VNC_DEBUG("Accept VeNCrypt auth\n");
2609 start_auth_vencrypt(vs);
2610 break;
2612 #ifdef CONFIG_VNC_SASL
2613 case VNC_AUTH_SASL:
2614 VNC_DEBUG("Accept SASL auth\n");
2615 start_auth_sasl(vs);
2616 break;
2617 #endif /* CONFIG_VNC_SASL */
2619 default: /* Should not be possible, but just in case */
2620 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2621 vnc_write_u8(vs, 1);
2622 if (vs->minor >= 8) {
2623 static const char err[] = "Authentication failed";
2624 vnc_write_u32(vs, sizeof(err));
2625 vnc_write(vs, err, sizeof(err));
2627 vnc_client_error(vs);
2630 return 0;
2633 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2635 char local[13];
2637 memcpy(local, version, 12);
2638 local[12] = 0;
2640 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2641 VNC_DEBUG("Malformed protocol version %s\n", local);
2642 vnc_client_error(vs);
2643 return 0;
2645 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2646 if (vs->major != 3 ||
2647 (vs->minor != 3 &&
2648 vs->minor != 4 &&
2649 vs->minor != 5 &&
2650 vs->minor != 7 &&
2651 vs->minor != 8)) {
2652 VNC_DEBUG("Unsupported client version\n");
2653 vnc_write_u32(vs, VNC_AUTH_INVALID);
2654 vnc_flush(vs);
2655 vnc_client_error(vs);
2656 return 0;
2658 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2659 * as equivalent to v3.3 by servers
2661 if (vs->minor == 4 || vs->minor == 5)
2662 vs->minor = 3;
2664 if (vs->minor == 3) {
2665 if (vs->auth == VNC_AUTH_NONE) {
2666 VNC_DEBUG("Tell client auth none\n");
2667 vnc_write_u32(vs, vs->auth);
2668 vnc_flush(vs);
2669 start_client_init(vs);
2670 } else if (vs->auth == VNC_AUTH_VNC) {
2671 VNC_DEBUG("Tell client VNC auth\n");
2672 vnc_write_u32(vs, vs->auth);
2673 vnc_flush(vs);
2674 start_auth_vnc(vs);
2675 } else {
2676 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2677 vnc_write_u32(vs, VNC_AUTH_INVALID);
2678 vnc_flush(vs);
2679 vnc_client_error(vs);
2681 } else {
2682 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2683 vnc_write_u8(vs, 1); /* num auth */
2684 vnc_write_u8(vs, vs->auth);
2685 vnc_read_when(vs, protocol_client_auth, 1);
2686 vnc_flush(vs);
2689 return 0;
2692 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2694 struct VncSurface *vs = &vd->guest;
2696 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2699 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2701 int i, j;
2703 w = (x + w) / VNC_STAT_RECT;
2704 h = (y + h) / VNC_STAT_RECT;
2705 x /= VNC_STAT_RECT;
2706 y /= VNC_STAT_RECT;
2708 for (j = y; j <= h; j++) {
2709 for (i = x; i <= w; i++) {
2710 vs->lossy_rect[j][i] = 1;
2715 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2717 VncState *vs;
2718 int sty = y / VNC_STAT_RECT;
2719 int stx = x / VNC_STAT_RECT;
2720 int has_dirty = 0;
2722 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2723 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2725 QTAILQ_FOREACH(vs, &vd->clients, next) {
2726 int j;
2728 /* kernel send buffers are full -> refresh later */
2729 if (vs->output.offset) {
2730 continue;
2733 if (!vs->lossy_rect[sty][stx]) {
2734 continue;
2737 vs->lossy_rect[sty][stx] = 0;
2738 for (j = 0; j < VNC_STAT_RECT; ++j) {
2739 bitmap_set(vs->dirty[y + j],
2740 x / VNC_DIRTY_PIXELS_PER_BIT,
2741 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2743 has_dirty++;
2746 return has_dirty;
2749 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2751 int width = pixman_image_get_width(vd->guest.fb);
2752 int height = pixman_image_get_height(vd->guest.fb);
2753 int x, y;
2754 struct timeval res;
2755 int has_dirty = 0;
2757 for (y = 0; y < height; y += VNC_STAT_RECT) {
2758 for (x = 0; x < width; x += VNC_STAT_RECT) {
2759 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2761 rect->updated = false;
2765 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2767 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2768 return has_dirty;
2770 vd->guest.last_freq_check = *tv;
2772 for (y = 0; y < height; y += VNC_STAT_RECT) {
2773 for (x = 0; x < width; x += VNC_STAT_RECT) {
2774 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2775 int count = ARRAY_SIZE(rect->times);
2776 struct timeval min, max;
2778 if (!timerisset(&rect->times[count - 1])) {
2779 continue ;
2782 max = rect->times[(rect->idx + count - 1) % count];
2783 qemu_timersub(tv, &max, &res);
2785 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2786 rect->freq = 0;
2787 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2788 memset(rect->times, 0, sizeof (rect->times));
2789 continue ;
2792 min = rect->times[rect->idx];
2793 max = rect->times[(rect->idx + count - 1) % count];
2794 qemu_timersub(&max, &min, &res);
2796 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2797 rect->freq /= count;
2798 rect->freq = 1. / rect->freq;
2801 return has_dirty;
2804 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2806 int i, j;
2807 double total = 0;
2808 int num = 0;
2810 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2811 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2813 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2814 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2815 total += vnc_stat_rect(vs->vd, i, j)->freq;
2816 num++;
2820 if (num) {
2821 return total / num;
2822 } else {
2823 return 0;
2827 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2829 VncRectStat *rect;
2831 rect = vnc_stat_rect(vd, x, y);
2832 if (rect->updated) {
2833 return ;
2835 rect->times[rect->idx] = *tv;
2836 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2837 rect->updated = true;
2840 static int vnc_refresh_server_surface(VncDisplay *vd)
2842 int width = MIN(pixman_image_get_width(vd->guest.fb),
2843 pixman_image_get_width(vd->server));
2844 int height = MIN(pixman_image_get_height(vd->guest.fb),
2845 pixman_image_get_height(vd->server));
2846 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2847 uint8_t *guest_row0 = NULL, *server_row0;
2848 VncState *vs;
2849 int has_dirty = 0;
2850 pixman_image_t *tmpbuf = NULL;
2852 struct timeval tv = { 0, 0 };
2854 if (!vd->non_adaptive) {
2855 gettimeofday(&tv, NULL);
2856 has_dirty = vnc_update_stats(vd, &tv);
2860 * Walk through the guest dirty map.
2861 * Check and copy modified bits from guest to server surface.
2862 * Update server dirty map.
2864 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2865 server_stride = guest_stride = guest_ll =
2866 pixman_image_get_stride(vd->server);
2867 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2868 server_stride);
2869 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2870 int width = pixman_image_get_width(vd->server);
2871 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2872 } else {
2873 int guest_bpp =
2874 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2875 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2876 guest_stride = pixman_image_get_stride(vd->guest.fb);
2877 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2879 line_bytes = MIN(server_stride, guest_ll);
2881 for (;;) {
2882 int x;
2883 uint8_t *guest_ptr, *server_ptr;
2884 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2885 height * VNC_DIRTY_BPL(&vd->guest),
2886 y * VNC_DIRTY_BPL(&vd->guest));
2887 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2888 /* no more dirty bits */
2889 break;
2891 y = offset / VNC_DIRTY_BPL(&vd->guest);
2892 x = offset % VNC_DIRTY_BPL(&vd->guest);
2894 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2896 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2897 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2898 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2899 } else {
2900 guest_ptr = guest_row0 + y * guest_stride;
2902 guest_ptr += x * cmp_bytes;
2904 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2905 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2906 int _cmp_bytes = cmp_bytes;
2907 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2908 continue;
2910 if ((x + 1) * cmp_bytes > line_bytes) {
2911 _cmp_bytes = line_bytes - x * cmp_bytes;
2913 assert(_cmp_bytes >= 0);
2914 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2915 continue;
2917 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2918 if (!vd->non_adaptive) {
2919 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2920 y, &tv);
2922 QTAILQ_FOREACH(vs, &vd->clients, next) {
2923 set_bit(x, vs->dirty[y]);
2925 has_dirty++;
2928 y++;
2930 qemu_pixman_image_unref(tmpbuf);
2931 return has_dirty;
2934 static void vnc_refresh(DisplayChangeListener *dcl)
2936 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2937 VncState *vs, *vn;
2938 int has_dirty, rects = 0;
2940 if (QTAILQ_EMPTY(&vd->clients)) {
2941 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2942 return;
2945 graphic_hw_update(vd->dcl.con);
2947 if (vnc_trylock_display(vd)) {
2948 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2949 return;
2952 has_dirty = vnc_refresh_server_surface(vd);
2953 vnc_unlock_display(vd);
2955 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2956 rects += vnc_update_client(vs, has_dirty, false);
2957 /* vs might be free()ed here */
2960 if (has_dirty && rects) {
2961 vd->dcl.update_interval /= 2;
2962 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2963 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2965 } else {
2966 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2967 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2968 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2973 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2974 bool skipauth, bool websocket)
2976 VncState *vs = g_new0(VncState, 1);
2977 int i;
2979 vs->sioc = sioc;
2980 object_ref(OBJECT(vs->sioc));
2981 vs->ioc = QIO_CHANNEL(sioc);
2982 object_ref(OBJECT(vs->ioc));
2983 vs->vd = vd;
2985 buffer_init(&vs->input, "vnc-input/%p", sioc);
2986 buffer_init(&vs->output, "vnc-output/%p", sioc);
2987 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2989 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2990 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2991 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2992 #ifdef CONFIG_VNC_JPEG
2993 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2994 #endif
2995 #ifdef CONFIG_VNC_PNG
2996 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2997 #endif
2998 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2999 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
3000 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
3001 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
3003 if (skipauth) {
3004 vs->auth = VNC_AUTH_NONE;
3005 vs->subauth = VNC_AUTH_INVALID;
3006 } else {
3007 if (websocket) {
3008 vs->auth = vd->ws_auth;
3009 vs->subauth = VNC_AUTH_INVALID;
3010 } else {
3011 vs->auth = vd->auth;
3012 vs->subauth = vd->subauth;
3015 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3016 sioc, websocket, vs->auth, vs->subauth);
3018 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3019 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3020 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3023 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3024 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3025 qio_channel_set_blocking(vs->ioc, false, NULL);
3026 if (websocket) {
3027 vs->websocket = 1;
3028 if (vd->ws_tls) {
3029 vs->ioc_tag = qio_channel_add_watch(
3030 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3031 } else {
3032 vs->ioc_tag = qio_channel_add_watch(
3033 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
3035 } else {
3036 vs->ioc_tag = qio_channel_add_watch(
3037 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
3040 vnc_client_cache_addr(vs);
3041 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3042 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3044 if (!vs->websocket) {
3045 vnc_init_state(vs);
3048 if (vd->num_connecting > vd->connections_limit) {
3049 QTAILQ_FOREACH(vs, &vd->clients, next) {
3050 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3051 vnc_disconnect_start(vs);
3052 return;
3058 void vnc_init_state(VncState *vs)
3060 vs->initialized = true;
3061 VncDisplay *vd = vs->vd;
3062 bool first_client = QTAILQ_EMPTY(&vd->clients);
3064 vs->last_x = -1;
3065 vs->last_y = -1;
3067 vs->as.freq = 44100;
3068 vs->as.nchannels = 2;
3069 vs->as.fmt = AUD_FMT_S16;
3070 vs->as.endianness = 0;
3072 qemu_mutex_init(&vs->output_mutex);
3073 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3075 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3076 if (first_client) {
3077 vnc_update_server_surface(vd);
3080 graphic_hw_update(vd->dcl.con);
3082 vnc_write(vs, "RFB 003.008\n", 12);
3083 vnc_flush(vs);
3084 vnc_read_when(vs, protocol_version, 12);
3085 reset_keys(vs);
3086 if (vs->vd->lock_key_sync)
3087 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3089 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3090 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3092 /* vs might be free()ed here */
3095 static gboolean vnc_listen_io(QIOChannel *ioc,
3096 GIOCondition condition,
3097 void *opaque)
3099 VncDisplay *vs = opaque;
3100 QIOChannelSocket *sioc = NULL;
3101 Error *err = NULL;
3103 /* Catch-up */
3104 graphic_hw_update(vs->dcl.con);
3105 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3106 if (sioc != NULL) {
3107 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3108 vnc_connect(vs, sioc, false,
3109 ioc != QIO_CHANNEL(vs->lsock));
3110 object_unref(OBJECT(sioc));
3111 } else {
3112 /* client probably closed connection before we got there */
3113 error_free(err);
3116 return TRUE;
3119 static const DisplayChangeListenerOps dcl_ops = {
3120 .dpy_name = "vnc",
3121 .dpy_refresh = vnc_refresh,
3122 .dpy_gfx_copy = vnc_dpy_copy,
3123 .dpy_gfx_update = vnc_dpy_update,
3124 .dpy_gfx_switch = vnc_dpy_switch,
3125 .dpy_gfx_check_format = qemu_pixman_check_format,
3126 .dpy_mouse_set = vnc_mouse_set,
3127 .dpy_cursor_define = vnc_dpy_cursor_define,
3130 void vnc_display_init(const char *id)
3132 VncDisplay *vs;
3134 if (vnc_display_find(id) != NULL) {
3135 return;
3137 vs = g_malloc0(sizeof(*vs));
3139 vs->id = strdup(id);
3140 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3142 QTAILQ_INIT(&vs->clients);
3143 vs->expires = TIME_MAX;
3145 if (keyboard_layout) {
3146 trace_vnc_key_map_init(keyboard_layout);
3147 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3148 } else {
3149 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3152 if (!vs->kbd_layout)
3153 exit(1);
3155 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3156 vs->connections_limit = 32;
3158 qemu_mutex_init(&vs->mutex);
3159 vnc_start_worker_thread();
3161 vs->dcl.ops = &dcl_ops;
3162 register_displaychangelistener(&vs->dcl);
3166 static void vnc_display_close(VncDisplay *vs)
3168 if (!vs)
3169 return;
3170 vs->enabled = false;
3171 vs->is_unix = false;
3172 if (vs->lsock != NULL) {
3173 if (vs->lsock_tag) {
3174 g_source_remove(vs->lsock_tag);
3176 object_unref(OBJECT(vs->lsock));
3177 vs->lsock = NULL;
3179 vs->ws_enabled = false;
3180 if (vs->lwebsock != NULL) {
3181 if (vs->lwebsock_tag) {
3182 g_source_remove(vs->lwebsock_tag);
3184 object_unref(OBJECT(vs->lwebsock));
3185 vs->lwebsock = NULL;
3187 vs->auth = VNC_AUTH_INVALID;
3188 vs->subauth = VNC_AUTH_INVALID;
3189 if (vs->tlscreds) {
3190 object_unparent(OBJECT(vs->tlscreds));
3191 vs->tlscreds = NULL;
3193 g_free(vs->tlsaclname);
3194 vs->tlsaclname = NULL;
3197 int vnc_display_password(const char *id, const char *password)
3199 VncDisplay *vs = vnc_display_find(id);
3201 if (!vs) {
3202 return -EINVAL;
3204 if (vs->auth == VNC_AUTH_NONE) {
3205 error_printf_unless_qmp("If you want use passwords please enable "
3206 "password auth using '-vnc ${dpy},password'.\n");
3207 return -EINVAL;
3210 g_free(vs->password);
3211 vs->password = g_strdup(password);
3213 return 0;
3216 int vnc_display_pw_expire(const char *id, time_t expires)
3218 VncDisplay *vs = vnc_display_find(id);
3220 if (!vs) {
3221 return -EINVAL;
3224 vs->expires = expires;
3225 return 0;
3228 static void vnc_display_print_local_addr(VncDisplay *vs)
3230 SocketAddress *addr;
3231 Error *err = NULL;
3233 addr = qio_channel_socket_get_local_address(vs->lsock, &err);
3234 if (!addr) {
3235 return;
3238 if (addr->type != SOCKET_ADDRESS_KIND_INET) {
3239 qapi_free_SocketAddress(addr);
3240 return;
3242 error_printf_unless_qmp("VNC server running on %s:%s\n",
3243 addr->u.inet.data->host,
3244 addr->u.inet.data->port);
3245 qapi_free_SocketAddress(addr);
3248 static QemuOptsList qemu_vnc_opts = {
3249 .name = "vnc",
3250 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3251 .implied_opt_name = "vnc",
3252 .desc = {
3254 .name = "vnc",
3255 .type = QEMU_OPT_STRING,
3257 .name = "websocket",
3258 .type = QEMU_OPT_STRING,
3260 .name = "tls-creds",
3261 .type = QEMU_OPT_STRING,
3263 /* Deprecated in favour of tls-creds */
3264 .name = "x509",
3265 .type = QEMU_OPT_STRING,
3267 .name = "share",
3268 .type = QEMU_OPT_STRING,
3270 .name = "display",
3271 .type = QEMU_OPT_STRING,
3273 .name = "head",
3274 .type = QEMU_OPT_NUMBER,
3276 .name = "connections",
3277 .type = QEMU_OPT_NUMBER,
3279 .name = "to",
3280 .type = QEMU_OPT_NUMBER,
3282 .name = "ipv4",
3283 .type = QEMU_OPT_BOOL,
3285 .name = "ipv6",
3286 .type = QEMU_OPT_BOOL,
3288 .name = "password",
3289 .type = QEMU_OPT_BOOL,
3291 .name = "reverse",
3292 .type = QEMU_OPT_BOOL,
3294 .name = "lock-key-sync",
3295 .type = QEMU_OPT_BOOL,
3297 .name = "key-delay-ms",
3298 .type = QEMU_OPT_NUMBER,
3300 .name = "sasl",
3301 .type = QEMU_OPT_BOOL,
3303 /* Deprecated in favour of tls-creds */
3304 .name = "tls",
3305 .type = QEMU_OPT_BOOL,
3307 /* Deprecated in favour of tls-creds */
3308 .name = "x509verify",
3309 .type = QEMU_OPT_STRING,
3311 .name = "acl",
3312 .type = QEMU_OPT_BOOL,
3314 .name = "lossy",
3315 .type = QEMU_OPT_BOOL,
3317 .name = "non-adaptive",
3318 .type = QEMU_OPT_BOOL,
3320 { /* end of list */ }
3325 static int
3326 vnc_display_setup_auth(VncDisplay *vs,
3327 bool password,
3328 bool sasl,
3329 bool websocket,
3330 Error **errp)
3333 * We have a choice of 3 authentication options
3335 * 1. none
3336 * 2. vnc
3337 * 3. sasl
3339 * The channel can be run in 2 modes
3341 * 1. clear
3342 * 2. tls
3344 * And TLS can use 2 types of credentials
3346 * 1. anon
3347 * 2. x509
3349 * We thus have 9 possible logical combinations
3351 * 1. clear + none
3352 * 2. clear + vnc
3353 * 3. clear + sasl
3354 * 4. tls + anon + none
3355 * 5. tls + anon + vnc
3356 * 6. tls + anon + sasl
3357 * 7. tls + x509 + none
3358 * 8. tls + x509 + vnc
3359 * 9. tls + x509 + sasl
3361 * These need to be mapped into the VNC auth schemes
3362 * in an appropriate manner. In regular VNC, all the
3363 * TLS options get mapped into VNC_AUTH_VENCRYPT
3364 * sub-auth types.
3366 * In websockets, the https:// protocol already provides
3367 * TLS support, so there is no need to make use of the
3368 * VeNCrypt extension. Furthermore, websockets browser
3369 * clients could not use VeNCrypt even if they wanted to,
3370 * as they cannot control when the TLS handshake takes
3371 * place. Thus there is no option but to rely on https://,
3372 * meaning combinations 4->6 and 7->9 will be mapped to
3373 * VNC auth schemes in the same way as combos 1->3.
3375 * Regardless of fact that we have a different mapping to
3376 * VNC auth mechs for plain VNC vs websockets VNC, the end
3377 * result has the same security characteristics.
3379 if (password) {
3380 if (vs->tlscreds) {
3381 vs->auth = VNC_AUTH_VENCRYPT;
3382 if (websocket) {
3383 vs->ws_tls = true;
3385 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3386 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3387 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3388 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3389 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3390 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3391 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3392 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3393 } else {
3394 error_setg(errp,
3395 "Unsupported TLS cred type %s",
3396 object_get_typename(OBJECT(vs->tlscreds)));
3397 return -1;
3399 } else {
3400 VNC_DEBUG("Initializing VNC server with password auth\n");
3401 vs->auth = VNC_AUTH_VNC;
3402 vs->subauth = VNC_AUTH_INVALID;
3404 if (websocket) {
3405 vs->ws_auth = VNC_AUTH_VNC;
3406 } else {
3407 vs->ws_auth = VNC_AUTH_INVALID;
3409 } else if (sasl) {
3410 if (vs->tlscreds) {
3411 vs->auth = VNC_AUTH_VENCRYPT;
3412 if (websocket) {
3413 vs->ws_tls = true;
3415 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3416 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3417 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3418 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3419 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3420 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3421 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3422 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3423 } else {
3424 error_setg(errp,
3425 "Unsupported TLS cred type %s",
3426 object_get_typename(OBJECT(vs->tlscreds)));
3427 return -1;
3429 } else {
3430 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3431 vs->auth = VNC_AUTH_SASL;
3432 vs->subauth = VNC_AUTH_INVALID;
3434 if (websocket) {
3435 vs->ws_auth = VNC_AUTH_SASL;
3436 } else {
3437 vs->ws_auth = VNC_AUTH_INVALID;
3439 } else {
3440 if (vs->tlscreds) {
3441 vs->auth = VNC_AUTH_VENCRYPT;
3442 if (websocket) {
3443 vs->ws_tls = true;
3445 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3446 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3447 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3448 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3449 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3450 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3451 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3452 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3453 } else {
3454 error_setg(errp,
3455 "Unsupported TLS cred type %s",
3456 object_get_typename(OBJECT(vs->tlscreds)));
3457 return -1;
3459 } else {
3460 VNC_DEBUG("Initializing VNC server with no auth\n");
3461 vs->auth = VNC_AUTH_NONE;
3462 vs->subauth = VNC_AUTH_INVALID;
3464 if (websocket) {
3465 vs->ws_auth = VNC_AUTH_NONE;
3466 } else {
3467 vs->ws_auth = VNC_AUTH_INVALID;
3470 return 0;
3475 * Handle back compat with old CLI syntax by creating some
3476 * suitable QCryptoTLSCreds objects
3478 static QCryptoTLSCreds *
3479 vnc_display_create_creds(bool x509,
3480 bool x509verify,
3481 const char *dir,
3482 const char *id,
3483 Error **errp)
3485 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3486 Object *parent = object_get_objects_root();
3487 Object *creds;
3488 Error *err = NULL;
3490 if (x509) {
3491 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3492 parent,
3493 credsid,
3494 &err,
3495 "endpoint", "server",
3496 "dir", dir,
3497 "verify-peer", x509verify ? "yes" : "no",
3498 NULL);
3499 } else {
3500 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3501 parent,
3502 credsid,
3503 &err,
3504 "endpoint", "server",
3505 NULL);
3508 g_free(credsid);
3510 if (err) {
3511 error_propagate(errp, err);
3512 return NULL;
3515 return QCRYPTO_TLS_CREDS(creds);
3519 void vnc_display_open(const char *id, Error **errp)
3521 VncDisplay *vs = vnc_display_find(id);
3522 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3523 SocketAddress *saddr = NULL, *wsaddr = NULL;
3524 const char *share, *device_id;
3525 QemuConsole *con;
3526 bool password = false;
3527 bool reverse = false;
3528 const char *vnc;
3529 char *h;
3530 const char *credid;
3531 int show_vnc_port = 0;
3532 bool sasl = false;
3533 #ifdef CONFIG_VNC_SASL
3534 int saslErr;
3535 #endif
3536 int acl = 0;
3537 int lock_key_sync = 1;
3538 int key_delay_ms;
3540 if (!vs) {
3541 error_setg(errp, "VNC display not active");
3542 return;
3544 vnc_display_close(vs);
3546 if (!opts) {
3547 return;
3549 vnc = qemu_opt_get(opts, "vnc");
3550 if (!vnc || strcmp(vnc, "none") == 0) {
3551 return;
3554 h = strrchr(vnc, ':');
3555 if (h) {
3556 size_t hlen = h - vnc;
3558 const char *websocket = qemu_opt_get(opts, "websocket");
3559 int to = qemu_opt_get_number(opts, "to", 0);
3560 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3561 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3562 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3563 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3565 saddr = g_new0(SocketAddress, 1);
3566 if (websocket) {
3567 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3568 error_setg(errp,
3569 "SHA1 hash support is required for websockets");
3570 goto fail;
3573 wsaddr = g_new0(SocketAddress, 1);
3574 vs->ws_enabled = true;
3577 if (strncmp(vnc, "unix:", 5) == 0) {
3578 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3579 saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
3580 saddr->u.q_unix.data->path = g_strdup(vnc + 5);
3582 if (vs->ws_enabled) {
3583 error_setg(errp, "UNIX sockets not supported with websock");
3584 goto fail;
3586 } else {
3587 unsigned long long baseport;
3588 InetSocketAddress *inet;
3589 saddr->type = SOCKET_ADDRESS_KIND_INET;
3590 inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
3591 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3592 inet->host = g_strndup(vnc + 1, hlen - 2);
3593 } else {
3594 inet->host = g_strndup(vnc, hlen);
3596 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3597 error_setg(errp, "can't convert to a number: %s", h + 1);
3598 goto fail;
3600 if (baseport > 65535 ||
3601 baseport + 5900 > 65535) {
3602 error_setg(errp, "port %s out of range", h + 1);
3603 goto fail;
3605 inet->port = g_strdup_printf(
3606 "%d", (int)baseport + 5900);
3608 if (to) {
3609 inet->has_to = true;
3610 inet->to = to + 5900;
3611 show_vnc_port = 1;
3613 inet->ipv4 = ipv4;
3614 inet->has_ipv4 = has_ipv4;
3615 inet->ipv6 = ipv6;
3616 inet->has_ipv6 = has_ipv6;
3618 if (vs->ws_enabled) {
3619 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3620 inet = wsaddr->u.inet.data = g_new0(InetSocketAddress, 1);
3621 inet->host = g_strdup(saddr->u.inet.data->host);
3622 inet->port = g_strdup(websocket);
3624 if (to) {
3625 inet->has_to = true;
3626 inet->to = to;
3628 inet->ipv4 = ipv4;
3629 inet->has_ipv4 = has_ipv4;
3630 inet->ipv6 = ipv6;
3631 inet->has_ipv6 = has_ipv6;
3634 } else {
3635 error_setg(errp, "no vnc port specified");
3636 goto fail;
3639 password = qemu_opt_get_bool(opts, "password", false);
3640 if (password) {
3641 if (fips_get_state()) {
3642 error_setg(errp,
3643 "VNC password auth disabled due to FIPS mode, "
3644 "consider using the VeNCrypt or SASL authentication "
3645 "methods as an alternative");
3646 goto fail;
3648 if (!qcrypto_cipher_supports(
3649 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3650 error_setg(errp,
3651 "Cipher backend does not support DES RFB algorithm");
3652 goto fail;
3656 reverse = qemu_opt_get_bool(opts, "reverse", false);
3657 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3658 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
3659 sasl = qemu_opt_get_bool(opts, "sasl", false);
3660 #ifndef CONFIG_VNC_SASL
3661 if (sasl) {
3662 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3663 goto fail;
3665 #endif /* CONFIG_VNC_SASL */
3666 credid = qemu_opt_get(opts, "tls-creds");
3667 if (credid) {
3668 Object *creds;
3669 if (qemu_opt_get(opts, "tls") ||
3670 qemu_opt_get(opts, "x509") ||
3671 qemu_opt_get(opts, "x509verify")) {
3672 error_setg(errp,
3673 "'tls-creds' parameter is mutually exclusive with "
3674 "'tls', 'x509' and 'x509verify' parameters");
3675 goto fail;
3678 creds = object_resolve_path_component(
3679 object_get_objects_root(), credid);
3680 if (!creds) {
3681 error_setg(errp, "No TLS credentials with id '%s'",
3682 credid);
3683 goto fail;
3685 vs->tlscreds = (QCryptoTLSCreds *)
3686 object_dynamic_cast(creds,
3687 TYPE_QCRYPTO_TLS_CREDS);
3688 if (!vs->tlscreds) {
3689 error_setg(errp, "Object with id '%s' is not TLS credentials",
3690 credid);
3691 goto fail;
3693 object_ref(OBJECT(vs->tlscreds));
3695 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3696 error_setg(errp,
3697 "Expecting TLS credentials with a server endpoint");
3698 goto fail;
3700 } else {
3701 const char *path;
3702 bool tls = false, x509 = false, x509verify = false;
3703 tls = qemu_opt_get_bool(opts, "tls", false);
3704 if (tls) {
3705 path = qemu_opt_get(opts, "x509");
3707 if (path) {
3708 x509 = true;
3709 } else {
3710 path = qemu_opt_get(opts, "x509verify");
3711 if (path) {
3712 x509 = true;
3713 x509verify = true;
3716 vs->tlscreds = vnc_display_create_creds(x509,
3717 x509verify,
3718 path,
3719 vs->id,
3720 errp);
3721 if (!vs->tlscreds) {
3722 goto fail;
3726 acl = qemu_opt_get_bool(opts, "acl", false);
3728 share = qemu_opt_get(opts, "share");
3729 if (share) {
3730 if (strcmp(share, "ignore") == 0) {
3731 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3732 } else if (strcmp(share, "allow-exclusive") == 0) {
3733 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3734 } else if (strcmp(share, "force-shared") == 0) {
3735 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3736 } else {
3737 error_setg(errp, "unknown vnc share= option");
3738 goto fail;
3740 } else {
3741 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3743 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3745 #ifdef CONFIG_VNC_JPEG
3746 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3747 #endif
3748 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3749 /* adaptive updates are only used with tight encoding and
3750 * if lossy updates are enabled so we can disable all the
3751 * calculations otherwise */
3752 if (!vs->lossy) {
3753 vs->non_adaptive = true;
3756 if (acl) {
3757 if (strcmp(vs->id, "default") == 0) {
3758 vs->tlsaclname = g_strdup("vnc.x509dname");
3759 } else {
3760 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3762 qemu_acl_init(vs->tlsaclname);
3764 #ifdef CONFIG_VNC_SASL
3765 if (acl && sasl) {
3766 char *aclname;
3768 if (strcmp(vs->id, "default") == 0) {
3769 aclname = g_strdup("vnc.username");
3770 } else {
3771 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3773 vs->sasl.acl = qemu_acl_init(aclname);
3774 g_free(aclname);
3776 #endif
3778 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3779 goto fail;
3782 #ifdef CONFIG_VNC_SASL
3783 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3784 error_setg(errp, "Failed to initialize SASL auth: %s",
3785 sasl_errstring(saslErr, NULL, NULL));
3786 goto fail;
3788 #endif
3789 vs->lock_key_sync = lock_key_sync;
3790 vs->key_delay_ms = key_delay_ms;
3792 device_id = qemu_opt_get(opts, "display");
3793 if (device_id) {
3794 int head = qemu_opt_get_number(opts, "head", 0);
3795 Error *err = NULL;
3797 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3798 if (err) {
3799 error_propagate(errp, err);
3800 goto fail;
3802 } else {
3803 con = NULL;
3806 if (con != vs->dcl.con) {
3807 unregister_displaychangelistener(&vs->dcl);
3808 vs->dcl.con = con;
3809 register_displaychangelistener(&vs->dcl);
3812 if (reverse) {
3813 /* connect to viewer */
3814 QIOChannelSocket *sioc = NULL;
3815 vs->lsock = NULL;
3816 vs->lwebsock = NULL;
3817 if (vs->ws_enabled) {
3818 error_setg(errp, "Cannot use websockets in reverse mode");
3819 goto fail;
3821 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3822 sioc = qio_channel_socket_new();
3823 if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
3824 goto fail;
3826 vnc_connect(vs, sioc, false, false);
3827 object_unref(OBJECT(sioc));
3828 } else {
3829 vs->lsock = qio_channel_socket_new();
3830 if (qio_channel_socket_listen_sync(vs->lsock, saddr, errp) < 0) {
3831 goto fail;
3833 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3834 vs->enabled = true;
3836 if (vs->ws_enabled) {
3837 vs->lwebsock = qio_channel_socket_new();
3838 if (qio_channel_socket_listen_sync(vs->lwebsock,
3839 wsaddr, errp) < 0) {
3840 object_unref(OBJECT(vs->lsock));
3841 vs->lsock = NULL;
3842 goto fail;
3846 vs->lsock_tag = qio_channel_add_watch(
3847 QIO_CHANNEL(vs->lsock),
3848 G_IO_IN, vnc_listen_io, vs, NULL);
3849 if (vs->ws_enabled) {
3850 vs->lwebsock_tag = qio_channel_add_watch(
3851 QIO_CHANNEL(vs->lwebsock),
3852 G_IO_IN, vnc_listen_io, vs, NULL);
3856 if (show_vnc_port) {
3857 vnc_display_print_local_addr(vs);
3860 qapi_free_SocketAddress(saddr);
3861 qapi_free_SocketAddress(wsaddr);
3862 return;
3864 fail:
3865 qapi_free_SocketAddress(saddr);
3866 qapi_free_SocketAddress(wsaddr);
3867 vs->enabled = false;
3868 vs->ws_enabled = false;
3871 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3873 VncDisplay *vs = vnc_display_find(id);
3874 QIOChannelSocket *sioc;
3876 if (!vs) {
3877 return;
3880 sioc = qio_channel_socket_new_fd(csock, NULL);
3881 if (sioc) {
3882 vnc_connect(vs, sioc, skipauth, false);
3883 object_unref(OBJECT(sioc));
3887 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3889 int i = 2;
3890 char *id;
3892 id = g_strdup("default");
3893 while (qemu_opts_find(olist, id)) {
3894 g_free(id);
3895 id = g_strdup_printf("vnc%d", i++);
3897 qemu_opts_set_id(opts, id);
3900 QemuOpts *vnc_parse(const char *str, Error **errp)
3902 QemuOptsList *olist = qemu_find_opts("vnc");
3903 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3904 const char *id;
3906 if (!opts) {
3907 return NULL;
3910 id = qemu_opts_id(opts);
3911 if (!id) {
3912 /* auto-assign id if not present */
3913 vnc_auto_assign_id(olist, opts);
3915 return opts;
3918 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3920 Error *local_err = NULL;
3921 char *id = (char *)qemu_opts_id(opts);
3923 assert(id);
3924 vnc_display_init(id);
3925 vnc_display_open(id, &local_err);
3926 if (local_err != NULL) {
3927 error_reportf_err(local_err, "Failed to start VNC server: ");
3928 exit(1);
3930 return 0;
3933 static void vnc_register_config(void)
3935 qemu_add_opts(&qemu_vnc_opts);
3937 opts_init(vnc_register_config);