Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging
[qemu.git] / ui / vnc.c
blob3ce3a5beec44867f702696b26399bd64a5e0106f
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "vnc.h"
29 #include "vnc-jobs.h"
30 #include "trace.h"
31 #include "hw/qdev.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
36 #include "qemu/acl.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
59 QTAILQ_HEAD_INITIALIZER(vnc_displays);
61 static int vnc_cursor_define(VncState *vs);
62 static void vnc_release_modifiers(VncState *vs);
64 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
66 #ifdef _VNC_DEBUG
67 static const char *mn[] = {
68 [0] = "undefined",
69 [VNC_SHARE_MODE_CONNECTING] = "connecting",
70 [VNC_SHARE_MODE_SHARED] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
74 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
75 vs->ioc, mn[vs->share_mode], mn[mode]);
76 #endif
78 switch (vs->share_mode) {
79 case VNC_SHARE_MODE_CONNECTING:
80 vs->vd->num_connecting--;
81 break;
82 case VNC_SHARE_MODE_SHARED:
83 vs->vd->num_shared--;
84 break;
85 case VNC_SHARE_MODE_EXCLUSIVE:
86 vs->vd->num_exclusive--;
87 break;
88 default:
89 break;
92 vs->share_mode = mode;
94 switch (vs->share_mode) {
95 case VNC_SHARE_MODE_CONNECTING:
96 vs->vd->num_connecting++;
97 break;
98 case VNC_SHARE_MODE_SHARED:
99 vs->vd->num_shared++;
100 break;
101 case VNC_SHARE_MODE_EXCLUSIVE:
102 vs->vd->num_exclusive++;
103 break;
104 default:
105 break;
110 static void vnc_init_basic_info(SocketAddress *addr,
111 VncBasicInfo *info,
112 Error **errp)
114 switch (addr->type) {
115 case SOCKET_ADDRESS_KIND_INET:
116 info->host = g_strdup(addr->u.inet.data->host);
117 info->service = g_strdup(addr->u.inet.data->port);
118 if (addr->u.inet.data->ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_KIND_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.data->path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 default:
132 error_setg(errp, "Unsupported socket kind %d",
133 addr->type);
134 break;
137 return;
140 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
141 VncBasicInfo *info,
142 Error **errp)
144 SocketAddress *addr = NULL;
146 addr = qio_channel_socket_get_local_address(ioc, errp);
147 if (!addr) {
148 return;
151 vnc_init_basic_info(addr, info, errp);
152 qapi_free_SocketAddress(addr);
155 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
156 VncBasicInfo *info,
157 Error **errp)
159 SocketAddress *addr = NULL;
161 addr = qio_channel_socket_get_remote_address(ioc, errp);
162 if (!addr) {
163 return;
166 vnc_init_basic_info(addr, info, errp);
167 qapi_free_SocketAddress(addr);
170 static const char *vnc_auth_name(VncDisplay *vd) {
171 switch (vd->auth) {
172 case VNC_AUTH_INVALID:
173 return "invalid";
174 case VNC_AUTH_NONE:
175 return "none";
176 case VNC_AUTH_VNC:
177 return "vnc";
178 case VNC_AUTH_RA2:
179 return "ra2";
180 case VNC_AUTH_RA2NE:
181 return "ra2ne";
182 case VNC_AUTH_TIGHT:
183 return "tight";
184 case VNC_AUTH_ULTRA:
185 return "ultra";
186 case VNC_AUTH_TLS:
187 return "tls";
188 case VNC_AUTH_VENCRYPT:
189 switch (vd->subauth) {
190 case VNC_AUTH_VENCRYPT_PLAIN:
191 return "vencrypt+plain";
192 case VNC_AUTH_VENCRYPT_TLSNONE:
193 return "vencrypt+tls+none";
194 case VNC_AUTH_VENCRYPT_TLSVNC:
195 return "vencrypt+tls+vnc";
196 case VNC_AUTH_VENCRYPT_TLSPLAIN:
197 return "vencrypt+tls+plain";
198 case VNC_AUTH_VENCRYPT_X509NONE:
199 return "vencrypt+x509+none";
200 case VNC_AUTH_VENCRYPT_X509VNC:
201 return "vencrypt+x509+vnc";
202 case VNC_AUTH_VENCRYPT_X509PLAIN:
203 return "vencrypt+x509+plain";
204 case VNC_AUTH_VENCRYPT_TLSSASL:
205 return "vencrypt+tls+sasl";
206 case VNC_AUTH_VENCRYPT_X509SASL:
207 return "vencrypt+x509+sasl";
208 default:
209 return "vencrypt";
211 case VNC_AUTH_SASL:
212 return "sasl";
214 return "unknown";
217 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
219 VncServerInfo *info;
220 Error *err = NULL;
222 info = g_malloc(sizeof(*info));
223 vnc_init_basic_info_from_server_addr(vd->lsock,
224 qapi_VncServerInfo_base(info), &err);
225 info->has_auth = true;
226 info->auth = g_strdup(vnc_auth_name(vd));
227 if (err) {
228 qapi_free_VncServerInfo(info);
229 info = NULL;
230 error_free(err);
232 return info;
235 static void vnc_client_cache_auth(VncState *client)
237 if (!client->info) {
238 return;
241 if (client->tls) {
242 client->info->x509_dname =
243 qcrypto_tls_session_get_peer_name(client->tls);
244 client->info->has_x509_dname =
245 client->info->x509_dname != NULL;
247 #ifdef CONFIG_VNC_SASL
248 if (client->sasl.conn &&
249 client->sasl.username) {
250 client->info->has_sasl_username = true;
251 client->info->sasl_username = g_strdup(client->sasl.username);
253 #endif
256 static void vnc_client_cache_addr(VncState *client)
258 Error *err = NULL;
260 client->info = g_malloc0(sizeof(*client->info));
261 vnc_init_basic_info_from_remote_addr(client->sioc,
262 qapi_VncClientInfo_base(client->info),
263 &err);
264 if (err) {
265 qapi_free_VncClientInfo(client->info);
266 client->info = NULL;
267 error_free(err);
271 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
273 VncServerInfo *si;
275 if (!vs->info) {
276 return;
279 si = vnc_server_info_get(vs->vd);
280 if (!si) {
281 return;
284 switch (event) {
285 case QAPI_EVENT_VNC_CONNECTED:
286 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
287 &error_abort);
288 break;
289 case QAPI_EVENT_VNC_INITIALIZED:
290 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
291 break;
292 case QAPI_EVENT_VNC_DISCONNECTED:
293 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
294 break;
295 default:
296 break;
299 qapi_free_VncServerInfo(si);
302 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
304 VncClientInfo *info;
305 Error *err = NULL;
307 info = g_malloc0(sizeof(*info));
309 vnc_init_basic_info_from_remote_addr(client->sioc,
310 qapi_VncClientInfo_base(info),
311 &err);
312 if (err) {
313 error_free(err);
314 qapi_free_VncClientInfo(info);
315 return NULL;
318 info->websocket = client->websocket;
320 if (client->tls) {
321 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
322 info->has_x509_dname = info->x509_dname != NULL;
324 #ifdef CONFIG_VNC_SASL
325 if (client->sasl.conn && client->sasl.username) {
326 info->has_sasl_username = true;
327 info->sasl_username = g_strdup(client->sasl.username);
329 #endif
331 return info;
334 static VncDisplay *vnc_display_find(const char *id)
336 VncDisplay *vd;
338 if (id == NULL) {
339 return QTAILQ_FIRST(&vnc_displays);
341 QTAILQ_FOREACH(vd, &vnc_displays, next) {
342 if (strcmp(id, vd->id) == 0) {
343 return vd;
346 return NULL;
349 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
351 VncClientInfoList *cinfo, *prev = NULL;
352 VncState *client;
354 QTAILQ_FOREACH(client, &vd->clients, next) {
355 cinfo = g_new0(VncClientInfoList, 1);
356 cinfo->value = qmp_query_vnc_client(client);
357 cinfo->next = prev;
358 prev = cinfo;
360 return prev;
363 VncInfo *qmp_query_vnc(Error **errp)
365 VncInfo *info = g_malloc0(sizeof(*info));
366 VncDisplay *vd = vnc_display_find(NULL);
367 SocketAddress *addr = NULL;
369 if (vd == NULL || !vd->enabled) {
370 info->enabled = false;
371 } else {
372 info->enabled = true;
374 /* for compatibility with the original command */
375 info->has_clients = true;
376 info->clients = qmp_query_client_list(vd);
378 if (vd->lsock == NULL) {
379 return info;
382 addr = qio_channel_socket_get_local_address(vd->lsock, errp);
383 if (!addr) {
384 goto out_error;
387 switch (addr->type) {
388 case SOCKET_ADDRESS_KIND_INET:
389 info->host = g_strdup(addr->u.inet.data->host);
390 info->service = g_strdup(addr->u.inet.data->port);
391 if (addr->u.inet.data->ipv6) {
392 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
393 } else {
394 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
396 break;
398 case SOCKET_ADDRESS_KIND_UNIX:
399 info->host = g_strdup("");
400 info->service = g_strdup(addr->u.q_unix.data->path);
401 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
402 break;
404 default:
405 error_setg(errp, "Unsupported socket kind %d",
406 addr->type);
407 goto out_error;
410 info->has_host = true;
411 info->has_service = true;
412 info->has_family = true;
414 info->has_auth = true;
415 info->auth = g_strdup(vnc_auth_name(vd));
418 qapi_free_SocketAddress(addr);
419 return info;
421 out_error:
422 qapi_free_SocketAddress(addr);
423 qapi_free_VncInfo(info);
424 return NULL;
427 static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,
428 bool websocket,
429 VncBasicInfoList *prev)
431 VncBasicInfoList *list;
432 VncBasicInfo *info;
433 Error *err = NULL;
434 SocketAddress *addr;
436 addr = qio_channel_socket_get_local_address(ioc, &err);
437 if (!addr) {
438 error_free(err);
439 return prev;
442 info = g_new0(VncBasicInfo, 1);
443 vnc_init_basic_info(addr, info, &err);
444 qapi_free_SocketAddress(addr);
445 if (err) {
446 qapi_free_VncBasicInfo(info);
447 error_free(err);
448 return prev;
450 info->websocket = websocket;
452 list = g_new0(VncBasicInfoList, 1);
453 list->value = info;
454 list->next = prev;
455 return list;
458 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
460 switch (vd->auth) {
461 case VNC_AUTH_VNC:
462 info->auth = VNC_PRIMARY_AUTH_VNC;
463 break;
464 case VNC_AUTH_RA2:
465 info->auth = VNC_PRIMARY_AUTH_RA2;
466 break;
467 case VNC_AUTH_RA2NE:
468 info->auth = VNC_PRIMARY_AUTH_RA2NE;
469 break;
470 case VNC_AUTH_TIGHT:
471 info->auth = VNC_PRIMARY_AUTH_TIGHT;
472 break;
473 case VNC_AUTH_ULTRA:
474 info->auth = VNC_PRIMARY_AUTH_ULTRA;
475 break;
476 case VNC_AUTH_TLS:
477 info->auth = VNC_PRIMARY_AUTH_TLS;
478 break;
479 case VNC_AUTH_VENCRYPT:
480 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
481 info->has_vencrypt = true;
482 switch (vd->subauth) {
483 case VNC_AUTH_VENCRYPT_PLAIN:
484 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
485 break;
486 case VNC_AUTH_VENCRYPT_TLSNONE:
487 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
488 break;
489 case VNC_AUTH_VENCRYPT_TLSVNC:
490 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
491 break;
492 case VNC_AUTH_VENCRYPT_TLSPLAIN:
493 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
494 break;
495 case VNC_AUTH_VENCRYPT_X509NONE:
496 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
497 break;
498 case VNC_AUTH_VENCRYPT_X509VNC:
499 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
500 break;
501 case VNC_AUTH_VENCRYPT_X509PLAIN:
502 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
503 break;
504 case VNC_AUTH_VENCRYPT_TLSSASL:
505 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
506 break;
507 case VNC_AUTH_VENCRYPT_X509SASL:
508 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
509 break;
510 default:
511 info->has_vencrypt = false;
512 break;
514 break;
515 case VNC_AUTH_SASL:
516 info->auth = VNC_PRIMARY_AUTH_SASL;
517 break;
518 case VNC_AUTH_NONE:
519 default:
520 info->auth = VNC_PRIMARY_AUTH_NONE;
521 break;
525 VncInfo2List *qmp_query_vnc_servers(Error **errp)
527 VncInfo2List *item, *prev = NULL;
528 VncInfo2 *info;
529 VncDisplay *vd;
530 DeviceState *dev;
532 QTAILQ_FOREACH(vd, &vnc_displays, next) {
533 info = g_new0(VncInfo2, 1);
534 info->id = g_strdup(vd->id);
535 info->clients = qmp_query_client_list(vd);
536 qmp_query_auth(vd, info);
537 if (vd->dcl.con) {
538 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
539 "device", NULL));
540 info->has_display = true;
541 info->display = g_strdup(dev->id);
543 if (vd->lsock != NULL) {
544 info->server = qmp_query_server_entry(
545 vd->lsock, false, info->server);
547 if (vd->lwebsock != NULL) {
548 info->server = qmp_query_server_entry(
549 vd->lwebsock, true, info->server);
552 item = g_new0(VncInfo2List, 1);
553 item->value = info;
554 item->next = prev;
555 prev = item;
557 return prev;
560 /* TODO
561 1) Get the queue working for IO.
562 2) there is some weirdness when using the -S option (the screen is grey
563 and not totally invalidated
564 3) resolutions > 1024
567 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
568 static void vnc_disconnect_start(VncState *vs);
570 static void vnc_colordepth(VncState *vs);
571 static void framebuffer_update_request(VncState *vs, int incremental,
572 int x_position, int y_position,
573 int w, int h);
574 static void vnc_refresh(DisplayChangeListener *dcl);
575 static int vnc_refresh_server_surface(VncDisplay *vd);
577 static int vnc_width(VncDisplay *vd)
579 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
580 VNC_DIRTY_PIXELS_PER_BIT));
583 static int vnc_height(VncDisplay *vd)
585 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
588 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
589 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
590 VncDisplay *vd,
591 int x, int y, int w, int h)
593 int width = vnc_width(vd);
594 int height = vnc_height(vd);
596 /* this is needed this to ensure we updated all affected
597 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
598 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
599 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
601 x = MIN(x, width);
602 y = MIN(y, height);
603 w = MIN(x + w, width) - x;
604 h = MIN(y + h, height);
606 for (; y < h; y++) {
607 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
608 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
612 static void vnc_dpy_update(DisplayChangeListener *dcl,
613 int x, int y, int w, int h)
615 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
616 struct VncSurface *s = &vd->guest;
618 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
621 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
622 int32_t encoding)
624 vnc_write_u16(vs, x);
625 vnc_write_u16(vs, y);
626 vnc_write_u16(vs, w);
627 vnc_write_u16(vs, h);
629 vnc_write_s32(vs, encoding);
633 static void vnc_desktop_resize(VncState *vs)
635 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
636 return;
638 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
639 vs->client_height == pixman_image_get_height(vs->vd->server)) {
640 return;
642 vs->client_width = pixman_image_get_width(vs->vd->server);
643 vs->client_height = pixman_image_get_height(vs->vd->server);
644 vnc_lock_output(vs);
645 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
646 vnc_write_u8(vs, 0);
647 vnc_write_u16(vs, 1); /* number of rects */
648 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
649 VNC_ENCODING_DESKTOPRESIZE);
650 vnc_unlock_output(vs);
651 vnc_flush(vs);
654 static void vnc_abort_display_jobs(VncDisplay *vd)
656 VncState *vs;
658 QTAILQ_FOREACH(vs, &vd->clients, next) {
659 vnc_lock_output(vs);
660 vs->abort = true;
661 vnc_unlock_output(vs);
663 QTAILQ_FOREACH(vs, &vd->clients, next) {
664 vnc_jobs_join(vs);
666 QTAILQ_FOREACH(vs, &vd->clients, next) {
667 vnc_lock_output(vs);
668 vs->abort = false;
669 vnc_unlock_output(vs);
673 int vnc_server_fb_stride(VncDisplay *vd)
675 return pixman_image_get_stride(vd->server);
678 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
680 uint8_t *ptr;
682 ptr = (uint8_t *)pixman_image_get_data(vd->server);
683 ptr += y * vnc_server_fb_stride(vd);
684 ptr += x * VNC_SERVER_FB_BYTES;
685 return ptr;
688 static void vnc_update_server_surface(VncDisplay *vd)
690 qemu_pixman_image_unref(vd->server);
691 vd->server = NULL;
693 if (QTAILQ_EMPTY(&vd->clients)) {
694 return;
697 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
698 vnc_width(vd),
699 vnc_height(vd),
700 NULL, 0);
703 static void vnc_dpy_switch(DisplayChangeListener *dcl,
704 DisplaySurface *surface)
706 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
707 VncState *vs;
708 int width, height;
710 vnc_abort_display_jobs(vd);
711 vd->ds = surface;
713 /* server surface */
714 vnc_update_server_surface(vd);
716 /* guest surface */
717 qemu_pixman_image_unref(vd->guest.fb);
718 vd->guest.fb = pixman_image_ref(surface->image);
719 vd->guest.format = surface->format;
720 width = vnc_width(vd);
721 height = vnc_height(vd);
722 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
723 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
724 width, height);
726 QTAILQ_FOREACH(vs, &vd->clients, next) {
727 vnc_colordepth(vs);
728 vnc_desktop_resize(vs);
729 if (vs->vd->cursor) {
730 vnc_cursor_define(vs);
732 memset(vs->dirty, 0x00, sizeof(vs->dirty));
733 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
734 width, height);
738 /* fastest code */
739 static void vnc_write_pixels_copy(VncState *vs,
740 void *pixels, int size)
742 vnc_write(vs, pixels, size);
745 /* slowest but generic code. */
746 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
748 uint8_t r, g, b;
750 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
751 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
752 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
753 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
754 #else
755 # error need some bits here if you change VNC_SERVER_FB_FORMAT
756 #endif
757 v = (r << vs->client_pf.rshift) |
758 (g << vs->client_pf.gshift) |
759 (b << vs->client_pf.bshift);
760 switch (vs->client_pf.bytes_per_pixel) {
761 case 1:
762 buf[0] = v;
763 break;
764 case 2:
765 if (vs->client_be) {
766 buf[0] = v >> 8;
767 buf[1] = v;
768 } else {
769 buf[1] = v >> 8;
770 buf[0] = v;
772 break;
773 default:
774 case 4:
775 if (vs->client_be) {
776 buf[0] = v >> 24;
777 buf[1] = v >> 16;
778 buf[2] = v >> 8;
779 buf[3] = v;
780 } else {
781 buf[3] = v >> 24;
782 buf[2] = v >> 16;
783 buf[1] = v >> 8;
784 buf[0] = v;
786 break;
790 static void vnc_write_pixels_generic(VncState *vs,
791 void *pixels1, int size)
793 uint8_t buf[4];
795 if (VNC_SERVER_FB_BYTES == 4) {
796 uint32_t *pixels = pixels1;
797 int n, i;
798 n = size >> 2;
799 for (i = 0; i < n; i++) {
800 vnc_convert_pixel(vs, buf, pixels[i]);
801 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
806 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
808 int i;
809 uint8_t *row;
810 VncDisplay *vd = vs->vd;
812 row = vnc_server_fb_ptr(vd, x, y);
813 for (i = 0; i < h; i++) {
814 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
815 row += vnc_server_fb_stride(vd);
817 return 1;
820 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
822 int n = 0;
823 bool encode_raw = false;
824 size_t saved_offs = vs->output.offset;
826 switch(vs->vnc_encoding) {
827 case VNC_ENCODING_ZLIB:
828 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
829 break;
830 case VNC_ENCODING_HEXTILE:
831 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
832 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
833 break;
834 case VNC_ENCODING_TIGHT:
835 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
836 break;
837 case VNC_ENCODING_TIGHT_PNG:
838 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
839 break;
840 case VNC_ENCODING_ZRLE:
841 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
842 break;
843 case VNC_ENCODING_ZYWRLE:
844 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
845 break;
846 default:
847 encode_raw = true;
848 break;
851 /* If the client has the same pixel format as our internal buffer and
852 * a RAW encoding would need less space fall back to RAW encoding to
853 * save bandwidth and processing power in the client. */
854 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
855 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
856 vs->output.offset = saved_offs;
857 encode_raw = true;
860 if (encode_raw) {
861 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
862 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
865 return n;
868 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
870 /* send bitblit op to the vnc client */
871 vnc_lock_output(vs);
872 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
873 vnc_write_u8(vs, 0);
874 vnc_write_u16(vs, 1); /* number of rects */
875 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
876 vnc_write_u16(vs, src_x);
877 vnc_write_u16(vs, src_y);
878 vnc_unlock_output(vs);
879 vnc_flush(vs);
882 static void vnc_dpy_copy(DisplayChangeListener *dcl,
883 int src_x, int src_y,
884 int dst_x, int dst_y, int w, int h)
886 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
887 VncState *vs, *vn;
888 uint8_t *src_row;
889 uint8_t *dst_row;
890 int i, x, y, pitch, inc, w_lim, s;
891 int cmp_bytes;
893 if (!vd->server) {
894 /* no client connected */
895 return;
898 vnc_refresh_server_surface(vd);
899 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
900 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
901 vs->force_update = 1;
902 vnc_update_client(vs, 1, true);
903 /* vs might be free()ed here */
907 /* do bitblit op on the local surface too */
908 pitch = vnc_server_fb_stride(vd);
909 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
910 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
911 y = dst_y;
912 inc = 1;
913 if (dst_y > src_y) {
914 /* copy backwards */
915 src_row += pitch * (h-1);
916 dst_row += pitch * (h-1);
917 pitch = -pitch;
918 y = dst_y + h - 1;
919 inc = -1;
921 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
922 if (w_lim < 0) {
923 w_lim = w;
924 } else {
925 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
927 for (i = 0; i < h; i++) {
928 for (x = 0; x <= w_lim;
929 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
930 if (x == w_lim) {
931 if ((s = w - w_lim) == 0)
932 break;
933 } else if (!x) {
934 s = (VNC_DIRTY_PIXELS_PER_BIT -
935 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
936 s = MIN(s, w_lim);
937 } else {
938 s = VNC_DIRTY_PIXELS_PER_BIT;
940 cmp_bytes = s * VNC_SERVER_FB_BYTES;
941 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
942 continue;
943 memmove(dst_row, src_row, cmp_bytes);
944 QTAILQ_FOREACH(vs, &vd->clients, next) {
945 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
946 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
947 vs->dirty[y]);
951 src_row += pitch - w * VNC_SERVER_FB_BYTES;
952 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
953 y += inc;
956 QTAILQ_FOREACH(vs, &vd->clients, next) {
957 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
958 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
963 static void vnc_mouse_set(DisplayChangeListener *dcl,
964 int x, int y, int visible)
966 /* can we ask the client(s) to move the pointer ??? */
969 static int vnc_cursor_define(VncState *vs)
971 QEMUCursor *c = vs->vd->cursor;
972 int isize;
974 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
975 vnc_lock_output(vs);
976 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
977 vnc_write_u8(vs, 0); /* padding */
978 vnc_write_u16(vs, 1); /* # of rects */
979 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
980 VNC_ENCODING_RICH_CURSOR);
981 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
982 vnc_write_pixels_generic(vs, c->data, isize);
983 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
984 vnc_unlock_output(vs);
985 return 0;
987 return -1;
990 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
991 QEMUCursor *c)
993 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
994 VncState *vs;
996 cursor_put(vd->cursor);
997 g_free(vd->cursor_mask);
999 vd->cursor = c;
1000 cursor_get(vd->cursor);
1001 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1002 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1003 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1005 QTAILQ_FOREACH(vs, &vd->clients, next) {
1006 vnc_cursor_define(vs);
1010 static int find_and_clear_dirty_height(VncState *vs,
1011 int y, int last_x, int x, int height)
1013 int h;
1015 for (h = 1; h < (height - y); h++) {
1016 if (!test_bit(last_x, vs->dirty[y + h])) {
1017 break;
1019 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1022 return h;
1025 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1027 if (vs->disconnecting) {
1028 vnc_disconnect_finish(vs);
1029 return 0;
1032 vs->has_dirty += has_dirty;
1033 if (vs->need_update && !vs->disconnecting) {
1034 VncDisplay *vd = vs->vd;
1035 VncJob *job;
1036 int y;
1037 int height, width;
1038 int n = 0;
1040 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1041 /* kernel send buffers are full -> drop frames to throttle */
1042 return 0;
1044 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1045 return 0;
1048 * Send screen updates to the vnc client using the server
1049 * surface and server dirty map. guest surface updates
1050 * happening in parallel don't disturb us, the next pass will
1051 * send them to the client.
1053 job = vnc_job_new(vs);
1055 height = pixman_image_get_height(vd->server);
1056 width = pixman_image_get_width(vd->server);
1058 y = 0;
1059 for (;;) {
1060 int x, h;
1061 unsigned long x2;
1062 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1063 height * VNC_DIRTY_BPL(vs),
1064 y * VNC_DIRTY_BPL(vs));
1065 if (offset == height * VNC_DIRTY_BPL(vs)) {
1066 /* no more dirty bits */
1067 break;
1069 y = offset / VNC_DIRTY_BPL(vs);
1070 x = offset % VNC_DIRTY_BPL(vs);
1071 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1072 VNC_DIRTY_BPL(vs), x);
1073 bitmap_clear(vs->dirty[y], x, x2 - x);
1074 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1075 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1076 if (x2 > x) {
1077 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1078 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1080 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1081 y += h;
1082 if (y == height) {
1083 break;
1088 vnc_job_push(job);
1089 if (sync) {
1090 vnc_jobs_join(vs);
1092 vs->force_update = 0;
1093 vs->has_dirty = 0;
1094 return n;
1097 if (vs->disconnecting) {
1098 vnc_disconnect_finish(vs);
1099 } else if (sync) {
1100 vnc_jobs_join(vs);
1103 return 0;
1106 /* audio */
1107 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1109 VncState *vs = opaque;
1111 switch (cmd) {
1112 case AUD_CNOTIFY_DISABLE:
1113 vnc_lock_output(vs);
1114 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1115 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1116 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1117 vnc_unlock_output(vs);
1118 vnc_flush(vs);
1119 break;
1121 case AUD_CNOTIFY_ENABLE:
1122 vnc_lock_output(vs);
1123 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1124 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1125 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1126 vnc_unlock_output(vs);
1127 vnc_flush(vs);
1128 break;
1132 static void audio_capture_destroy(void *opaque)
1136 static void audio_capture(void *opaque, void *buf, int size)
1138 VncState *vs = opaque;
1140 vnc_lock_output(vs);
1141 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1142 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1143 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1144 vnc_write_u32(vs, size);
1145 vnc_write(vs, buf, size);
1146 vnc_unlock_output(vs);
1147 vnc_flush(vs);
1150 static void audio_add(VncState *vs)
1152 struct audio_capture_ops ops;
1154 if (vs->audio_cap) {
1155 error_report("audio already running");
1156 return;
1159 ops.notify = audio_capture_notify;
1160 ops.destroy = audio_capture_destroy;
1161 ops.capture = audio_capture;
1163 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1164 if (!vs->audio_cap) {
1165 error_report("Failed to add audio capture");
1169 static void audio_del(VncState *vs)
1171 if (vs->audio_cap) {
1172 AUD_del_capture(vs->audio_cap, vs);
1173 vs->audio_cap = NULL;
1177 static void vnc_disconnect_start(VncState *vs)
1179 if (vs->disconnecting) {
1180 return;
1182 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1183 if (vs->ioc_tag) {
1184 g_source_remove(vs->ioc_tag);
1186 qio_channel_close(vs->ioc, NULL);
1187 vs->disconnecting = TRUE;
1190 void vnc_disconnect_finish(VncState *vs)
1192 int i;
1194 vnc_jobs_join(vs); /* Wait encoding jobs */
1196 vnc_lock_output(vs);
1197 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1199 buffer_free(&vs->input);
1200 buffer_free(&vs->output);
1202 qapi_free_VncClientInfo(vs->info);
1204 vnc_zlib_clear(vs);
1205 vnc_tight_clear(vs);
1206 vnc_zrle_clear(vs);
1208 #ifdef CONFIG_VNC_SASL
1209 vnc_sasl_client_cleanup(vs);
1210 #endif /* CONFIG_VNC_SASL */
1211 audio_del(vs);
1212 vnc_release_modifiers(vs);
1214 if (vs->initialized) {
1215 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1216 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1217 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1218 /* last client gone */
1219 vnc_update_server_surface(vs->vd);
1223 if (vs->vd->lock_key_sync)
1224 qemu_remove_led_event_handler(vs->led);
1225 vnc_unlock_output(vs);
1227 qemu_mutex_destroy(&vs->output_mutex);
1228 if (vs->bh != NULL) {
1229 qemu_bh_delete(vs->bh);
1231 buffer_free(&vs->jobs_buffer);
1233 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1234 g_free(vs->lossy_rect[i]);
1236 g_free(vs->lossy_rect);
1238 object_unref(OBJECT(vs->ioc));
1239 vs->ioc = NULL;
1240 object_unref(OBJECT(vs->sioc));
1241 vs->sioc = NULL;
1242 g_free(vs);
1245 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1247 if (ret <= 0) {
1248 if (ret == 0) {
1249 VNC_DEBUG("Closing down client sock: EOF\n");
1250 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1251 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1252 ret, errp ? error_get_pretty(*errp) : "Unknown");
1255 vnc_disconnect_start(vs);
1256 if (errp) {
1257 error_free(*errp);
1258 *errp = NULL;
1260 return 0;
1262 return ret;
1266 void vnc_client_error(VncState *vs)
1268 VNC_DEBUG("Closing down client sock: protocol error\n");
1269 vnc_disconnect_start(vs);
1274 * Called to write a chunk of data to the client socket. The data may
1275 * be the raw data, or may have already been encoded by SASL.
1276 * The data will be written either straight onto the socket, or
1277 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1279 * NB, it is theoretically possible to have 2 layers of encryption,
1280 * both SASL, and this TLS layer. It is highly unlikely in practice
1281 * though, since SASL encryption will typically be a no-op if TLS
1282 * is active
1284 * Returns the number of bytes written, which may be less than
1285 * the requested 'datalen' if the socket would block. Returns
1286 * -1 on error, and disconnects the client socket.
1288 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1290 Error *err = NULL;
1291 ssize_t ret;
1292 ret = qio_channel_write(
1293 vs->ioc, (const char *)data, datalen, &err);
1294 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1295 return vnc_client_io_error(vs, ret, &err);
1300 * Called to write buffered data to the client socket, when not
1301 * using any SASL SSF encryption layers. Will write as much data
1302 * as possible without blocking. If all buffered data is written,
1303 * will switch the FD poll() handler back to read monitoring.
1305 * Returns the number of bytes written, which may be less than
1306 * the buffered output data if the socket would block. Returns
1307 * -1 on error, and disconnects the client socket.
1309 static ssize_t vnc_client_write_plain(VncState *vs)
1311 ssize_t ret;
1313 #ifdef CONFIG_VNC_SASL
1314 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1315 vs->output.buffer, vs->output.capacity, vs->output.offset,
1316 vs->sasl.waitWriteSSF);
1318 if (vs->sasl.conn &&
1319 vs->sasl.runSSF &&
1320 vs->sasl.waitWriteSSF) {
1321 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1322 if (ret)
1323 vs->sasl.waitWriteSSF -= ret;
1324 } else
1325 #endif /* CONFIG_VNC_SASL */
1326 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1327 if (!ret)
1328 return 0;
1330 buffer_advance(&vs->output, ret);
1332 if (vs->output.offset == 0) {
1333 if (vs->ioc_tag) {
1334 g_source_remove(vs->ioc_tag);
1336 vs->ioc_tag = qio_channel_add_watch(
1337 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1340 return ret;
1345 * First function called whenever there is data to be written to
1346 * the client socket. Will delegate actual work according to whether
1347 * SASL SSF layers are enabled (thus requiring encryption calls)
1349 static void vnc_client_write_locked(VncState *vs)
1351 #ifdef CONFIG_VNC_SASL
1352 if (vs->sasl.conn &&
1353 vs->sasl.runSSF &&
1354 !vs->sasl.waitWriteSSF) {
1355 vnc_client_write_sasl(vs);
1356 } else
1357 #endif /* CONFIG_VNC_SASL */
1359 vnc_client_write_plain(vs);
1363 static void vnc_client_write(VncState *vs)
1366 vnc_lock_output(vs);
1367 if (vs->output.offset) {
1368 vnc_client_write_locked(vs);
1369 } else if (vs->ioc != NULL) {
1370 if (vs->ioc_tag) {
1371 g_source_remove(vs->ioc_tag);
1373 vs->ioc_tag = qio_channel_add_watch(
1374 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1376 vnc_unlock_output(vs);
1379 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1381 vs->read_handler = func;
1382 vs->read_handler_expect = expecting;
1387 * Called to read a chunk of data from the client socket. The data may
1388 * be the raw data, or may need to be further decoded by SASL.
1389 * The data will be read either straight from to the socket, or
1390 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1392 * NB, it is theoretically possible to have 2 layers of encryption,
1393 * both SASL, and this TLS layer. It is highly unlikely in practice
1394 * though, since SASL encryption will typically be a no-op if TLS
1395 * is active
1397 * Returns the number of bytes read, which may be less than
1398 * the requested 'datalen' if the socket would block. Returns
1399 * -1 on error, and disconnects the client socket.
1401 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1403 ssize_t ret;
1404 Error *err = NULL;
1405 ret = qio_channel_read(
1406 vs->ioc, (char *)data, datalen, &err);
1407 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1408 return vnc_client_io_error(vs, ret, &err);
1413 * Called to read data from the client socket to the input buffer,
1414 * when not using any SASL SSF encryption layers. Will read as much
1415 * data as possible without blocking.
1417 * Returns the number of bytes read. Returns -1 on error, and
1418 * disconnects the client socket.
1420 static ssize_t vnc_client_read_plain(VncState *vs)
1422 ssize_t ret;
1423 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1424 vs->input.buffer, vs->input.capacity, vs->input.offset);
1425 buffer_reserve(&vs->input, 4096);
1426 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1427 if (!ret)
1428 return 0;
1429 vs->input.offset += ret;
1430 return ret;
1433 static void vnc_jobs_bh(void *opaque)
1435 VncState *vs = opaque;
1437 vnc_jobs_consume_buffer(vs);
1441 * First function called whenever there is more data to be read from
1442 * the client socket. Will delegate actual work according to whether
1443 * SASL SSF layers are enabled (thus requiring decryption calls)
1444 * Returns 0 on success, -1 if client disconnected
1446 static int vnc_client_read(VncState *vs)
1448 ssize_t ret;
1450 #ifdef CONFIG_VNC_SASL
1451 if (vs->sasl.conn && vs->sasl.runSSF)
1452 ret = vnc_client_read_sasl(vs);
1453 else
1454 #endif /* CONFIG_VNC_SASL */
1455 ret = vnc_client_read_plain(vs);
1456 if (!ret) {
1457 if (vs->disconnecting) {
1458 vnc_disconnect_finish(vs);
1459 return -1;
1461 return 0;
1464 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1465 size_t len = vs->read_handler_expect;
1466 int ret;
1468 ret = vs->read_handler(vs, vs->input.buffer, len);
1469 if (vs->disconnecting) {
1470 vnc_disconnect_finish(vs);
1471 return -1;
1474 if (!ret) {
1475 buffer_advance(&vs->input, len);
1476 } else {
1477 vs->read_handler_expect = ret;
1480 return 0;
1483 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1484 GIOCondition condition, void *opaque)
1486 VncState *vs = opaque;
1487 if (condition & G_IO_IN) {
1488 if (vnc_client_read(vs) < 0) {
1489 return TRUE;
1492 if (condition & G_IO_OUT) {
1493 vnc_client_write(vs);
1495 return TRUE;
1499 void vnc_write(VncState *vs, const void *data, size_t len)
1501 buffer_reserve(&vs->output, len);
1503 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1504 if (vs->ioc_tag) {
1505 g_source_remove(vs->ioc_tag);
1507 vs->ioc_tag = qio_channel_add_watch(
1508 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1511 buffer_append(&vs->output, data, len);
1514 void vnc_write_s32(VncState *vs, int32_t value)
1516 vnc_write_u32(vs, *(uint32_t *)&value);
1519 void vnc_write_u32(VncState *vs, uint32_t value)
1521 uint8_t buf[4];
1523 buf[0] = (value >> 24) & 0xFF;
1524 buf[1] = (value >> 16) & 0xFF;
1525 buf[2] = (value >> 8) & 0xFF;
1526 buf[3] = value & 0xFF;
1528 vnc_write(vs, buf, 4);
1531 void vnc_write_u16(VncState *vs, uint16_t value)
1533 uint8_t buf[2];
1535 buf[0] = (value >> 8) & 0xFF;
1536 buf[1] = value & 0xFF;
1538 vnc_write(vs, buf, 2);
1541 void vnc_write_u8(VncState *vs, uint8_t value)
1543 vnc_write(vs, (char *)&value, 1);
1546 void vnc_flush(VncState *vs)
1548 vnc_lock_output(vs);
1549 if (vs->ioc != NULL && vs->output.offset) {
1550 vnc_client_write_locked(vs);
1552 vnc_unlock_output(vs);
1555 static uint8_t read_u8(uint8_t *data, size_t offset)
1557 return data[offset];
1560 static uint16_t read_u16(uint8_t *data, size_t offset)
1562 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1565 static int32_t read_s32(uint8_t *data, size_t offset)
1567 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1568 (data[offset + 2] << 8) | data[offset + 3]);
1571 uint32_t read_u32(uint8_t *data, size_t offset)
1573 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1574 (data[offset + 2] << 8) | data[offset + 3]);
1577 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1581 static void check_pointer_type_change(Notifier *notifier, void *data)
1583 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1584 int absolute = qemu_input_is_absolute();
1586 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1587 vnc_lock_output(vs);
1588 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1589 vnc_write_u8(vs, 0);
1590 vnc_write_u16(vs, 1);
1591 vnc_framebuffer_update(vs, absolute, 0,
1592 pixman_image_get_width(vs->vd->server),
1593 pixman_image_get_height(vs->vd->server),
1594 VNC_ENCODING_POINTER_TYPE_CHANGE);
1595 vnc_unlock_output(vs);
1596 vnc_flush(vs);
1598 vs->absolute = absolute;
1601 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1603 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1604 [INPUT_BUTTON_LEFT] = 0x01,
1605 [INPUT_BUTTON_MIDDLE] = 0x02,
1606 [INPUT_BUTTON_RIGHT] = 0x04,
1607 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1608 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1610 QemuConsole *con = vs->vd->dcl.con;
1611 int width = pixman_image_get_width(vs->vd->server);
1612 int height = pixman_image_get_height(vs->vd->server);
1614 if (vs->last_bmask != button_mask) {
1615 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1616 vs->last_bmask = button_mask;
1619 if (vs->absolute) {
1620 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1621 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1622 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1623 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1624 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1625 } else {
1626 if (vs->last_x != -1) {
1627 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1628 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1630 vs->last_x = x;
1631 vs->last_y = y;
1633 qemu_input_event_sync();
1636 static void reset_keys(VncState *vs)
1638 int i;
1639 for(i = 0; i < 256; i++) {
1640 if (vs->modifiers_state[i]) {
1641 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1642 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1643 vs->modifiers_state[i] = 0;
1648 static void press_key(VncState *vs, int keysym)
1650 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1651 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1652 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1653 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1654 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1657 static int current_led_state(VncState *vs)
1659 int ledstate = 0;
1661 if (vs->modifiers_state[0x46]) {
1662 ledstate |= QEMU_SCROLL_LOCK_LED;
1664 if (vs->modifiers_state[0x45]) {
1665 ledstate |= QEMU_NUM_LOCK_LED;
1667 if (vs->modifiers_state[0x3a]) {
1668 ledstate |= QEMU_CAPS_LOCK_LED;
1671 return ledstate;
1674 static void vnc_led_state_change(VncState *vs)
1676 int ledstate = 0;
1678 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1679 return;
1682 ledstate = current_led_state(vs);
1683 vnc_lock_output(vs);
1684 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1685 vnc_write_u8(vs, 0);
1686 vnc_write_u16(vs, 1);
1687 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1688 vnc_write_u8(vs, ledstate);
1689 vnc_unlock_output(vs);
1690 vnc_flush(vs);
1693 static void kbd_leds(void *opaque, int ledstate)
1695 VncState *vs = opaque;
1696 int caps, num, scr;
1697 bool has_changed = (ledstate != current_led_state(vs));
1699 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1700 (ledstate & QEMU_NUM_LOCK_LED),
1701 (ledstate & QEMU_SCROLL_LOCK_LED));
1703 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1704 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1705 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1707 if (vs->modifiers_state[0x3a] != caps) {
1708 vs->modifiers_state[0x3a] = caps;
1710 if (vs->modifiers_state[0x45] != num) {
1711 vs->modifiers_state[0x45] = num;
1713 if (vs->modifiers_state[0x46] != scr) {
1714 vs->modifiers_state[0x46] = scr;
1717 /* Sending the current led state message to the client */
1718 if (has_changed) {
1719 vnc_led_state_change(vs);
1723 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1725 /* QEMU console switch */
1726 switch(keycode) {
1727 case 0x2a: /* Left Shift */
1728 case 0x36: /* Right Shift */
1729 case 0x1d: /* Left CTRL */
1730 case 0x9d: /* Right CTRL */
1731 case 0x38: /* Left ALT */
1732 case 0xb8: /* Right ALT */
1733 if (down)
1734 vs->modifiers_state[keycode] = 1;
1735 else
1736 vs->modifiers_state[keycode] = 0;
1737 break;
1738 case 0x02 ... 0x0a: /* '1' to '9' keys */
1739 if (vs->vd->dcl.con == NULL &&
1740 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1741 /* Reset the modifiers sent to the current console */
1742 reset_keys(vs);
1743 console_select(keycode - 0x02);
1744 return;
1746 break;
1747 case 0x3a: /* CapsLock */
1748 case 0x45: /* NumLock */
1749 if (down)
1750 vs->modifiers_state[keycode] ^= 1;
1751 break;
1754 /* Turn off the lock state sync logic if the client support the led
1755 state extension.
1757 if (down && vs->vd->lock_key_sync &&
1758 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1759 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1760 /* If the numlock state needs to change then simulate an additional
1761 keypress before sending this one. This will happen if the user
1762 toggles numlock away from the VNC window.
1764 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1765 if (!vs->modifiers_state[0x45]) {
1766 trace_vnc_key_sync_numlock(true);
1767 vs->modifiers_state[0x45] = 1;
1768 press_key(vs, 0xff7f);
1770 } else {
1771 if (vs->modifiers_state[0x45]) {
1772 trace_vnc_key_sync_numlock(false);
1773 vs->modifiers_state[0x45] = 0;
1774 press_key(vs, 0xff7f);
1779 if (down && vs->vd->lock_key_sync &&
1780 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1781 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1782 /* If the capslock state needs to change then simulate an additional
1783 keypress before sending this one. This will happen if the user
1784 toggles capslock away from the VNC window.
1786 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1787 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1788 int capslock = !!(vs->modifiers_state[0x3a]);
1789 if (capslock) {
1790 if (uppercase == shift) {
1791 trace_vnc_key_sync_capslock(false);
1792 vs->modifiers_state[0x3a] = 0;
1793 press_key(vs, 0xffe5);
1795 } else {
1796 if (uppercase != shift) {
1797 trace_vnc_key_sync_capslock(true);
1798 vs->modifiers_state[0x3a] = 1;
1799 press_key(vs, 0xffe5);
1804 if (qemu_console_is_graphic(NULL)) {
1805 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1806 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1807 } else {
1808 bool numlock = vs->modifiers_state[0x45];
1809 bool control = (vs->modifiers_state[0x1d] ||
1810 vs->modifiers_state[0x9d]);
1811 /* QEMU console emulation */
1812 if (down) {
1813 switch (keycode) {
1814 case 0x2a: /* Left Shift */
1815 case 0x36: /* Right Shift */
1816 case 0x1d: /* Left CTRL */
1817 case 0x9d: /* Right CTRL */
1818 case 0x38: /* Left ALT */
1819 case 0xb8: /* Right ALT */
1820 break;
1821 case 0xc8:
1822 kbd_put_keysym(QEMU_KEY_UP);
1823 break;
1824 case 0xd0:
1825 kbd_put_keysym(QEMU_KEY_DOWN);
1826 break;
1827 case 0xcb:
1828 kbd_put_keysym(QEMU_KEY_LEFT);
1829 break;
1830 case 0xcd:
1831 kbd_put_keysym(QEMU_KEY_RIGHT);
1832 break;
1833 case 0xd3:
1834 kbd_put_keysym(QEMU_KEY_DELETE);
1835 break;
1836 case 0xc7:
1837 kbd_put_keysym(QEMU_KEY_HOME);
1838 break;
1839 case 0xcf:
1840 kbd_put_keysym(QEMU_KEY_END);
1841 break;
1842 case 0xc9:
1843 kbd_put_keysym(QEMU_KEY_PAGEUP);
1844 break;
1845 case 0xd1:
1846 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1847 break;
1849 case 0x47:
1850 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1851 break;
1852 case 0x48:
1853 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1854 break;
1855 case 0x49:
1856 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1857 break;
1858 case 0x4b:
1859 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1860 break;
1861 case 0x4c:
1862 kbd_put_keysym('5');
1863 break;
1864 case 0x4d:
1865 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1866 break;
1867 case 0x4f:
1868 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1869 break;
1870 case 0x50:
1871 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1872 break;
1873 case 0x51:
1874 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1875 break;
1876 case 0x52:
1877 kbd_put_keysym('0');
1878 break;
1879 case 0x53:
1880 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1881 break;
1883 case 0xb5:
1884 kbd_put_keysym('/');
1885 break;
1886 case 0x37:
1887 kbd_put_keysym('*');
1888 break;
1889 case 0x4a:
1890 kbd_put_keysym('-');
1891 break;
1892 case 0x4e:
1893 kbd_put_keysym('+');
1894 break;
1895 case 0x9c:
1896 kbd_put_keysym('\n');
1897 break;
1899 default:
1900 if (control) {
1901 kbd_put_keysym(sym & 0x1f);
1902 } else {
1903 kbd_put_keysym(sym);
1905 break;
1911 static void vnc_release_modifiers(VncState *vs)
1913 static const int keycodes[] = {
1914 /* shift, control, alt keys, both left & right */
1915 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1917 int i, keycode;
1919 if (!qemu_console_is_graphic(NULL)) {
1920 return;
1922 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1923 keycode = keycodes[i];
1924 if (!vs->modifiers_state[keycode]) {
1925 continue;
1927 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1928 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1932 static const char *code2name(int keycode)
1934 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1937 static void key_event(VncState *vs, int down, uint32_t sym)
1939 int keycode;
1940 int lsym = sym;
1942 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1943 lsym = lsym - 'A' + 'a';
1946 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1947 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1948 do_key_event(vs, down, keycode, sym);
1951 static void ext_key_event(VncState *vs, int down,
1952 uint32_t sym, uint16_t keycode)
1954 /* if the user specifies a keyboard layout, always use it */
1955 if (keyboard_layout) {
1956 key_event(vs, down, sym);
1957 } else {
1958 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1959 do_key_event(vs, down, keycode, sym);
1963 static void framebuffer_update_request(VncState *vs, int incremental,
1964 int x, int y, int w, int h)
1966 vs->need_update = 1;
1968 if (incremental) {
1969 return;
1972 vs->force_update = 1;
1973 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1976 static void send_ext_key_event_ack(VncState *vs)
1978 vnc_lock_output(vs);
1979 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1980 vnc_write_u8(vs, 0);
1981 vnc_write_u16(vs, 1);
1982 vnc_framebuffer_update(vs, 0, 0,
1983 pixman_image_get_width(vs->vd->server),
1984 pixman_image_get_height(vs->vd->server),
1985 VNC_ENCODING_EXT_KEY_EVENT);
1986 vnc_unlock_output(vs);
1987 vnc_flush(vs);
1990 static void send_ext_audio_ack(VncState *vs)
1992 vnc_lock_output(vs);
1993 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1994 vnc_write_u8(vs, 0);
1995 vnc_write_u16(vs, 1);
1996 vnc_framebuffer_update(vs, 0, 0,
1997 pixman_image_get_width(vs->vd->server),
1998 pixman_image_get_height(vs->vd->server),
1999 VNC_ENCODING_AUDIO);
2000 vnc_unlock_output(vs);
2001 vnc_flush(vs);
2004 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2006 int i;
2007 unsigned int enc = 0;
2009 vs->features = 0;
2010 vs->vnc_encoding = 0;
2011 vs->tight.compression = 9;
2012 vs->tight.quality = -1; /* Lossless by default */
2013 vs->absolute = -1;
2016 * Start from the end because the encodings are sent in order of preference.
2017 * This way the preferred encoding (first encoding defined in the array)
2018 * will be set at the end of the loop.
2020 for (i = n_encodings - 1; i >= 0; i--) {
2021 enc = encodings[i];
2022 switch (enc) {
2023 case VNC_ENCODING_RAW:
2024 vs->vnc_encoding = enc;
2025 break;
2026 case VNC_ENCODING_COPYRECT:
2027 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2028 break;
2029 case VNC_ENCODING_HEXTILE:
2030 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2031 vs->vnc_encoding = enc;
2032 break;
2033 case VNC_ENCODING_TIGHT:
2034 vs->features |= VNC_FEATURE_TIGHT_MASK;
2035 vs->vnc_encoding = enc;
2036 break;
2037 #ifdef CONFIG_VNC_PNG
2038 case VNC_ENCODING_TIGHT_PNG:
2039 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2040 vs->vnc_encoding = enc;
2041 break;
2042 #endif
2043 case VNC_ENCODING_ZLIB:
2044 vs->features |= VNC_FEATURE_ZLIB_MASK;
2045 vs->vnc_encoding = enc;
2046 break;
2047 case VNC_ENCODING_ZRLE:
2048 vs->features |= VNC_FEATURE_ZRLE_MASK;
2049 vs->vnc_encoding = enc;
2050 break;
2051 case VNC_ENCODING_ZYWRLE:
2052 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2053 vs->vnc_encoding = enc;
2054 break;
2055 case VNC_ENCODING_DESKTOPRESIZE:
2056 vs->features |= VNC_FEATURE_RESIZE_MASK;
2057 break;
2058 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2059 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2060 break;
2061 case VNC_ENCODING_RICH_CURSOR:
2062 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2063 if (vs->vd->cursor) {
2064 vnc_cursor_define(vs);
2066 break;
2067 case VNC_ENCODING_EXT_KEY_EVENT:
2068 send_ext_key_event_ack(vs);
2069 break;
2070 case VNC_ENCODING_AUDIO:
2071 send_ext_audio_ack(vs);
2072 break;
2073 case VNC_ENCODING_WMVi:
2074 vs->features |= VNC_FEATURE_WMVI_MASK;
2075 break;
2076 case VNC_ENCODING_LED_STATE:
2077 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2078 break;
2079 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2080 vs->tight.compression = (enc & 0x0F);
2081 break;
2082 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2083 if (vs->vd->lossy) {
2084 vs->tight.quality = (enc & 0x0F);
2086 break;
2087 default:
2088 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2089 break;
2092 vnc_desktop_resize(vs);
2093 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2094 vnc_led_state_change(vs);
2097 static void set_pixel_conversion(VncState *vs)
2099 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2101 if (fmt == VNC_SERVER_FB_FORMAT) {
2102 vs->write_pixels = vnc_write_pixels_copy;
2103 vnc_hextile_set_pixel_conversion(vs, 0);
2104 } else {
2105 vs->write_pixels = vnc_write_pixels_generic;
2106 vnc_hextile_set_pixel_conversion(vs, 1);
2110 static void send_color_map(VncState *vs)
2112 int i;
2114 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2115 vnc_write_u8(vs, 0); /* padding */
2116 vnc_write_u16(vs, 0); /* first color */
2117 vnc_write_u16(vs, 256); /* # of colors */
2119 for (i = 0; i < 256; i++) {
2120 PixelFormat *pf = &vs->client_pf;
2122 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2123 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2124 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2128 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2129 int big_endian_flag, int true_color_flag,
2130 int red_max, int green_max, int blue_max,
2131 int red_shift, int green_shift, int blue_shift)
2133 if (!true_color_flag) {
2134 /* Expose a reasonable default 256 color map */
2135 bits_per_pixel = 8;
2136 red_max = 7;
2137 green_max = 7;
2138 blue_max = 3;
2139 red_shift = 0;
2140 green_shift = 3;
2141 blue_shift = 6;
2144 switch (bits_per_pixel) {
2145 case 8:
2146 case 16:
2147 case 32:
2148 break;
2149 default:
2150 vnc_client_error(vs);
2151 return;
2154 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2155 vs->client_pf.rbits = hweight_long(red_max);
2156 vs->client_pf.rshift = red_shift;
2157 vs->client_pf.rmask = red_max << red_shift;
2158 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2159 vs->client_pf.gbits = hweight_long(green_max);
2160 vs->client_pf.gshift = green_shift;
2161 vs->client_pf.gmask = green_max << green_shift;
2162 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2163 vs->client_pf.bbits = hweight_long(blue_max);
2164 vs->client_pf.bshift = blue_shift;
2165 vs->client_pf.bmask = blue_max << blue_shift;
2166 vs->client_pf.bits_per_pixel = bits_per_pixel;
2167 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2168 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2169 vs->client_be = big_endian_flag;
2171 if (!true_color_flag) {
2172 send_color_map(vs);
2175 set_pixel_conversion(vs);
2177 graphic_hw_invalidate(vs->vd->dcl.con);
2178 graphic_hw_update(vs->vd->dcl.con);
2181 static void pixel_format_message (VncState *vs) {
2182 char pad[3] = { 0, 0, 0 };
2184 vs->client_pf = qemu_default_pixelformat(32);
2186 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2187 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2189 #ifdef HOST_WORDS_BIGENDIAN
2190 vnc_write_u8(vs, 1); /* big-endian-flag */
2191 #else
2192 vnc_write_u8(vs, 0); /* big-endian-flag */
2193 #endif
2194 vnc_write_u8(vs, 1); /* true-color-flag */
2195 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2196 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2197 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2198 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2199 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2200 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2201 vnc_write(vs, pad, 3); /* padding */
2203 vnc_hextile_set_pixel_conversion(vs, 0);
2204 vs->write_pixels = vnc_write_pixels_copy;
2207 static void vnc_colordepth(VncState *vs)
2209 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2210 /* Sending a WMVi message to notify the client*/
2211 vnc_lock_output(vs);
2212 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2213 vnc_write_u8(vs, 0);
2214 vnc_write_u16(vs, 1); /* number of rects */
2215 vnc_framebuffer_update(vs, 0, 0,
2216 pixman_image_get_width(vs->vd->server),
2217 pixman_image_get_height(vs->vd->server),
2218 VNC_ENCODING_WMVi);
2219 pixel_format_message(vs);
2220 vnc_unlock_output(vs);
2221 vnc_flush(vs);
2222 } else {
2223 set_pixel_conversion(vs);
2227 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2229 int i;
2230 uint16_t limit;
2231 VncDisplay *vd = vs->vd;
2233 if (data[0] > 3) {
2234 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2237 switch (data[0]) {
2238 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2239 if (len == 1)
2240 return 20;
2242 set_pixel_format(vs, read_u8(data, 4),
2243 read_u8(data, 6), read_u8(data, 7),
2244 read_u16(data, 8), read_u16(data, 10),
2245 read_u16(data, 12), read_u8(data, 14),
2246 read_u8(data, 15), read_u8(data, 16));
2247 break;
2248 case VNC_MSG_CLIENT_SET_ENCODINGS:
2249 if (len == 1)
2250 return 4;
2252 if (len == 4) {
2253 limit = read_u16(data, 2);
2254 if (limit > 0)
2255 return 4 + (limit * 4);
2256 } else
2257 limit = read_u16(data, 2);
2259 for (i = 0; i < limit; i++) {
2260 int32_t val = read_s32(data, 4 + (i * 4));
2261 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2264 set_encodings(vs, (int32_t *)(data + 4), limit);
2265 break;
2266 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2267 if (len == 1)
2268 return 10;
2270 framebuffer_update_request(vs,
2271 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2272 read_u16(data, 6), read_u16(data, 8));
2273 break;
2274 case VNC_MSG_CLIENT_KEY_EVENT:
2275 if (len == 1)
2276 return 8;
2278 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2279 break;
2280 case VNC_MSG_CLIENT_POINTER_EVENT:
2281 if (len == 1)
2282 return 6;
2284 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2285 break;
2286 case VNC_MSG_CLIENT_CUT_TEXT:
2287 if (len == 1) {
2288 return 8;
2290 if (len == 8) {
2291 uint32_t dlen = read_u32(data, 4);
2292 if (dlen > (1 << 20)) {
2293 error_report("vnc: client_cut_text msg payload has %u bytes"
2294 " which exceeds our limit of 1MB.", dlen);
2295 vnc_client_error(vs);
2296 break;
2298 if (dlen > 0) {
2299 return 8 + dlen;
2303 client_cut_text(vs, read_u32(data, 4), data + 8);
2304 break;
2305 case VNC_MSG_CLIENT_QEMU:
2306 if (len == 1)
2307 return 2;
2309 switch (read_u8(data, 1)) {
2310 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2311 if (len == 2)
2312 return 12;
2314 ext_key_event(vs, read_u16(data, 2),
2315 read_u32(data, 4), read_u32(data, 8));
2316 break;
2317 case VNC_MSG_CLIENT_QEMU_AUDIO:
2318 if (len == 2)
2319 return 4;
2321 switch (read_u16 (data, 2)) {
2322 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2323 audio_add(vs);
2324 break;
2325 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2326 audio_del(vs);
2327 break;
2328 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2329 if (len == 4)
2330 return 10;
2331 switch (read_u8(data, 4)) {
2332 case 0: vs->as.fmt = AUD_FMT_U8; break;
2333 case 1: vs->as.fmt = AUD_FMT_S8; break;
2334 case 2: vs->as.fmt = AUD_FMT_U16; break;
2335 case 3: vs->as.fmt = AUD_FMT_S16; break;
2336 case 4: vs->as.fmt = AUD_FMT_U32; break;
2337 case 5: vs->as.fmt = AUD_FMT_S32; break;
2338 default:
2339 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2340 vnc_client_error(vs);
2341 break;
2343 vs->as.nchannels = read_u8(data, 5);
2344 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2345 VNC_DEBUG("Invalid audio channel coount %d\n",
2346 read_u8(data, 5));
2347 vnc_client_error(vs);
2348 break;
2350 vs->as.freq = read_u32(data, 6);
2351 break;
2352 default:
2353 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2354 vnc_client_error(vs);
2355 break;
2357 break;
2359 default:
2360 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2361 vnc_client_error(vs);
2362 break;
2364 break;
2365 default:
2366 VNC_DEBUG("Msg: %d\n", data[0]);
2367 vnc_client_error(vs);
2368 break;
2371 vnc_read_when(vs, protocol_client_msg, 1);
2372 return 0;
2375 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2377 char buf[1024];
2378 VncShareMode mode;
2379 int size;
2381 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2382 switch (vs->vd->share_policy) {
2383 case VNC_SHARE_POLICY_IGNORE:
2385 * Ignore the shared flag. Nothing to do here.
2387 * Doesn't conform to the rfb spec but is traditional qemu
2388 * behavior, thus left here as option for compatibility
2389 * reasons.
2391 break;
2392 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2394 * Policy: Allow clients ask for exclusive access.
2396 * Implementation: When a client asks for exclusive access,
2397 * disconnect all others. Shared connects are allowed as long
2398 * as no exclusive connection exists.
2400 * This is how the rfb spec suggests to handle the shared flag.
2402 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2403 VncState *client;
2404 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2405 if (vs == client) {
2406 continue;
2408 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2409 client->share_mode != VNC_SHARE_MODE_SHARED) {
2410 continue;
2412 vnc_disconnect_start(client);
2415 if (mode == VNC_SHARE_MODE_SHARED) {
2416 if (vs->vd->num_exclusive > 0) {
2417 vnc_disconnect_start(vs);
2418 return 0;
2421 break;
2422 case VNC_SHARE_POLICY_FORCE_SHARED:
2424 * Policy: Shared connects only.
2425 * Implementation: Disallow clients asking for exclusive access.
2427 * Useful for shared desktop sessions where you don't want
2428 * someone forgetting to say -shared when running the vnc
2429 * client disconnect everybody else.
2431 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2432 vnc_disconnect_start(vs);
2433 return 0;
2435 break;
2437 vnc_set_share_mode(vs, mode);
2439 if (vs->vd->num_shared > vs->vd->connections_limit) {
2440 vnc_disconnect_start(vs);
2441 return 0;
2444 vs->client_width = pixman_image_get_width(vs->vd->server);
2445 vs->client_height = pixman_image_get_height(vs->vd->server);
2446 vnc_write_u16(vs, vs->client_width);
2447 vnc_write_u16(vs, vs->client_height);
2449 pixel_format_message(vs);
2451 if (qemu_name)
2452 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2453 else
2454 size = snprintf(buf, sizeof(buf), "QEMU");
2456 vnc_write_u32(vs, size);
2457 vnc_write(vs, buf, size);
2458 vnc_flush(vs);
2460 vnc_client_cache_auth(vs);
2461 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2463 vnc_read_when(vs, protocol_client_msg, 1);
2465 return 0;
2468 void start_client_init(VncState *vs)
2470 vnc_read_when(vs, protocol_client_init, 1);
2473 static void make_challenge(VncState *vs)
2475 int i;
2477 srand(time(NULL)+getpid()+getpid()*987654+rand());
2479 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2480 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2483 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2485 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2486 size_t i, pwlen;
2487 unsigned char key[8];
2488 time_t now = time(NULL);
2489 QCryptoCipher *cipher = NULL;
2490 Error *err = NULL;
2492 if (!vs->vd->password) {
2493 VNC_DEBUG("No password configured on server");
2494 goto reject;
2496 if (vs->vd->expires < now) {
2497 VNC_DEBUG("Password is expired");
2498 goto reject;
2501 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2503 /* Calculate the expected challenge response */
2504 pwlen = strlen(vs->vd->password);
2505 for (i=0; i<sizeof(key); i++)
2506 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2508 cipher = qcrypto_cipher_new(
2509 QCRYPTO_CIPHER_ALG_DES_RFB,
2510 QCRYPTO_CIPHER_MODE_ECB,
2511 key, G_N_ELEMENTS(key),
2512 &err);
2513 if (!cipher) {
2514 VNC_DEBUG("Cannot initialize cipher %s",
2515 error_get_pretty(err));
2516 error_free(err);
2517 goto reject;
2520 if (qcrypto_cipher_encrypt(cipher,
2521 vs->challenge,
2522 response,
2523 VNC_AUTH_CHALLENGE_SIZE,
2524 &err) < 0) {
2525 VNC_DEBUG("Cannot encrypt challenge %s",
2526 error_get_pretty(err));
2527 error_free(err);
2528 goto reject;
2531 /* Compare expected vs actual challenge response */
2532 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2533 VNC_DEBUG("Client challenge response did not match\n");
2534 goto reject;
2535 } else {
2536 VNC_DEBUG("Accepting VNC challenge response\n");
2537 vnc_write_u32(vs, 0); /* Accept auth */
2538 vnc_flush(vs);
2540 start_client_init(vs);
2543 qcrypto_cipher_free(cipher);
2544 return 0;
2546 reject:
2547 vnc_write_u32(vs, 1); /* Reject auth */
2548 if (vs->minor >= 8) {
2549 static const char err[] = "Authentication failed";
2550 vnc_write_u32(vs, sizeof(err));
2551 vnc_write(vs, err, sizeof(err));
2553 vnc_flush(vs);
2554 vnc_client_error(vs);
2555 qcrypto_cipher_free(cipher);
2556 return 0;
2559 void start_auth_vnc(VncState *vs)
2561 make_challenge(vs);
2562 /* Send client a 'random' challenge */
2563 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2564 vnc_flush(vs);
2566 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2570 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2572 /* We only advertise 1 auth scheme at a time, so client
2573 * must pick the one we sent. Verify this */
2574 if (data[0] != vs->auth) { /* Reject auth */
2575 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2576 vnc_write_u32(vs, 1);
2577 if (vs->minor >= 8) {
2578 static const char err[] = "Authentication failed";
2579 vnc_write_u32(vs, sizeof(err));
2580 vnc_write(vs, err, sizeof(err));
2582 vnc_client_error(vs);
2583 } else { /* Accept requested auth */
2584 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2585 switch (vs->auth) {
2586 case VNC_AUTH_NONE:
2587 VNC_DEBUG("Accept auth none\n");
2588 if (vs->minor >= 8) {
2589 vnc_write_u32(vs, 0); /* Accept auth completion */
2590 vnc_flush(vs);
2592 start_client_init(vs);
2593 break;
2595 case VNC_AUTH_VNC:
2596 VNC_DEBUG("Start VNC auth\n");
2597 start_auth_vnc(vs);
2598 break;
2600 case VNC_AUTH_VENCRYPT:
2601 VNC_DEBUG("Accept VeNCrypt auth\n");
2602 start_auth_vencrypt(vs);
2603 break;
2605 #ifdef CONFIG_VNC_SASL
2606 case VNC_AUTH_SASL:
2607 VNC_DEBUG("Accept SASL auth\n");
2608 start_auth_sasl(vs);
2609 break;
2610 #endif /* CONFIG_VNC_SASL */
2612 default: /* Should not be possible, but just in case */
2613 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2614 vnc_write_u8(vs, 1);
2615 if (vs->minor >= 8) {
2616 static const char err[] = "Authentication failed";
2617 vnc_write_u32(vs, sizeof(err));
2618 vnc_write(vs, err, sizeof(err));
2620 vnc_client_error(vs);
2623 return 0;
2626 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2628 char local[13];
2630 memcpy(local, version, 12);
2631 local[12] = 0;
2633 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2634 VNC_DEBUG("Malformed protocol version %s\n", local);
2635 vnc_client_error(vs);
2636 return 0;
2638 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2639 if (vs->major != 3 ||
2640 (vs->minor != 3 &&
2641 vs->minor != 4 &&
2642 vs->minor != 5 &&
2643 vs->minor != 7 &&
2644 vs->minor != 8)) {
2645 VNC_DEBUG("Unsupported client version\n");
2646 vnc_write_u32(vs, VNC_AUTH_INVALID);
2647 vnc_flush(vs);
2648 vnc_client_error(vs);
2649 return 0;
2651 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2652 * as equivalent to v3.3 by servers
2654 if (vs->minor == 4 || vs->minor == 5)
2655 vs->minor = 3;
2657 if (vs->minor == 3) {
2658 if (vs->auth == VNC_AUTH_NONE) {
2659 VNC_DEBUG("Tell client auth none\n");
2660 vnc_write_u32(vs, vs->auth);
2661 vnc_flush(vs);
2662 start_client_init(vs);
2663 } else if (vs->auth == VNC_AUTH_VNC) {
2664 VNC_DEBUG("Tell client VNC auth\n");
2665 vnc_write_u32(vs, vs->auth);
2666 vnc_flush(vs);
2667 start_auth_vnc(vs);
2668 } else {
2669 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2670 vnc_write_u32(vs, VNC_AUTH_INVALID);
2671 vnc_flush(vs);
2672 vnc_client_error(vs);
2674 } else {
2675 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2676 vnc_write_u8(vs, 1); /* num auth */
2677 vnc_write_u8(vs, vs->auth);
2678 vnc_read_when(vs, protocol_client_auth, 1);
2679 vnc_flush(vs);
2682 return 0;
2685 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2687 struct VncSurface *vs = &vd->guest;
2689 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2692 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2694 int i, j;
2696 w = (x + w) / VNC_STAT_RECT;
2697 h = (y + h) / VNC_STAT_RECT;
2698 x /= VNC_STAT_RECT;
2699 y /= VNC_STAT_RECT;
2701 for (j = y; j <= h; j++) {
2702 for (i = x; i <= w; i++) {
2703 vs->lossy_rect[j][i] = 1;
2708 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2710 VncState *vs;
2711 int sty = y / VNC_STAT_RECT;
2712 int stx = x / VNC_STAT_RECT;
2713 int has_dirty = 0;
2715 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2716 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2718 QTAILQ_FOREACH(vs, &vd->clients, next) {
2719 int j;
2721 /* kernel send buffers are full -> refresh later */
2722 if (vs->output.offset) {
2723 continue;
2726 if (!vs->lossy_rect[sty][stx]) {
2727 continue;
2730 vs->lossy_rect[sty][stx] = 0;
2731 for (j = 0; j < VNC_STAT_RECT; ++j) {
2732 bitmap_set(vs->dirty[y + j],
2733 x / VNC_DIRTY_PIXELS_PER_BIT,
2734 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2736 has_dirty++;
2739 return has_dirty;
2742 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2744 int width = pixman_image_get_width(vd->guest.fb);
2745 int height = pixman_image_get_height(vd->guest.fb);
2746 int x, y;
2747 struct timeval res;
2748 int has_dirty = 0;
2750 for (y = 0; y < height; y += VNC_STAT_RECT) {
2751 for (x = 0; x < width; x += VNC_STAT_RECT) {
2752 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2754 rect->updated = false;
2758 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2760 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2761 return has_dirty;
2763 vd->guest.last_freq_check = *tv;
2765 for (y = 0; y < height; y += VNC_STAT_RECT) {
2766 for (x = 0; x < width; x += VNC_STAT_RECT) {
2767 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2768 int count = ARRAY_SIZE(rect->times);
2769 struct timeval min, max;
2771 if (!timerisset(&rect->times[count - 1])) {
2772 continue ;
2775 max = rect->times[(rect->idx + count - 1) % count];
2776 qemu_timersub(tv, &max, &res);
2778 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2779 rect->freq = 0;
2780 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2781 memset(rect->times, 0, sizeof (rect->times));
2782 continue ;
2785 min = rect->times[rect->idx];
2786 max = rect->times[(rect->idx + count - 1) % count];
2787 qemu_timersub(&max, &min, &res);
2789 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2790 rect->freq /= count;
2791 rect->freq = 1. / rect->freq;
2794 return has_dirty;
2797 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2799 int i, j;
2800 double total = 0;
2801 int num = 0;
2803 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2804 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2806 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2807 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2808 total += vnc_stat_rect(vs->vd, i, j)->freq;
2809 num++;
2813 if (num) {
2814 return total / num;
2815 } else {
2816 return 0;
2820 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2822 VncRectStat *rect;
2824 rect = vnc_stat_rect(vd, x, y);
2825 if (rect->updated) {
2826 return ;
2828 rect->times[rect->idx] = *tv;
2829 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2830 rect->updated = true;
2833 static int vnc_refresh_server_surface(VncDisplay *vd)
2835 int width = MIN(pixman_image_get_width(vd->guest.fb),
2836 pixman_image_get_width(vd->server));
2837 int height = MIN(pixman_image_get_height(vd->guest.fb),
2838 pixman_image_get_height(vd->server));
2839 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2840 uint8_t *guest_row0 = NULL, *server_row0;
2841 VncState *vs;
2842 int has_dirty = 0;
2843 pixman_image_t *tmpbuf = NULL;
2845 struct timeval tv = { 0, 0 };
2847 if (!vd->non_adaptive) {
2848 gettimeofday(&tv, NULL);
2849 has_dirty = vnc_update_stats(vd, &tv);
2853 * Walk through the guest dirty map.
2854 * Check and copy modified bits from guest to server surface.
2855 * Update server dirty map.
2857 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2858 server_stride = guest_stride = guest_ll =
2859 pixman_image_get_stride(vd->server);
2860 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2861 server_stride);
2862 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2863 int width = pixman_image_get_width(vd->server);
2864 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2865 } else {
2866 int guest_bpp =
2867 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2868 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2869 guest_stride = pixman_image_get_stride(vd->guest.fb);
2870 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2872 line_bytes = MIN(server_stride, guest_ll);
2874 for (;;) {
2875 int x;
2876 uint8_t *guest_ptr, *server_ptr;
2877 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2878 height * VNC_DIRTY_BPL(&vd->guest),
2879 y * VNC_DIRTY_BPL(&vd->guest));
2880 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2881 /* no more dirty bits */
2882 break;
2884 y = offset / VNC_DIRTY_BPL(&vd->guest);
2885 x = offset % VNC_DIRTY_BPL(&vd->guest);
2887 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2889 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2890 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2891 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2892 } else {
2893 guest_ptr = guest_row0 + y * guest_stride;
2895 guest_ptr += x * cmp_bytes;
2897 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2898 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2899 int _cmp_bytes = cmp_bytes;
2900 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2901 continue;
2903 if ((x + 1) * cmp_bytes > line_bytes) {
2904 _cmp_bytes = line_bytes - x * cmp_bytes;
2906 assert(_cmp_bytes >= 0);
2907 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2908 continue;
2910 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2911 if (!vd->non_adaptive) {
2912 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2913 y, &tv);
2915 QTAILQ_FOREACH(vs, &vd->clients, next) {
2916 set_bit(x, vs->dirty[y]);
2918 has_dirty++;
2921 y++;
2923 qemu_pixman_image_unref(tmpbuf);
2924 return has_dirty;
2927 static void vnc_refresh(DisplayChangeListener *dcl)
2929 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2930 VncState *vs, *vn;
2931 int has_dirty, rects = 0;
2933 if (QTAILQ_EMPTY(&vd->clients)) {
2934 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2935 return;
2938 graphic_hw_update(vd->dcl.con);
2940 if (vnc_trylock_display(vd)) {
2941 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2942 return;
2945 has_dirty = vnc_refresh_server_surface(vd);
2946 vnc_unlock_display(vd);
2948 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2949 rects += vnc_update_client(vs, has_dirty, false);
2950 /* vs might be free()ed here */
2953 if (has_dirty && rects) {
2954 vd->dcl.update_interval /= 2;
2955 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2956 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2958 } else {
2959 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2960 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2961 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2966 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2967 bool skipauth, bool websocket)
2969 VncState *vs = g_new0(VncState, 1);
2970 int i;
2972 vs->sioc = sioc;
2973 object_ref(OBJECT(vs->sioc));
2974 vs->ioc = QIO_CHANNEL(sioc);
2975 object_ref(OBJECT(vs->ioc));
2976 vs->vd = vd;
2978 buffer_init(&vs->input, "vnc-input/%p", sioc);
2979 buffer_init(&vs->output, "vnc-output/%p", sioc);
2980 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2982 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2983 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2984 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2985 #ifdef CONFIG_VNC_JPEG
2986 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2987 #endif
2988 #ifdef CONFIG_VNC_PNG
2989 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2990 #endif
2991 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2992 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2993 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2994 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2996 if (skipauth) {
2997 vs->auth = VNC_AUTH_NONE;
2998 vs->subauth = VNC_AUTH_INVALID;
2999 } else {
3000 if (websocket) {
3001 vs->auth = vd->ws_auth;
3002 vs->subauth = VNC_AUTH_INVALID;
3003 } else {
3004 vs->auth = vd->auth;
3005 vs->subauth = vd->subauth;
3008 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3009 sioc, websocket, vs->auth, vs->subauth);
3011 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3012 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3013 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3016 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3017 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3018 qio_channel_set_blocking(vs->ioc, false, NULL);
3019 if (websocket) {
3020 vs->websocket = 1;
3021 if (vd->ws_tls) {
3022 vs->ioc_tag = qio_channel_add_watch(
3023 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3024 } else {
3025 vs->ioc_tag = qio_channel_add_watch(
3026 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
3028 } else {
3029 vs->ioc_tag = qio_channel_add_watch(
3030 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
3033 vnc_client_cache_addr(vs);
3034 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3035 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3037 if (!vs->websocket) {
3038 vnc_init_state(vs);
3041 if (vd->num_connecting > vd->connections_limit) {
3042 QTAILQ_FOREACH(vs, &vd->clients, next) {
3043 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3044 vnc_disconnect_start(vs);
3045 return;
3051 void vnc_init_state(VncState *vs)
3053 vs->initialized = true;
3054 VncDisplay *vd = vs->vd;
3055 bool first_client = QTAILQ_EMPTY(&vd->clients);
3057 vs->last_x = -1;
3058 vs->last_y = -1;
3060 vs->as.freq = 44100;
3061 vs->as.nchannels = 2;
3062 vs->as.fmt = AUD_FMT_S16;
3063 vs->as.endianness = 0;
3065 qemu_mutex_init(&vs->output_mutex);
3066 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3068 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3069 if (first_client) {
3070 vnc_update_server_surface(vd);
3073 graphic_hw_update(vd->dcl.con);
3075 vnc_write(vs, "RFB 003.008\n", 12);
3076 vnc_flush(vs);
3077 vnc_read_when(vs, protocol_version, 12);
3078 reset_keys(vs);
3079 if (vs->vd->lock_key_sync)
3080 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3082 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3083 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3085 /* vs might be free()ed here */
3088 static gboolean vnc_listen_io(QIOChannel *ioc,
3089 GIOCondition condition,
3090 void *opaque)
3092 VncDisplay *vs = opaque;
3093 QIOChannelSocket *sioc = NULL;
3094 Error *err = NULL;
3096 /* Catch-up */
3097 graphic_hw_update(vs->dcl.con);
3098 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3099 if (sioc != NULL) {
3100 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3101 vnc_connect(vs, sioc, false,
3102 ioc != QIO_CHANNEL(vs->lsock));
3103 object_unref(OBJECT(sioc));
3104 } else {
3105 /* client probably closed connection before we got there */
3106 error_free(err);
3109 return TRUE;
3112 static const DisplayChangeListenerOps dcl_ops = {
3113 .dpy_name = "vnc",
3114 .dpy_refresh = vnc_refresh,
3115 .dpy_gfx_copy = vnc_dpy_copy,
3116 .dpy_gfx_update = vnc_dpy_update,
3117 .dpy_gfx_switch = vnc_dpy_switch,
3118 .dpy_gfx_check_format = qemu_pixman_check_format,
3119 .dpy_mouse_set = vnc_mouse_set,
3120 .dpy_cursor_define = vnc_dpy_cursor_define,
3123 void vnc_display_init(const char *id)
3125 VncDisplay *vs;
3127 if (vnc_display_find(id) != NULL) {
3128 return;
3130 vs = g_malloc0(sizeof(*vs));
3132 vs->id = strdup(id);
3133 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3135 QTAILQ_INIT(&vs->clients);
3136 vs->expires = TIME_MAX;
3138 if (keyboard_layout) {
3139 trace_vnc_key_map_init(keyboard_layout);
3140 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3141 } else {
3142 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3145 if (!vs->kbd_layout)
3146 exit(1);
3148 qemu_mutex_init(&vs->mutex);
3149 vnc_start_worker_thread();
3151 vs->dcl.ops = &dcl_ops;
3152 register_displaychangelistener(&vs->dcl);
3156 static void vnc_display_close(VncDisplay *vs)
3158 if (!vs)
3159 return;
3160 vs->enabled = false;
3161 vs->is_unix = false;
3162 if (vs->lsock != NULL) {
3163 if (vs->lsock_tag) {
3164 g_source_remove(vs->lsock_tag);
3166 object_unref(OBJECT(vs->lsock));
3167 vs->lsock = NULL;
3169 vs->ws_enabled = false;
3170 if (vs->lwebsock != NULL) {
3171 if (vs->lwebsock_tag) {
3172 g_source_remove(vs->lwebsock_tag);
3174 object_unref(OBJECT(vs->lwebsock));
3175 vs->lwebsock = NULL;
3177 vs->auth = VNC_AUTH_INVALID;
3178 vs->subauth = VNC_AUTH_INVALID;
3179 if (vs->tlscreds) {
3180 object_unparent(OBJECT(vs->tlscreds));
3181 vs->tlscreds = NULL;
3183 g_free(vs->tlsaclname);
3184 vs->tlsaclname = NULL;
3187 int vnc_display_password(const char *id, const char *password)
3189 VncDisplay *vs = vnc_display_find(id);
3191 if (!vs) {
3192 return -EINVAL;
3194 if (vs->auth == VNC_AUTH_NONE) {
3195 error_printf_unless_qmp("If you want use passwords please enable "
3196 "password auth using '-vnc ${dpy},password'.");
3197 return -EINVAL;
3200 g_free(vs->password);
3201 vs->password = g_strdup(password);
3203 return 0;
3206 int vnc_display_pw_expire(const char *id, time_t expires)
3208 VncDisplay *vs = vnc_display_find(id);
3210 if (!vs) {
3211 return -EINVAL;
3214 vs->expires = expires;
3215 return 0;
3218 static void vnc_display_print_local_addr(VncDisplay *vs)
3220 SocketAddress *addr;
3221 Error *err = NULL;
3223 addr = qio_channel_socket_get_local_address(vs->lsock, &err);
3224 if (!addr) {
3225 return;
3228 if (addr->type != SOCKET_ADDRESS_KIND_INET) {
3229 qapi_free_SocketAddress(addr);
3230 return;
3232 error_printf_unless_qmp("VNC server running on %s:%s\n",
3233 addr->u.inet.data->host,
3234 addr->u.inet.data->port);
3235 qapi_free_SocketAddress(addr);
3238 static QemuOptsList qemu_vnc_opts = {
3239 .name = "vnc",
3240 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3241 .implied_opt_name = "vnc",
3242 .desc = {
3244 .name = "vnc",
3245 .type = QEMU_OPT_STRING,
3247 .name = "websocket",
3248 .type = QEMU_OPT_STRING,
3250 .name = "tls-creds",
3251 .type = QEMU_OPT_STRING,
3253 /* Deprecated in favour of tls-creds */
3254 .name = "x509",
3255 .type = QEMU_OPT_STRING,
3257 .name = "share",
3258 .type = QEMU_OPT_STRING,
3260 .name = "display",
3261 .type = QEMU_OPT_STRING,
3263 .name = "head",
3264 .type = QEMU_OPT_NUMBER,
3266 .name = "connections",
3267 .type = QEMU_OPT_NUMBER,
3269 .name = "to",
3270 .type = QEMU_OPT_NUMBER,
3272 .name = "ipv4",
3273 .type = QEMU_OPT_BOOL,
3275 .name = "ipv6",
3276 .type = QEMU_OPT_BOOL,
3278 .name = "password",
3279 .type = QEMU_OPT_BOOL,
3281 .name = "reverse",
3282 .type = QEMU_OPT_BOOL,
3284 .name = "lock-key-sync",
3285 .type = QEMU_OPT_BOOL,
3287 .name = "key-delay-ms",
3288 .type = QEMU_OPT_NUMBER,
3290 .name = "sasl",
3291 .type = QEMU_OPT_BOOL,
3293 /* Deprecated in favour of tls-creds */
3294 .name = "tls",
3295 .type = QEMU_OPT_BOOL,
3297 /* Deprecated in favour of tls-creds */
3298 .name = "x509verify",
3299 .type = QEMU_OPT_STRING,
3301 .name = "acl",
3302 .type = QEMU_OPT_BOOL,
3304 .name = "lossy",
3305 .type = QEMU_OPT_BOOL,
3307 .name = "non-adaptive",
3308 .type = QEMU_OPT_BOOL,
3310 { /* end of list */ }
3315 static int
3316 vnc_display_setup_auth(VncDisplay *vs,
3317 bool password,
3318 bool sasl,
3319 bool websocket,
3320 Error **errp)
3323 * We have a choice of 3 authentication options
3325 * 1. none
3326 * 2. vnc
3327 * 3. sasl
3329 * The channel can be run in 2 modes
3331 * 1. clear
3332 * 2. tls
3334 * And TLS can use 2 types of credentials
3336 * 1. anon
3337 * 2. x509
3339 * We thus have 9 possible logical combinations
3341 * 1. clear + none
3342 * 2. clear + vnc
3343 * 3. clear + sasl
3344 * 4. tls + anon + none
3345 * 5. tls + anon + vnc
3346 * 6. tls + anon + sasl
3347 * 7. tls + x509 + none
3348 * 8. tls + x509 + vnc
3349 * 9. tls + x509 + sasl
3351 * These need to be mapped into the VNC auth schemes
3352 * in an appropriate manner. In regular VNC, all the
3353 * TLS options get mapped into VNC_AUTH_VENCRYPT
3354 * sub-auth types.
3356 * In websockets, the https:// protocol already provides
3357 * TLS support, so there is no need to make use of the
3358 * VeNCrypt extension. Furthermore, websockets browser
3359 * clients could not use VeNCrypt even if they wanted to,
3360 * as they cannot control when the TLS handshake takes
3361 * place. Thus there is no option but to rely on https://,
3362 * meaning combinations 4->6 and 7->9 will be mapped to
3363 * VNC auth schemes in the same way as combos 1->3.
3365 * Regardless of fact that we have a different mapping to
3366 * VNC auth mechs for plain VNC vs websockets VNC, the end
3367 * result has the same security characteristics.
3369 if (password) {
3370 if (vs->tlscreds) {
3371 vs->auth = VNC_AUTH_VENCRYPT;
3372 if (websocket) {
3373 vs->ws_tls = true;
3375 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3376 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3377 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3378 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3379 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3380 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3381 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3382 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3383 } else {
3384 error_setg(errp,
3385 "Unsupported TLS cred type %s",
3386 object_get_typename(OBJECT(vs->tlscreds)));
3387 return -1;
3389 } else {
3390 VNC_DEBUG("Initializing VNC server with password auth\n");
3391 vs->auth = VNC_AUTH_VNC;
3392 vs->subauth = VNC_AUTH_INVALID;
3394 if (websocket) {
3395 vs->ws_auth = VNC_AUTH_VNC;
3396 } else {
3397 vs->ws_auth = VNC_AUTH_INVALID;
3399 } else if (sasl) {
3400 if (vs->tlscreds) {
3401 vs->auth = VNC_AUTH_VENCRYPT;
3402 if (websocket) {
3403 vs->ws_tls = true;
3405 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3406 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3407 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3408 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3409 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3410 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3411 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3412 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3413 } else {
3414 error_setg(errp,
3415 "Unsupported TLS cred type %s",
3416 object_get_typename(OBJECT(vs->tlscreds)));
3417 return -1;
3419 } else {
3420 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3421 vs->auth = VNC_AUTH_SASL;
3422 vs->subauth = VNC_AUTH_INVALID;
3424 if (websocket) {
3425 vs->ws_auth = VNC_AUTH_SASL;
3426 } else {
3427 vs->ws_auth = VNC_AUTH_INVALID;
3429 } else {
3430 if (vs->tlscreds) {
3431 vs->auth = VNC_AUTH_VENCRYPT;
3432 if (websocket) {
3433 vs->ws_tls = true;
3435 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3436 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3437 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3438 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3439 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3440 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3441 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3442 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3443 } else {
3444 error_setg(errp,
3445 "Unsupported TLS cred type %s",
3446 object_get_typename(OBJECT(vs->tlscreds)));
3447 return -1;
3449 } else {
3450 VNC_DEBUG("Initializing VNC server with no auth\n");
3451 vs->auth = VNC_AUTH_NONE;
3452 vs->subauth = VNC_AUTH_INVALID;
3454 if (websocket) {
3455 vs->ws_auth = VNC_AUTH_NONE;
3456 } else {
3457 vs->ws_auth = VNC_AUTH_INVALID;
3460 return 0;
3465 * Handle back compat with old CLI syntax by creating some
3466 * suitable QCryptoTLSCreds objects
3468 static QCryptoTLSCreds *
3469 vnc_display_create_creds(bool x509,
3470 bool x509verify,
3471 const char *dir,
3472 const char *id,
3473 Error **errp)
3475 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3476 Object *parent = object_get_objects_root();
3477 Object *creds;
3478 Error *err = NULL;
3480 if (x509) {
3481 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3482 parent,
3483 credsid,
3484 &err,
3485 "endpoint", "server",
3486 "dir", dir,
3487 "verify-peer", x509verify ? "yes" : "no",
3488 NULL);
3489 } else {
3490 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3491 parent,
3492 credsid,
3493 &err,
3494 "endpoint", "server",
3495 NULL);
3498 g_free(credsid);
3500 if (err) {
3501 error_propagate(errp, err);
3502 return NULL;
3505 return QCRYPTO_TLS_CREDS(creds);
3509 void vnc_display_open(const char *id, Error **errp)
3511 VncDisplay *vs = vnc_display_find(id);
3512 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3513 SocketAddress *saddr = NULL, *wsaddr = NULL;
3514 const char *share, *device_id;
3515 QemuConsole *con;
3516 bool password = false;
3517 bool reverse = false;
3518 const char *vnc;
3519 char *h;
3520 const char *credid;
3521 int show_vnc_port = 0;
3522 bool sasl = false;
3523 #ifdef CONFIG_VNC_SASL
3524 int saslErr;
3525 #endif
3526 int acl = 0;
3527 int lock_key_sync = 1;
3528 int key_delay_ms;
3530 if (!vs) {
3531 error_setg(errp, "VNC display not active");
3532 return;
3534 vnc_display_close(vs);
3536 if (!opts) {
3537 return;
3539 vnc = qemu_opt_get(opts, "vnc");
3540 if (!vnc || strcmp(vnc, "none") == 0) {
3541 return;
3544 h = strrchr(vnc, ':');
3545 if (h) {
3546 size_t hlen = h - vnc;
3548 const char *websocket = qemu_opt_get(opts, "websocket");
3549 int to = qemu_opt_get_number(opts, "to", 0);
3550 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3551 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3552 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3553 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3555 saddr = g_new0(SocketAddress, 1);
3556 if (websocket) {
3557 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3558 error_setg(errp,
3559 "SHA1 hash support is required for websockets");
3560 goto fail;
3563 wsaddr = g_new0(SocketAddress, 1);
3564 vs->ws_enabled = true;
3567 if (strncmp(vnc, "unix:", 5) == 0) {
3568 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3569 saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
3570 saddr->u.q_unix.data->path = g_strdup(vnc + 5);
3572 if (vs->ws_enabled) {
3573 error_setg(errp, "UNIX sockets not supported with websock");
3574 goto fail;
3576 } else {
3577 unsigned long long baseport;
3578 InetSocketAddress *inet;
3579 saddr->type = SOCKET_ADDRESS_KIND_INET;
3580 inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
3581 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3582 inet->host = g_strndup(vnc + 1, hlen - 2);
3583 } else {
3584 inet->host = g_strndup(vnc, hlen);
3586 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3587 error_setg(errp, "can't convert to a number: %s", h + 1);
3588 goto fail;
3590 if (baseport > 65535 ||
3591 baseport + 5900 > 65535) {
3592 error_setg(errp, "port %s out of range", h + 1);
3593 goto fail;
3595 inet->port = g_strdup_printf(
3596 "%d", (int)baseport + 5900);
3598 if (to) {
3599 inet->has_to = true;
3600 inet->to = to + 5900;
3601 show_vnc_port = 1;
3603 inet->ipv4 = ipv4;
3604 inet->has_ipv4 = has_ipv4;
3605 inet->ipv6 = ipv6;
3606 inet->has_ipv6 = has_ipv6;
3608 if (vs->ws_enabled) {
3609 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3610 inet = wsaddr->u.inet.data = g_new0(InetSocketAddress, 1);
3611 inet->host = g_strdup(saddr->u.inet.data->host);
3612 inet->port = g_strdup(websocket);
3614 if (to) {
3615 inet->has_to = true;
3616 inet->to = to;
3618 inet->ipv4 = ipv4;
3619 inet->has_ipv4 = has_ipv4;
3620 inet->ipv6 = ipv6;
3621 inet->has_ipv6 = has_ipv6;
3624 } else {
3625 error_setg(errp, "no vnc port specified");
3626 goto fail;
3629 password = qemu_opt_get_bool(opts, "password", false);
3630 if (password) {
3631 if (fips_get_state()) {
3632 error_setg(errp,
3633 "VNC password auth disabled due to FIPS mode, "
3634 "consider using the VeNCrypt or SASL authentication "
3635 "methods as an alternative");
3636 goto fail;
3638 if (!qcrypto_cipher_supports(
3639 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3640 error_setg(errp,
3641 "Cipher backend does not support DES RFB algorithm");
3642 goto fail;
3646 reverse = qemu_opt_get_bool(opts, "reverse", false);
3647 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3648 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
3649 sasl = qemu_opt_get_bool(opts, "sasl", false);
3650 #ifndef CONFIG_VNC_SASL
3651 if (sasl) {
3652 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3653 goto fail;
3655 #endif /* CONFIG_VNC_SASL */
3656 credid = qemu_opt_get(opts, "tls-creds");
3657 if (credid) {
3658 Object *creds;
3659 if (qemu_opt_get(opts, "tls") ||
3660 qemu_opt_get(opts, "x509") ||
3661 qemu_opt_get(opts, "x509verify")) {
3662 error_setg(errp,
3663 "'tls-creds' parameter is mutually exclusive with "
3664 "'tls', 'x509' and 'x509verify' parameters");
3665 goto fail;
3668 creds = object_resolve_path_component(
3669 object_get_objects_root(), credid);
3670 if (!creds) {
3671 error_setg(errp, "No TLS credentials with id '%s'",
3672 credid);
3673 goto fail;
3675 vs->tlscreds = (QCryptoTLSCreds *)
3676 object_dynamic_cast(creds,
3677 TYPE_QCRYPTO_TLS_CREDS);
3678 if (!vs->tlscreds) {
3679 error_setg(errp, "Object with id '%s' is not TLS credentials",
3680 credid);
3681 goto fail;
3683 object_ref(OBJECT(vs->tlscreds));
3685 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3686 error_setg(errp,
3687 "Expecting TLS credentials with a server endpoint");
3688 goto fail;
3690 } else {
3691 const char *path;
3692 bool tls = false, x509 = false, x509verify = false;
3693 tls = qemu_opt_get_bool(opts, "tls", false);
3694 if (tls) {
3695 path = qemu_opt_get(opts, "x509");
3697 if (path) {
3698 x509 = true;
3699 } else {
3700 path = qemu_opt_get(opts, "x509verify");
3701 if (path) {
3702 x509 = true;
3703 x509verify = true;
3706 vs->tlscreds = vnc_display_create_creds(x509,
3707 x509verify,
3708 path,
3709 vs->id,
3710 errp);
3711 if (!vs->tlscreds) {
3712 goto fail;
3716 acl = qemu_opt_get_bool(opts, "acl", false);
3718 share = qemu_opt_get(opts, "share");
3719 if (share) {
3720 if (strcmp(share, "ignore") == 0) {
3721 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3722 } else if (strcmp(share, "allow-exclusive") == 0) {
3723 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3724 } else if (strcmp(share, "force-shared") == 0) {
3725 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3726 } else {
3727 error_setg(errp, "unknown vnc share= option");
3728 goto fail;
3730 } else {
3731 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3733 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3735 #ifdef CONFIG_VNC_JPEG
3736 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3737 #endif
3738 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3739 /* adaptive updates are only used with tight encoding and
3740 * if lossy updates are enabled so we can disable all the
3741 * calculations otherwise */
3742 if (!vs->lossy) {
3743 vs->non_adaptive = true;
3746 if (acl) {
3747 if (strcmp(vs->id, "default") == 0) {
3748 vs->tlsaclname = g_strdup("vnc.x509dname");
3749 } else {
3750 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3752 qemu_acl_init(vs->tlsaclname);
3754 #ifdef CONFIG_VNC_SASL
3755 if (acl && sasl) {
3756 char *aclname;
3758 if (strcmp(vs->id, "default") == 0) {
3759 aclname = g_strdup("vnc.username");
3760 } else {
3761 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3763 vs->sasl.acl = qemu_acl_init(aclname);
3764 g_free(aclname);
3766 #endif
3768 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3769 goto fail;
3772 #ifdef CONFIG_VNC_SASL
3773 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3774 error_setg(errp, "Failed to initialize SASL auth: %s",
3775 sasl_errstring(saslErr, NULL, NULL));
3776 goto fail;
3778 #endif
3779 vs->lock_key_sync = lock_key_sync;
3780 vs->key_delay_ms = key_delay_ms;
3782 device_id = qemu_opt_get(opts, "display");
3783 if (device_id) {
3784 int head = qemu_opt_get_number(opts, "head", 0);
3785 Error *err = NULL;
3787 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3788 if (err) {
3789 error_propagate(errp, err);
3790 goto fail;
3792 } else {
3793 con = NULL;
3796 if (con != vs->dcl.con) {
3797 unregister_displaychangelistener(&vs->dcl);
3798 vs->dcl.con = con;
3799 register_displaychangelistener(&vs->dcl);
3802 if (reverse) {
3803 /* connect to viewer */
3804 QIOChannelSocket *sioc = NULL;
3805 vs->lsock = NULL;
3806 vs->lwebsock = NULL;
3807 if (vs->ws_enabled) {
3808 error_setg(errp, "Cannot use websockets in reverse mode");
3809 goto fail;
3811 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3812 sioc = qio_channel_socket_new();
3813 if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
3814 goto fail;
3816 vnc_connect(vs, sioc, false, false);
3817 object_unref(OBJECT(sioc));
3818 } else {
3819 vs->lsock = qio_channel_socket_new();
3820 if (qio_channel_socket_listen_sync(vs->lsock, saddr, errp) < 0) {
3821 goto fail;
3823 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3824 vs->enabled = true;
3826 if (vs->ws_enabled) {
3827 vs->lwebsock = qio_channel_socket_new();
3828 if (qio_channel_socket_listen_sync(vs->lwebsock,
3829 wsaddr, errp) < 0) {
3830 object_unref(OBJECT(vs->lsock));
3831 vs->lsock = NULL;
3832 goto fail;
3836 vs->lsock_tag = qio_channel_add_watch(
3837 QIO_CHANNEL(vs->lsock),
3838 G_IO_IN, vnc_listen_io, vs, NULL);
3839 if (vs->ws_enabled) {
3840 vs->lwebsock_tag = qio_channel_add_watch(
3841 QIO_CHANNEL(vs->lwebsock),
3842 G_IO_IN, vnc_listen_io, vs, NULL);
3846 if (show_vnc_port) {
3847 vnc_display_print_local_addr(vs);
3850 qapi_free_SocketAddress(saddr);
3851 qapi_free_SocketAddress(wsaddr);
3852 return;
3854 fail:
3855 qapi_free_SocketAddress(saddr);
3856 qapi_free_SocketAddress(wsaddr);
3857 vs->enabled = false;
3858 vs->ws_enabled = false;
3861 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3863 VncDisplay *vs = vnc_display_find(id);
3864 QIOChannelSocket *sioc;
3866 if (!vs) {
3867 return;
3870 sioc = qio_channel_socket_new_fd(csock, NULL);
3871 if (sioc) {
3872 vnc_connect(vs, sioc, skipauth, false);
3873 object_unref(OBJECT(sioc));
3877 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3879 int i = 2;
3880 char *id;
3882 id = g_strdup("default");
3883 while (qemu_opts_find(olist, id)) {
3884 g_free(id);
3885 id = g_strdup_printf("vnc%d", i++);
3887 qemu_opts_set_id(opts, id);
3890 QemuOpts *vnc_parse(const char *str, Error **errp)
3892 QemuOptsList *olist = qemu_find_opts("vnc");
3893 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3894 const char *id;
3896 if (!opts) {
3897 return NULL;
3900 id = qemu_opts_id(opts);
3901 if (!id) {
3902 /* auto-assign id if not present */
3903 vnc_auto_assign_id(olist, opts);
3905 return opts;
3908 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3910 Error *local_err = NULL;
3911 char *id = (char *)qemu_opts_id(opts);
3913 assert(id);
3914 vnc_display_init(id);
3915 vnc_display_open(id, &local_err);
3916 if (local_err != NULL) {
3917 error_reportf_err(local_err, "Failed to start VNC server: ");
3918 exit(1);
3920 return 0;
3923 static void vnc_register_config(void)
3925 qemu_add_opts(&qemu_vnc_opts);
3927 opts_init(vnc_register_config);