migration: Check for ID length
[qemu/kevin.git] / ui / vnc.c
blobcdeb79c3ccd27283c624a9bf1270cf8604d55149
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "vnc.h"
29 #include "vnc-jobs.h"
30 #include "trace.h"
31 #include "hw/qdev.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
36 #include "qemu/acl.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
59 QTAILQ_HEAD_INITIALIZER(vnc_displays);
61 static int vnc_cursor_define(VncState *vs);
62 static void vnc_release_modifiers(VncState *vs);
64 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
66 #ifdef _VNC_DEBUG
67 static const char *mn[] = {
68 [0] = "undefined",
69 [VNC_SHARE_MODE_CONNECTING] = "connecting",
70 [VNC_SHARE_MODE_SHARED] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
74 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
75 vs->ioc, mn[vs->share_mode], mn[mode]);
76 #endif
78 switch (vs->share_mode) {
79 case VNC_SHARE_MODE_CONNECTING:
80 vs->vd->num_connecting--;
81 break;
82 case VNC_SHARE_MODE_SHARED:
83 vs->vd->num_shared--;
84 break;
85 case VNC_SHARE_MODE_EXCLUSIVE:
86 vs->vd->num_exclusive--;
87 break;
88 default:
89 break;
92 vs->share_mode = mode;
94 switch (vs->share_mode) {
95 case VNC_SHARE_MODE_CONNECTING:
96 vs->vd->num_connecting++;
97 break;
98 case VNC_SHARE_MODE_SHARED:
99 vs->vd->num_shared++;
100 break;
101 case VNC_SHARE_MODE_EXCLUSIVE:
102 vs->vd->num_exclusive++;
103 break;
104 default:
105 break;
110 static void vnc_init_basic_info(SocketAddress *addr,
111 VncBasicInfo *info,
112 Error **errp)
114 switch (addr->type) {
115 case SOCKET_ADDRESS_KIND_INET:
116 info->host = g_strdup(addr->u.inet.data->host);
117 info->service = g_strdup(addr->u.inet.data->port);
118 if (addr->u.inet.data->ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_KIND_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.data->path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 default:
132 error_setg(errp, "Unsupported socket kind %d",
133 addr->type);
134 break;
137 return;
140 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
141 VncBasicInfo *info,
142 Error **errp)
144 SocketAddress *addr = NULL;
146 if (!ioc) {
147 error_setg(errp, "No listener socket available");
148 return;
151 addr = qio_channel_socket_get_local_address(ioc, errp);
152 if (!addr) {
153 return;
156 vnc_init_basic_info(addr, info, errp);
157 qapi_free_SocketAddress(addr);
160 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
161 VncBasicInfo *info,
162 Error **errp)
164 SocketAddress *addr = NULL;
166 addr = qio_channel_socket_get_remote_address(ioc, errp);
167 if (!addr) {
168 return;
171 vnc_init_basic_info(addr, info, errp);
172 qapi_free_SocketAddress(addr);
175 static const char *vnc_auth_name(VncDisplay *vd) {
176 switch (vd->auth) {
177 case VNC_AUTH_INVALID:
178 return "invalid";
179 case VNC_AUTH_NONE:
180 return "none";
181 case VNC_AUTH_VNC:
182 return "vnc";
183 case VNC_AUTH_RA2:
184 return "ra2";
185 case VNC_AUTH_RA2NE:
186 return "ra2ne";
187 case VNC_AUTH_TIGHT:
188 return "tight";
189 case VNC_AUTH_ULTRA:
190 return "ultra";
191 case VNC_AUTH_TLS:
192 return "tls";
193 case VNC_AUTH_VENCRYPT:
194 switch (vd->subauth) {
195 case VNC_AUTH_VENCRYPT_PLAIN:
196 return "vencrypt+plain";
197 case VNC_AUTH_VENCRYPT_TLSNONE:
198 return "vencrypt+tls+none";
199 case VNC_AUTH_VENCRYPT_TLSVNC:
200 return "vencrypt+tls+vnc";
201 case VNC_AUTH_VENCRYPT_TLSPLAIN:
202 return "vencrypt+tls+plain";
203 case VNC_AUTH_VENCRYPT_X509NONE:
204 return "vencrypt+x509+none";
205 case VNC_AUTH_VENCRYPT_X509VNC:
206 return "vencrypt+x509+vnc";
207 case VNC_AUTH_VENCRYPT_X509PLAIN:
208 return "vencrypt+x509+plain";
209 case VNC_AUTH_VENCRYPT_TLSSASL:
210 return "vencrypt+tls+sasl";
211 case VNC_AUTH_VENCRYPT_X509SASL:
212 return "vencrypt+x509+sasl";
213 default:
214 return "vencrypt";
216 case VNC_AUTH_SASL:
217 return "sasl";
219 return "unknown";
222 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
224 VncServerInfo *info;
225 Error *err = NULL;
227 info = g_malloc0(sizeof(*info));
228 vnc_init_basic_info_from_server_addr(vd->lsock,
229 qapi_VncServerInfo_base(info), &err);
230 info->has_auth = true;
231 info->auth = g_strdup(vnc_auth_name(vd));
232 if (err) {
233 qapi_free_VncServerInfo(info);
234 info = NULL;
235 error_free(err);
237 return info;
240 static void vnc_client_cache_auth(VncState *client)
242 if (!client->info) {
243 return;
246 if (client->tls) {
247 client->info->x509_dname =
248 qcrypto_tls_session_get_peer_name(client->tls);
249 client->info->has_x509_dname =
250 client->info->x509_dname != NULL;
252 #ifdef CONFIG_VNC_SASL
253 if (client->sasl.conn &&
254 client->sasl.username) {
255 client->info->has_sasl_username = true;
256 client->info->sasl_username = g_strdup(client->sasl.username);
258 #endif
261 static void vnc_client_cache_addr(VncState *client)
263 Error *err = NULL;
265 client->info = g_malloc0(sizeof(*client->info));
266 vnc_init_basic_info_from_remote_addr(client->sioc,
267 qapi_VncClientInfo_base(client->info),
268 &err);
269 if (err) {
270 qapi_free_VncClientInfo(client->info);
271 client->info = NULL;
272 error_free(err);
276 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
278 VncServerInfo *si;
280 if (!vs->info) {
281 return;
284 si = vnc_server_info_get(vs->vd);
285 if (!si) {
286 return;
289 switch (event) {
290 case QAPI_EVENT_VNC_CONNECTED:
291 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
292 &error_abort);
293 break;
294 case QAPI_EVENT_VNC_INITIALIZED:
295 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
296 break;
297 case QAPI_EVENT_VNC_DISCONNECTED:
298 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
299 break;
300 default:
301 break;
304 qapi_free_VncServerInfo(si);
307 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
309 VncClientInfo *info;
310 Error *err = NULL;
312 info = g_malloc0(sizeof(*info));
314 vnc_init_basic_info_from_remote_addr(client->sioc,
315 qapi_VncClientInfo_base(info),
316 &err);
317 if (err) {
318 error_free(err);
319 qapi_free_VncClientInfo(info);
320 return NULL;
323 info->websocket = client->websocket;
325 if (client->tls) {
326 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
327 info->has_x509_dname = info->x509_dname != NULL;
329 #ifdef CONFIG_VNC_SASL
330 if (client->sasl.conn && client->sasl.username) {
331 info->has_sasl_username = true;
332 info->sasl_username = g_strdup(client->sasl.username);
334 #endif
336 return info;
339 static VncDisplay *vnc_display_find(const char *id)
341 VncDisplay *vd;
343 if (id == NULL) {
344 return QTAILQ_FIRST(&vnc_displays);
346 QTAILQ_FOREACH(vd, &vnc_displays, next) {
347 if (strcmp(id, vd->id) == 0) {
348 return vd;
351 return NULL;
354 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
356 VncClientInfoList *cinfo, *prev = NULL;
357 VncState *client;
359 QTAILQ_FOREACH(client, &vd->clients, next) {
360 cinfo = g_new0(VncClientInfoList, 1);
361 cinfo->value = qmp_query_vnc_client(client);
362 cinfo->next = prev;
363 prev = cinfo;
365 return prev;
368 VncInfo *qmp_query_vnc(Error **errp)
370 VncInfo *info = g_malloc0(sizeof(*info));
371 VncDisplay *vd = vnc_display_find(NULL);
372 SocketAddress *addr = NULL;
374 if (vd == NULL || !vd->lsock) {
375 info->enabled = false;
376 } else {
377 info->enabled = true;
379 /* for compatibility with the original command */
380 info->has_clients = true;
381 info->clients = qmp_query_client_list(vd);
383 if (vd->lsock == NULL) {
384 return info;
387 addr = qio_channel_socket_get_local_address(vd->lsock, errp);
388 if (!addr) {
389 goto out_error;
392 switch (addr->type) {
393 case SOCKET_ADDRESS_KIND_INET:
394 info->host = g_strdup(addr->u.inet.data->host);
395 info->service = g_strdup(addr->u.inet.data->port);
396 if (addr->u.inet.data->ipv6) {
397 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
398 } else {
399 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
401 break;
403 case SOCKET_ADDRESS_KIND_UNIX:
404 info->host = g_strdup("");
405 info->service = g_strdup(addr->u.q_unix.data->path);
406 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
407 break;
409 default:
410 error_setg(errp, "Unsupported socket kind %d",
411 addr->type);
412 goto out_error;
415 info->has_host = true;
416 info->has_service = true;
417 info->has_family = true;
419 info->has_auth = true;
420 info->auth = g_strdup(vnc_auth_name(vd));
423 qapi_free_SocketAddress(addr);
424 return info;
426 out_error:
427 qapi_free_SocketAddress(addr);
428 qapi_free_VncInfo(info);
429 return NULL;
432 static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,
433 bool websocket,
434 VncBasicInfoList *prev)
436 VncBasicInfoList *list;
437 VncBasicInfo *info;
438 Error *err = NULL;
439 SocketAddress *addr;
441 addr = qio_channel_socket_get_local_address(ioc, &err);
442 if (!addr) {
443 error_free(err);
444 return prev;
447 info = g_new0(VncBasicInfo, 1);
448 vnc_init_basic_info(addr, info, &err);
449 qapi_free_SocketAddress(addr);
450 if (err) {
451 qapi_free_VncBasicInfo(info);
452 error_free(err);
453 return prev;
455 info->websocket = websocket;
457 list = g_new0(VncBasicInfoList, 1);
458 list->value = info;
459 list->next = prev;
460 return list;
463 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
465 switch (vd->auth) {
466 case VNC_AUTH_VNC:
467 info->auth = VNC_PRIMARY_AUTH_VNC;
468 break;
469 case VNC_AUTH_RA2:
470 info->auth = VNC_PRIMARY_AUTH_RA2;
471 break;
472 case VNC_AUTH_RA2NE:
473 info->auth = VNC_PRIMARY_AUTH_RA2NE;
474 break;
475 case VNC_AUTH_TIGHT:
476 info->auth = VNC_PRIMARY_AUTH_TIGHT;
477 break;
478 case VNC_AUTH_ULTRA:
479 info->auth = VNC_PRIMARY_AUTH_ULTRA;
480 break;
481 case VNC_AUTH_TLS:
482 info->auth = VNC_PRIMARY_AUTH_TLS;
483 break;
484 case VNC_AUTH_VENCRYPT:
485 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
486 info->has_vencrypt = true;
487 switch (vd->subauth) {
488 case VNC_AUTH_VENCRYPT_PLAIN:
489 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
490 break;
491 case VNC_AUTH_VENCRYPT_TLSNONE:
492 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
493 break;
494 case VNC_AUTH_VENCRYPT_TLSVNC:
495 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
496 break;
497 case VNC_AUTH_VENCRYPT_TLSPLAIN:
498 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
499 break;
500 case VNC_AUTH_VENCRYPT_X509NONE:
501 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
502 break;
503 case VNC_AUTH_VENCRYPT_X509VNC:
504 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
505 break;
506 case VNC_AUTH_VENCRYPT_X509PLAIN:
507 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
508 break;
509 case VNC_AUTH_VENCRYPT_TLSSASL:
510 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
511 break;
512 case VNC_AUTH_VENCRYPT_X509SASL:
513 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
514 break;
515 default:
516 info->has_vencrypt = false;
517 break;
519 break;
520 case VNC_AUTH_SASL:
521 info->auth = VNC_PRIMARY_AUTH_SASL;
522 break;
523 case VNC_AUTH_NONE:
524 default:
525 info->auth = VNC_PRIMARY_AUTH_NONE;
526 break;
530 VncInfo2List *qmp_query_vnc_servers(Error **errp)
532 VncInfo2List *item, *prev = NULL;
533 VncInfo2 *info;
534 VncDisplay *vd;
535 DeviceState *dev;
537 QTAILQ_FOREACH(vd, &vnc_displays, next) {
538 info = g_new0(VncInfo2, 1);
539 info->id = g_strdup(vd->id);
540 info->clients = qmp_query_client_list(vd);
541 qmp_query_auth(vd, info);
542 if (vd->dcl.con) {
543 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
544 "device", NULL));
545 info->has_display = true;
546 info->display = g_strdup(dev->id);
548 if (vd->lsock != NULL) {
549 info->server = qmp_query_server_entry(
550 vd->lsock, false, info->server);
552 if (vd->lwebsock != NULL) {
553 info->server = qmp_query_server_entry(
554 vd->lwebsock, true, info->server);
557 item = g_new0(VncInfo2List, 1);
558 item->value = info;
559 item->next = prev;
560 prev = item;
562 return prev;
565 /* TODO
566 1) Get the queue working for IO.
567 2) there is some weirdness when using the -S option (the screen is grey
568 and not totally invalidated
569 3) resolutions > 1024
572 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
573 static void vnc_disconnect_start(VncState *vs);
575 static void vnc_colordepth(VncState *vs);
576 static void framebuffer_update_request(VncState *vs, int incremental,
577 int x_position, int y_position,
578 int w, int h);
579 static void vnc_refresh(DisplayChangeListener *dcl);
580 static int vnc_refresh_server_surface(VncDisplay *vd);
582 static int vnc_width(VncDisplay *vd)
584 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
585 VNC_DIRTY_PIXELS_PER_BIT));
588 static int vnc_height(VncDisplay *vd)
590 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
593 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
594 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
595 VncDisplay *vd,
596 int x, int y, int w, int h)
598 int width = vnc_width(vd);
599 int height = vnc_height(vd);
601 /* this is needed this to ensure we updated all affected
602 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
603 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
604 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
606 x = MIN(x, width);
607 y = MIN(y, height);
608 w = MIN(x + w, width) - x;
609 h = MIN(y + h, height);
611 for (; y < h; y++) {
612 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
613 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
617 static void vnc_dpy_update(DisplayChangeListener *dcl,
618 int x, int y, int w, int h)
620 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
621 struct VncSurface *s = &vd->guest;
623 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
626 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
627 int32_t encoding)
629 vnc_write_u16(vs, x);
630 vnc_write_u16(vs, y);
631 vnc_write_u16(vs, w);
632 vnc_write_u16(vs, h);
634 vnc_write_s32(vs, encoding);
638 static void vnc_desktop_resize(VncState *vs)
640 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
641 return;
643 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
644 vs->client_height == pixman_image_get_height(vs->vd->server)) {
645 return;
647 vs->client_width = pixman_image_get_width(vs->vd->server);
648 vs->client_height = pixman_image_get_height(vs->vd->server);
649 vnc_lock_output(vs);
650 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
651 vnc_write_u8(vs, 0);
652 vnc_write_u16(vs, 1); /* number of rects */
653 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
654 VNC_ENCODING_DESKTOPRESIZE);
655 vnc_unlock_output(vs);
656 vnc_flush(vs);
659 static void vnc_abort_display_jobs(VncDisplay *vd)
661 VncState *vs;
663 QTAILQ_FOREACH(vs, &vd->clients, next) {
664 vnc_lock_output(vs);
665 vs->abort = true;
666 vnc_unlock_output(vs);
668 QTAILQ_FOREACH(vs, &vd->clients, next) {
669 vnc_jobs_join(vs);
671 QTAILQ_FOREACH(vs, &vd->clients, next) {
672 vnc_lock_output(vs);
673 vs->abort = false;
674 vnc_unlock_output(vs);
678 int vnc_server_fb_stride(VncDisplay *vd)
680 return pixman_image_get_stride(vd->server);
683 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
685 uint8_t *ptr;
687 ptr = (uint8_t *)pixman_image_get_data(vd->server);
688 ptr += y * vnc_server_fb_stride(vd);
689 ptr += x * VNC_SERVER_FB_BYTES;
690 return ptr;
693 static void vnc_update_server_surface(VncDisplay *vd)
695 int width, height;
697 qemu_pixman_image_unref(vd->server);
698 vd->server = NULL;
700 if (QTAILQ_EMPTY(&vd->clients)) {
701 return;
704 width = vnc_width(vd);
705 height = vnc_height(vd);
706 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
707 width, height,
708 NULL, 0);
710 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
711 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
712 width, height);
715 static void vnc_dpy_switch(DisplayChangeListener *dcl,
716 DisplaySurface *surface)
718 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
719 VncState *vs;
721 vnc_abort_display_jobs(vd);
722 vd->ds = surface;
724 /* server surface */
725 vnc_update_server_surface(vd);
727 /* guest surface */
728 qemu_pixman_image_unref(vd->guest.fb);
729 vd->guest.fb = pixman_image_ref(surface->image);
730 vd->guest.format = surface->format;
732 QTAILQ_FOREACH(vs, &vd->clients, next) {
733 vnc_colordepth(vs);
734 vnc_desktop_resize(vs);
735 if (vs->vd->cursor) {
736 vnc_cursor_define(vs);
738 memset(vs->dirty, 0x00, sizeof(vs->dirty));
739 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
740 vnc_width(vd),
741 vnc_height(vd));
745 /* fastest code */
746 static void vnc_write_pixels_copy(VncState *vs,
747 void *pixels, int size)
749 vnc_write(vs, pixels, size);
752 /* slowest but generic code. */
753 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
755 uint8_t r, g, b;
757 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
758 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
759 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
760 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
761 #else
762 # error need some bits here if you change VNC_SERVER_FB_FORMAT
763 #endif
764 v = (r << vs->client_pf.rshift) |
765 (g << vs->client_pf.gshift) |
766 (b << vs->client_pf.bshift);
767 switch (vs->client_pf.bytes_per_pixel) {
768 case 1:
769 buf[0] = v;
770 break;
771 case 2:
772 if (vs->client_be) {
773 buf[0] = v >> 8;
774 buf[1] = v;
775 } else {
776 buf[1] = v >> 8;
777 buf[0] = v;
779 break;
780 default:
781 case 4:
782 if (vs->client_be) {
783 buf[0] = v >> 24;
784 buf[1] = v >> 16;
785 buf[2] = v >> 8;
786 buf[3] = v;
787 } else {
788 buf[3] = v >> 24;
789 buf[2] = v >> 16;
790 buf[1] = v >> 8;
791 buf[0] = v;
793 break;
797 static void vnc_write_pixels_generic(VncState *vs,
798 void *pixels1, int size)
800 uint8_t buf[4];
802 if (VNC_SERVER_FB_BYTES == 4) {
803 uint32_t *pixels = pixels1;
804 int n, i;
805 n = size >> 2;
806 for (i = 0; i < n; i++) {
807 vnc_convert_pixel(vs, buf, pixels[i]);
808 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
813 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
815 int i;
816 uint8_t *row;
817 VncDisplay *vd = vs->vd;
819 row = vnc_server_fb_ptr(vd, x, y);
820 for (i = 0; i < h; i++) {
821 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
822 row += vnc_server_fb_stride(vd);
824 return 1;
827 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
829 int n = 0;
830 bool encode_raw = false;
831 size_t saved_offs = vs->output.offset;
833 switch(vs->vnc_encoding) {
834 case VNC_ENCODING_ZLIB:
835 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
836 break;
837 case VNC_ENCODING_HEXTILE:
838 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
839 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
840 break;
841 case VNC_ENCODING_TIGHT:
842 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
843 break;
844 case VNC_ENCODING_TIGHT_PNG:
845 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
846 break;
847 case VNC_ENCODING_ZRLE:
848 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
849 break;
850 case VNC_ENCODING_ZYWRLE:
851 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
852 break;
853 default:
854 encode_raw = true;
855 break;
858 /* If the client has the same pixel format as our internal buffer and
859 * a RAW encoding would need less space fall back to RAW encoding to
860 * save bandwidth and processing power in the client. */
861 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
862 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
863 vs->output.offset = saved_offs;
864 encode_raw = true;
867 if (encode_raw) {
868 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
869 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
872 return n;
875 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
877 /* send bitblit op to the vnc client */
878 vnc_lock_output(vs);
879 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
880 vnc_write_u8(vs, 0);
881 vnc_write_u16(vs, 1); /* number of rects */
882 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
883 vnc_write_u16(vs, src_x);
884 vnc_write_u16(vs, src_y);
885 vnc_unlock_output(vs);
886 vnc_flush(vs);
889 static void vnc_dpy_copy(DisplayChangeListener *dcl,
890 int src_x, int src_y,
891 int dst_x, int dst_y, int w, int h)
893 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
894 VncState *vs, *vn;
895 uint8_t *src_row;
896 uint8_t *dst_row;
897 int i, x, y, pitch, inc, w_lim, s;
898 int cmp_bytes;
900 if (!vd->server) {
901 /* no client connected */
902 return;
905 vnc_refresh_server_surface(vd);
906 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
907 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
908 vs->force_update = 1;
909 vnc_update_client(vs, 1, true);
910 /* vs might be free()ed here */
914 if (!vd->server) {
915 /* no client connected */
916 return;
918 /* do bitblit op on the local surface too */
919 pitch = vnc_server_fb_stride(vd);
920 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
921 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
922 y = dst_y;
923 inc = 1;
924 if (dst_y > src_y) {
925 /* copy backwards */
926 src_row += pitch * (h-1);
927 dst_row += pitch * (h-1);
928 pitch = -pitch;
929 y = dst_y + h - 1;
930 inc = -1;
932 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
933 if (w_lim < 0) {
934 w_lim = w;
935 } else {
936 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
938 for (i = 0; i < h; i++) {
939 for (x = 0; x <= w_lim;
940 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
941 if (x == w_lim) {
942 if ((s = w - w_lim) == 0)
943 break;
944 } else if (!x) {
945 s = (VNC_DIRTY_PIXELS_PER_BIT -
946 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
947 s = MIN(s, w_lim);
948 } else {
949 s = VNC_DIRTY_PIXELS_PER_BIT;
951 cmp_bytes = s * VNC_SERVER_FB_BYTES;
952 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
953 continue;
954 memmove(dst_row, src_row, cmp_bytes);
955 QTAILQ_FOREACH(vs, &vd->clients, next) {
956 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
957 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
958 vs->dirty[y]);
962 src_row += pitch - w * VNC_SERVER_FB_BYTES;
963 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
964 y += inc;
967 QTAILQ_FOREACH(vs, &vd->clients, next) {
968 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
969 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
974 static void vnc_mouse_set(DisplayChangeListener *dcl,
975 int x, int y, int visible)
977 /* can we ask the client(s) to move the pointer ??? */
980 static int vnc_cursor_define(VncState *vs)
982 QEMUCursor *c = vs->vd->cursor;
983 int isize;
985 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
986 vnc_lock_output(vs);
987 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
988 vnc_write_u8(vs, 0); /* padding */
989 vnc_write_u16(vs, 1); /* # of rects */
990 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
991 VNC_ENCODING_RICH_CURSOR);
992 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
993 vnc_write_pixels_generic(vs, c->data, isize);
994 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
995 vnc_unlock_output(vs);
996 return 0;
998 return -1;
1001 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1002 QEMUCursor *c)
1004 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1005 VncState *vs;
1007 cursor_put(vd->cursor);
1008 g_free(vd->cursor_mask);
1010 vd->cursor = c;
1011 cursor_get(vd->cursor);
1012 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1013 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1014 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1016 QTAILQ_FOREACH(vs, &vd->clients, next) {
1017 vnc_cursor_define(vs);
1021 static int find_and_clear_dirty_height(VncState *vs,
1022 int y, int last_x, int x, int height)
1024 int h;
1026 for (h = 1; h < (height - y); h++) {
1027 if (!test_bit(last_x, vs->dirty[y + h])) {
1028 break;
1030 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1033 return h;
1036 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1038 if (vs->disconnecting) {
1039 vnc_disconnect_finish(vs);
1040 return 0;
1043 vs->has_dirty += has_dirty;
1044 if (vs->need_update && !vs->disconnecting) {
1045 VncDisplay *vd = vs->vd;
1046 VncJob *job;
1047 int y;
1048 int height, width;
1049 int n = 0;
1051 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1052 /* kernel send buffers are full -> drop frames to throttle */
1053 return 0;
1055 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1056 return 0;
1059 * Send screen updates to the vnc client using the server
1060 * surface and server dirty map. guest surface updates
1061 * happening in parallel don't disturb us, the next pass will
1062 * send them to the client.
1064 job = vnc_job_new(vs);
1066 height = pixman_image_get_height(vd->server);
1067 width = pixman_image_get_width(vd->server);
1069 y = 0;
1070 for (;;) {
1071 int x, h;
1072 unsigned long x2;
1073 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1074 height * VNC_DIRTY_BPL(vs),
1075 y * VNC_DIRTY_BPL(vs));
1076 if (offset == height * VNC_DIRTY_BPL(vs)) {
1077 /* no more dirty bits */
1078 break;
1080 y = offset / VNC_DIRTY_BPL(vs);
1081 x = offset % VNC_DIRTY_BPL(vs);
1082 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1083 VNC_DIRTY_BPL(vs), x);
1084 bitmap_clear(vs->dirty[y], x, x2 - x);
1085 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1086 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1087 if (x2 > x) {
1088 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1089 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1091 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1092 y += h;
1093 if (y == height) {
1094 break;
1099 vnc_job_push(job);
1100 if (sync) {
1101 vnc_jobs_join(vs);
1103 vs->force_update = 0;
1104 vs->has_dirty = 0;
1105 return n;
1108 if (vs->disconnecting) {
1109 vnc_disconnect_finish(vs);
1110 } else if (sync) {
1111 vnc_jobs_join(vs);
1114 return 0;
1117 /* audio */
1118 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1120 VncState *vs = opaque;
1122 switch (cmd) {
1123 case AUD_CNOTIFY_DISABLE:
1124 vnc_lock_output(vs);
1125 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1126 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1127 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1128 vnc_unlock_output(vs);
1129 vnc_flush(vs);
1130 break;
1132 case AUD_CNOTIFY_ENABLE:
1133 vnc_lock_output(vs);
1134 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1135 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1136 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1137 vnc_unlock_output(vs);
1138 vnc_flush(vs);
1139 break;
1143 static void audio_capture_destroy(void *opaque)
1147 static void audio_capture(void *opaque, void *buf, int size)
1149 VncState *vs = opaque;
1151 vnc_lock_output(vs);
1152 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1153 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1154 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1155 vnc_write_u32(vs, size);
1156 vnc_write(vs, buf, size);
1157 vnc_unlock_output(vs);
1158 vnc_flush(vs);
1161 static void audio_add(VncState *vs)
1163 struct audio_capture_ops ops;
1165 if (vs->audio_cap) {
1166 error_report("audio already running");
1167 return;
1170 ops.notify = audio_capture_notify;
1171 ops.destroy = audio_capture_destroy;
1172 ops.capture = audio_capture;
1174 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1175 if (!vs->audio_cap) {
1176 error_report("Failed to add audio capture");
1180 static void audio_del(VncState *vs)
1182 if (vs->audio_cap) {
1183 AUD_del_capture(vs->audio_cap, vs);
1184 vs->audio_cap = NULL;
1188 static void vnc_disconnect_start(VncState *vs)
1190 if (vs->disconnecting) {
1191 return;
1193 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1194 if (vs->ioc_tag) {
1195 g_source_remove(vs->ioc_tag);
1197 qio_channel_close(vs->ioc, NULL);
1198 vs->disconnecting = TRUE;
1201 void vnc_disconnect_finish(VncState *vs)
1203 int i;
1205 vnc_jobs_join(vs); /* Wait encoding jobs */
1207 vnc_lock_output(vs);
1208 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1210 buffer_free(&vs->input);
1211 buffer_free(&vs->output);
1213 qapi_free_VncClientInfo(vs->info);
1215 vnc_zlib_clear(vs);
1216 vnc_tight_clear(vs);
1217 vnc_zrle_clear(vs);
1219 #ifdef CONFIG_VNC_SASL
1220 vnc_sasl_client_cleanup(vs);
1221 #endif /* CONFIG_VNC_SASL */
1222 audio_del(vs);
1223 vnc_release_modifiers(vs);
1225 if (vs->mouse_mode_notifier.notify != NULL) {
1226 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1228 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1229 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1230 /* last client gone */
1231 vnc_update_server_surface(vs->vd);
1234 vnc_unlock_output(vs);
1236 qemu_mutex_destroy(&vs->output_mutex);
1237 if (vs->bh != NULL) {
1238 qemu_bh_delete(vs->bh);
1240 buffer_free(&vs->jobs_buffer);
1242 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1243 g_free(vs->lossy_rect[i]);
1245 g_free(vs->lossy_rect);
1247 object_unref(OBJECT(vs->ioc));
1248 vs->ioc = NULL;
1249 object_unref(OBJECT(vs->sioc));
1250 vs->sioc = NULL;
1251 g_free(vs);
1254 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1256 if (ret <= 0) {
1257 if (ret == 0) {
1258 VNC_DEBUG("Closing down client sock: EOF\n");
1259 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1260 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1261 ret, errp ? error_get_pretty(*errp) : "Unknown");
1264 vnc_disconnect_start(vs);
1265 if (errp) {
1266 error_free(*errp);
1267 *errp = NULL;
1269 return 0;
1271 return ret;
1275 void vnc_client_error(VncState *vs)
1277 VNC_DEBUG("Closing down client sock: protocol error\n");
1278 vnc_disconnect_start(vs);
1283 * Called to write a chunk of data to the client socket. The data may
1284 * be the raw data, or may have already been encoded by SASL.
1285 * The data will be written either straight onto the socket, or
1286 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1288 * NB, it is theoretically possible to have 2 layers of encryption,
1289 * both SASL, and this TLS layer. It is highly unlikely in practice
1290 * though, since SASL encryption will typically be a no-op if TLS
1291 * is active
1293 * Returns the number of bytes written, which may be less than
1294 * the requested 'datalen' if the socket would block. Returns
1295 * -1 on error, and disconnects the client socket.
1297 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1299 Error *err = NULL;
1300 ssize_t ret;
1301 ret = qio_channel_write(
1302 vs->ioc, (const char *)data, datalen, &err);
1303 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1304 return vnc_client_io_error(vs, ret, &err);
1309 * Called to write buffered data to the client socket, when not
1310 * using any SASL SSF encryption layers. Will write as much data
1311 * as possible without blocking. If all buffered data is written,
1312 * will switch the FD poll() handler back to read monitoring.
1314 * Returns the number of bytes written, which may be less than
1315 * the buffered output data if the socket would block. Returns
1316 * -1 on error, and disconnects the client socket.
1318 static ssize_t vnc_client_write_plain(VncState *vs)
1320 ssize_t ret;
1322 #ifdef CONFIG_VNC_SASL
1323 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1324 vs->output.buffer, vs->output.capacity, vs->output.offset,
1325 vs->sasl.waitWriteSSF);
1327 if (vs->sasl.conn &&
1328 vs->sasl.runSSF &&
1329 vs->sasl.waitWriteSSF) {
1330 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1331 if (ret)
1332 vs->sasl.waitWriteSSF -= ret;
1333 } else
1334 #endif /* CONFIG_VNC_SASL */
1335 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1336 if (!ret)
1337 return 0;
1339 buffer_advance(&vs->output, ret);
1341 if (vs->output.offset == 0) {
1342 if (vs->ioc_tag) {
1343 g_source_remove(vs->ioc_tag);
1345 vs->ioc_tag = qio_channel_add_watch(
1346 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1349 return ret;
1354 * First function called whenever there is data to be written to
1355 * the client socket. Will delegate actual work according to whether
1356 * SASL SSF layers are enabled (thus requiring encryption calls)
1358 static void vnc_client_write_locked(VncState *vs)
1360 #ifdef CONFIG_VNC_SASL
1361 if (vs->sasl.conn &&
1362 vs->sasl.runSSF &&
1363 !vs->sasl.waitWriteSSF) {
1364 vnc_client_write_sasl(vs);
1365 } else
1366 #endif /* CONFIG_VNC_SASL */
1368 vnc_client_write_plain(vs);
1372 static void vnc_client_write(VncState *vs)
1375 vnc_lock_output(vs);
1376 if (vs->output.offset) {
1377 vnc_client_write_locked(vs);
1378 } else if (vs->ioc != NULL) {
1379 if (vs->ioc_tag) {
1380 g_source_remove(vs->ioc_tag);
1382 vs->ioc_tag = qio_channel_add_watch(
1383 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1385 vnc_unlock_output(vs);
1388 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1390 vs->read_handler = func;
1391 vs->read_handler_expect = expecting;
1396 * Called to read a chunk of data from the client socket. The data may
1397 * be the raw data, or may need to be further decoded by SASL.
1398 * The data will be read either straight from to the socket, or
1399 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1401 * NB, it is theoretically possible to have 2 layers of encryption,
1402 * both SASL, and this TLS layer. It is highly unlikely in practice
1403 * though, since SASL encryption will typically be a no-op if TLS
1404 * is active
1406 * Returns the number of bytes read, which may be less than
1407 * the requested 'datalen' if the socket would block. Returns
1408 * -1 on error, and disconnects the client socket.
1410 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1412 ssize_t ret;
1413 Error *err = NULL;
1414 ret = qio_channel_read(
1415 vs->ioc, (char *)data, datalen, &err);
1416 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1417 return vnc_client_io_error(vs, ret, &err);
1422 * Called to read data from the client socket to the input buffer,
1423 * when not using any SASL SSF encryption layers. Will read as much
1424 * data as possible without blocking.
1426 * Returns the number of bytes read. Returns -1 on error, and
1427 * disconnects the client socket.
1429 static ssize_t vnc_client_read_plain(VncState *vs)
1431 ssize_t ret;
1432 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1433 vs->input.buffer, vs->input.capacity, vs->input.offset);
1434 buffer_reserve(&vs->input, 4096);
1435 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1436 if (!ret)
1437 return 0;
1438 vs->input.offset += ret;
1439 return ret;
1442 static void vnc_jobs_bh(void *opaque)
1444 VncState *vs = opaque;
1446 vnc_jobs_consume_buffer(vs);
1450 * First function called whenever there is more data to be read from
1451 * the client socket. Will delegate actual work according to whether
1452 * SASL SSF layers are enabled (thus requiring decryption calls)
1453 * Returns 0 on success, -1 if client disconnected
1455 static int vnc_client_read(VncState *vs)
1457 ssize_t ret;
1459 #ifdef CONFIG_VNC_SASL
1460 if (vs->sasl.conn && vs->sasl.runSSF)
1461 ret = vnc_client_read_sasl(vs);
1462 else
1463 #endif /* CONFIG_VNC_SASL */
1464 ret = vnc_client_read_plain(vs);
1465 if (!ret) {
1466 if (vs->disconnecting) {
1467 vnc_disconnect_finish(vs);
1468 return -1;
1470 return 0;
1473 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1474 size_t len = vs->read_handler_expect;
1475 int ret;
1477 ret = vs->read_handler(vs, vs->input.buffer, len);
1478 if (vs->disconnecting) {
1479 vnc_disconnect_finish(vs);
1480 return -1;
1483 if (!ret) {
1484 buffer_advance(&vs->input, len);
1485 } else {
1486 vs->read_handler_expect = ret;
1489 return 0;
1492 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1493 GIOCondition condition, void *opaque)
1495 VncState *vs = opaque;
1496 if (condition & G_IO_IN) {
1497 if (vnc_client_read(vs) < 0) {
1498 return TRUE;
1501 if (condition & G_IO_OUT) {
1502 vnc_client_write(vs);
1504 return TRUE;
1508 void vnc_write(VncState *vs, const void *data, size_t len)
1510 buffer_reserve(&vs->output, len);
1512 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1513 if (vs->ioc_tag) {
1514 g_source_remove(vs->ioc_tag);
1516 vs->ioc_tag = qio_channel_add_watch(
1517 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1520 buffer_append(&vs->output, data, len);
1523 void vnc_write_s32(VncState *vs, int32_t value)
1525 vnc_write_u32(vs, *(uint32_t *)&value);
1528 void vnc_write_u32(VncState *vs, uint32_t value)
1530 uint8_t buf[4];
1532 buf[0] = (value >> 24) & 0xFF;
1533 buf[1] = (value >> 16) & 0xFF;
1534 buf[2] = (value >> 8) & 0xFF;
1535 buf[3] = value & 0xFF;
1537 vnc_write(vs, buf, 4);
1540 void vnc_write_u16(VncState *vs, uint16_t value)
1542 uint8_t buf[2];
1544 buf[0] = (value >> 8) & 0xFF;
1545 buf[1] = value & 0xFF;
1547 vnc_write(vs, buf, 2);
1550 void vnc_write_u8(VncState *vs, uint8_t value)
1552 vnc_write(vs, (char *)&value, 1);
1555 void vnc_flush(VncState *vs)
1557 vnc_lock_output(vs);
1558 if (vs->ioc != NULL && vs->output.offset) {
1559 vnc_client_write_locked(vs);
1561 vnc_unlock_output(vs);
1564 static uint8_t read_u8(uint8_t *data, size_t offset)
1566 return data[offset];
1569 static uint16_t read_u16(uint8_t *data, size_t offset)
1571 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1574 static int32_t read_s32(uint8_t *data, size_t offset)
1576 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1577 (data[offset + 2] << 8) | data[offset + 3]);
1580 uint32_t read_u32(uint8_t *data, size_t offset)
1582 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1583 (data[offset + 2] << 8) | data[offset + 3]);
1586 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1590 static void check_pointer_type_change(Notifier *notifier, void *data)
1592 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1593 int absolute = qemu_input_is_absolute();
1595 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1596 vnc_lock_output(vs);
1597 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1598 vnc_write_u8(vs, 0);
1599 vnc_write_u16(vs, 1);
1600 vnc_framebuffer_update(vs, absolute, 0,
1601 pixman_image_get_width(vs->vd->server),
1602 pixman_image_get_height(vs->vd->server),
1603 VNC_ENCODING_POINTER_TYPE_CHANGE);
1604 vnc_unlock_output(vs);
1605 vnc_flush(vs);
1607 vs->absolute = absolute;
1610 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1612 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1613 [INPUT_BUTTON_LEFT] = 0x01,
1614 [INPUT_BUTTON_MIDDLE] = 0x02,
1615 [INPUT_BUTTON_RIGHT] = 0x04,
1616 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1617 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1619 QemuConsole *con = vs->vd->dcl.con;
1620 int width = pixman_image_get_width(vs->vd->server);
1621 int height = pixman_image_get_height(vs->vd->server);
1623 if (vs->last_bmask != button_mask) {
1624 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1625 vs->last_bmask = button_mask;
1628 if (vs->absolute) {
1629 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1630 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1631 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1632 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1633 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1634 } else {
1635 if (vs->last_x != -1) {
1636 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1637 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1639 vs->last_x = x;
1640 vs->last_y = y;
1642 qemu_input_event_sync();
1645 static void reset_keys(VncState *vs)
1647 int i;
1648 for(i = 0; i < 256; i++) {
1649 if (vs->modifiers_state[i]) {
1650 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1651 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1652 vs->modifiers_state[i] = 0;
1657 static void press_key(VncState *vs, int keysym)
1659 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1660 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1661 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1662 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1663 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1666 static void vnc_led_state_change(VncState *vs)
1668 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1669 return;
1672 vnc_lock_output(vs);
1673 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1674 vnc_write_u8(vs, 0);
1675 vnc_write_u16(vs, 1);
1676 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1677 vnc_write_u8(vs, vs->vd->ledstate);
1678 vnc_unlock_output(vs);
1679 vnc_flush(vs);
1682 static void kbd_leds(void *opaque, int ledstate)
1684 VncDisplay *vd = opaque;
1685 VncState *client;
1687 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1688 (ledstate & QEMU_NUM_LOCK_LED),
1689 (ledstate & QEMU_SCROLL_LOCK_LED));
1691 if (ledstate == vd->ledstate) {
1692 return;
1695 vd->ledstate = ledstate;
1697 QTAILQ_FOREACH(client, &vd->clients, next) {
1698 vnc_led_state_change(client);
1702 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1704 /* QEMU console switch */
1705 switch(keycode) {
1706 case 0x2a: /* Left Shift */
1707 case 0x36: /* Right Shift */
1708 case 0x1d: /* Left CTRL */
1709 case 0x9d: /* Right CTRL */
1710 case 0x38: /* Left ALT */
1711 case 0xb8: /* Right ALT */
1712 if (down)
1713 vs->modifiers_state[keycode] = 1;
1714 else
1715 vs->modifiers_state[keycode] = 0;
1716 break;
1717 case 0x02 ... 0x0a: /* '1' to '9' keys */
1718 if (vs->vd->dcl.con == NULL &&
1719 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1720 /* Reset the modifiers sent to the current console */
1721 reset_keys(vs);
1722 console_select(keycode - 0x02);
1723 return;
1725 break;
1726 case 0x3a: /* CapsLock */
1727 case 0x45: /* NumLock */
1728 if (down)
1729 vs->modifiers_state[keycode] ^= 1;
1730 break;
1733 /* Turn off the lock state sync logic if the client support the led
1734 state extension.
1736 if (down && vs->vd->lock_key_sync &&
1737 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1738 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1739 /* If the numlock state needs to change then simulate an additional
1740 keypress before sending this one. This will happen if the user
1741 toggles numlock away from the VNC window.
1743 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1744 if (!vs->modifiers_state[0x45]) {
1745 trace_vnc_key_sync_numlock(true);
1746 vs->modifiers_state[0x45] = 1;
1747 press_key(vs, 0xff7f);
1749 } else {
1750 if (vs->modifiers_state[0x45]) {
1751 trace_vnc_key_sync_numlock(false);
1752 vs->modifiers_state[0x45] = 0;
1753 press_key(vs, 0xff7f);
1758 if (down && vs->vd->lock_key_sync &&
1759 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1760 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1761 /* If the capslock state needs to change then simulate an additional
1762 keypress before sending this one. This will happen if the user
1763 toggles capslock away from the VNC window.
1765 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1766 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1767 int capslock = !!(vs->modifiers_state[0x3a]);
1768 if (capslock) {
1769 if (uppercase == shift) {
1770 trace_vnc_key_sync_capslock(false);
1771 vs->modifiers_state[0x3a] = 0;
1772 press_key(vs, 0xffe5);
1774 } else {
1775 if (uppercase != shift) {
1776 trace_vnc_key_sync_capslock(true);
1777 vs->modifiers_state[0x3a] = 1;
1778 press_key(vs, 0xffe5);
1783 if (qemu_console_is_graphic(NULL)) {
1784 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1785 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1786 } else {
1787 bool numlock = vs->modifiers_state[0x45];
1788 bool control = (vs->modifiers_state[0x1d] ||
1789 vs->modifiers_state[0x9d]);
1790 /* QEMU console emulation */
1791 if (down) {
1792 switch (keycode) {
1793 case 0x2a: /* Left Shift */
1794 case 0x36: /* Right Shift */
1795 case 0x1d: /* Left CTRL */
1796 case 0x9d: /* Right CTRL */
1797 case 0x38: /* Left ALT */
1798 case 0xb8: /* Right ALT */
1799 break;
1800 case 0xc8:
1801 kbd_put_keysym(QEMU_KEY_UP);
1802 break;
1803 case 0xd0:
1804 kbd_put_keysym(QEMU_KEY_DOWN);
1805 break;
1806 case 0xcb:
1807 kbd_put_keysym(QEMU_KEY_LEFT);
1808 break;
1809 case 0xcd:
1810 kbd_put_keysym(QEMU_KEY_RIGHT);
1811 break;
1812 case 0xd3:
1813 kbd_put_keysym(QEMU_KEY_DELETE);
1814 break;
1815 case 0xc7:
1816 kbd_put_keysym(QEMU_KEY_HOME);
1817 break;
1818 case 0xcf:
1819 kbd_put_keysym(QEMU_KEY_END);
1820 break;
1821 case 0xc9:
1822 kbd_put_keysym(QEMU_KEY_PAGEUP);
1823 break;
1824 case 0xd1:
1825 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1826 break;
1828 case 0x47:
1829 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1830 break;
1831 case 0x48:
1832 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1833 break;
1834 case 0x49:
1835 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1836 break;
1837 case 0x4b:
1838 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1839 break;
1840 case 0x4c:
1841 kbd_put_keysym('5');
1842 break;
1843 case 0x4d:
1844 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1845 break;
1846 case 0x4f:
1847 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1848 break;
1849 case 0x50:
1850 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1851 break;
1852 case 0x51:
1853 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1854 break;
1855 case 0x52:
1856 kbd_put_keysym('0');
1857 break;
1858 case 0x53:
1859 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1860 break;
1862 case 0xb5:
1863 kbd_put_keysym('/');
1864 break;
1865 case 0x37:
1866 kbd_put_keysym('*');
1867 break;
1868 case 0x4a:
1869 kbd_put_keysym('-');
1870 break;
1871 case 0x4e:
1872 kbd_put_keysym('+');
1873 break;
1874 case 0x9c:
1875 kbd_put_keysym('\n');
1876 break;
1878 default:
1879 if (control) {
1880 kbd_put_keysym(sym & 0x1f);
1881 } else {
1882 kbd_put_keysym(sym);
1884 break;
1890 static void vnc_release_modifiers(VncState *vs)
1892 static const int keycodes[] = {
1893 /* shift, control, alt keys, both left & right */
1894 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1896 int i, keycode;
1898 if (!qemu_console_is_graphic(NULL)) {
1899 return;
1901 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1902 keycode = keycodes[i];
1903 if (!vs->modifiers_state[keycode]) {
1904 continue;
1906 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1907 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1911 static const char *code2name(int keycode)
1913 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1916 static void key_event(VncState *vs, int down, uint32_t sym)
1918 int keycode;
1919 int lsym = sym;
1921 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1922 lsym = lsym - 'A' + 'a';
1925 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1926 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1927 do_key_event(vs, down, keycode, sym);
1930 static void ext_key_event(VncState *vs, int down,
1931 uint32_t sym, uint16_t keycode)
1933 /* if the user specifies a keyboard layout, always use it */
1934 if (keyboard_layout) {
1935 key_event(vs, down, sym);
1936 } else {
1937 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1938 do_key_event(vs, down, keycode, sym);
1942 static void framebuffer_update_request(VncState *vs, int incremental,
1943 int x, int y, int w, int h)
1945 vs->need_update = 1;
1947 if (incremental) {
1948 return;
1951 vs->force_update = 1;
1952 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1955 static void send_ext_key_event_ack(VncState *vs)
1957 vnc_lock_output(vs);
1958 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1959 vnc_write_u8(vs, 0);
1960 vnc_write_u16(vs, 1);
1961 vnc_framebuffer_update(vs, 0, 0,
1962 pixman_image_get_width(vs->vd->server),
1963 pixman_image_get_height(vs->vd->server),
1964 VNC_ENCODING_EXT_KEY_EVENT);
1965 vnc_unlock_output(vs);
1966 vnc_flush(vs);
1969 static void send_ext_audio_ack(VncState *vs)
1971 vnc_lock_output(vs);
1972 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1973 vnc_write_u8(vs, 0);
1974 vnc_write_u16(vs, 1);
1975 vnc_framebuffer_update(vs, 0, 0,
1976 pixman_image_get_width(vs->vd->server),
1977 pixman_image_get_height(vs->vd->server),
1978 VNC_ENCODING_AUDIO);
1979 vnc_unlock_output(vs);
1980 vnc_flush(vs);
1983 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1985 int i;
1986 unsigned int enc = 0;
1988 vs->features = 0;
1989 vs->vnc_encoding = 0;
1990 vs->tight.compression = 9;
1991 vs->tight.quality = -1; /* Lossless by default */
1992 vs->absolute = -1;
1995 * Start from the end because the encodings are sent in order of preference.
1996 * This way the preferred encoding (first encoding defined in the array)
1997 * will be set at the end of the loop.
1999 for (i = n_encodings - 1; i >= 0; i--) {
2000 enc = encodings[i];
2001 switch (enc) {
2002 case VNC_ENCODING_RAW:
2003 vs->vnc_encoding = enc;
2004 break;
2005 case VNC_ENCODING_COPYRECT:
2006 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2007 break;
2008 case VNC_ENCODING_HEXTILE:
2009 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2010 vs->vnc_encoding = enc;
2011 break;
2012 case VNC_ENCODING_TIGHT:
2013 vs->features |= VNC_FEATURE_TIGHT_MASK;
2014 vs->vnc_encoding = enc;
2015 break;
2016 #ifdef CONFIG_VNC_PNG
2017 case VNC_ENCODING_TIGHT_PNG:
2018 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2019 vs->vnc_encoding = enc;
2020 break;
2021 #endif
2022 case VNC_ENCODING_ZLIB:
2023 vs->features |= VNC_FEATURE_ZLIB_MASK;
2024 vs->vnc_encoding = enc;
2025 break;
2026 case VNC_ENCODING_ZRLE:
2027 vs->features |= VNC_FEATURE_ZRLE_MASK;
2028 vs->vnc_encoding = enc;
2029 break;
2030 case VNC_ENCODING_ZYWRLE:
2031 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2032 vs->vnc_encoding = enc;
2033 break;
2034 case VNC_ENCODING_DESKTOPRESIZE:
2035 vs->features |= VNC_FEATURE_RESIZE_MASK;
2036 break;
2037 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2038 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2039 break;
2040 case VNC_ENCODING_RICH_CURSOR:
2041 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2042 if (vs->vd->cursor) {
2043 vnc_cursor_define(vs);
2045 break;
2046 case VNC_ENCODING_EXT_KEY_EVENT:
2047 send_ext_key_event_ack(vs);
2048 break;
2049 case VNC_ENCODING_AUDIO:
2050 send_ext_audio_ack(vs);
2051 break;
2052 case VNC_ENCODING_WMVi:
2053 vs->features |= VNC_FEATURE_WMVI_MASK;
2054 break;
2055 case VNC_ENCODING_LED_STATE:
2056 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2057 break;
2058 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2059 vs->tight.compression = (enc & 0x0F);
2060 break;
2061 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2062 if (vs->vd->lossy) {
2063 vs->tight.quality = (enc & 0x0F);
2065 break;
2066 default:
2067 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2068 break;
2071 vnc_desktop_resize(vs);
2072 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2073 vnc_led_state_change(vs);
2076 static void set_pixel_conversion(VncState *vs)
2078 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2080 if (fmt == VNC_SERVER_FB_FORMAT) {
2081 vs->write_pixels = vnc_write_pixels_copy;
2082 vnc_hextile_set_pixel_conversion(vs, 0);
2083 } else {
2084 vs->write_pixels = vnc_write_pixels_generic;
2085 vnc_hextile_set_pixel_conversion(vs, 1);
2089 static void send_color_map(VncState *vs)
2091 int i;
2093 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2094 vnc_write_u8(vs, 0); /* padding */
2095 vnc_write_u16(vs, 0); /* first color */
2096 vnc_write_u16(vs, 256); /* # of colors */
2098 for (i = 0; i < 256; i++) {
2099 PixelFormat *pf = &vs->client_pf;
2101 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2102 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2103 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2107 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2108 int big_endian_flag, int true_color_flag,
2109 int red_max, int green_max, int blue_max,
2110 int red_shift, int green_shift, int blue_shift)
2112 if (!true_color_flag) {
2113 /* Expose a reasonable default 256 color map */
2114 bits_per_pixel = 8;
2115 red_max = 7;
2116 green_max = 7;
2117 blue_max = 3;
2118 red_shift = 0;
2119 green_shift = 3;
2120 blue_shift = 6;
2123 switch (bits_per_pixel) {
2124 case 8:
2125 case 16:
2126 case 32:
2127 break;
2128 default:
2129 vnc_client_error(vs);
2130 return;
2133 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2134 vs->client_pf.rbits = hweight_long(red_max);
2135 vs->client_pf.rshift = red_shift;
2136 vs->client_pf.rmask = red_max << red_shift;
2137 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2138 vs->client_pf.gbits = hweight_long(green_max);
2139 vs->client_pf.gshift = green_shift;
2140 vs->client_pf.gmask = green_max << green_shift;
2141 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2142 vs->client_pf.bbits = hweight_long(blue_max);
2143 vs->client_pf.bshift = blue_shift;
2144 vs->client_pf.bmask = blue_max << blue_shift;
2145 vs->client_pf.bits_per_pixel = bits_per_pixel;
2146 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2147 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2148 vs->client_be = big_endian_flag;
2150 if (!true_color_flag) {
2151 send_color_map(vs);
2154 set_pixel_conversion(vs);
2156 graphic_hw_invalidate(vs->vd->dcl.con);
2157 graphic_hw_update(vs->vd->dcl.con);
2160 static void pixel_format_message (VncState *vs) {
2161 char pad[3] = { 0, 0, 0 };
2163 vs->client_pf = qemu_default_pixelformat(32);
2165 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2166 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2168 #ifdef HOST_WORDS_BIGENDIAN
2169 vnc_write_u8(vs, 1); /* big-endian-flag */
2170 #else
2171 vnc_write_u8(vs, 0); /* big-endian-flag */
2172 #endif
2173 vnc_write_u8(vs, 1); /* true-color-flag */
2174 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2175 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2176 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2177 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2178 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2179 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2180 vnc_write(vs, pad, 3); /* padding */
2182 vnc_hextile_set_pixel_conversion(vs, 0);
2183 vs->write_pixels = vnc_write_pixels_copy;
2186 static void vnc_colordepth(VncState *vs)
2188 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2189 /* Sending a WMVi message to notify the client*/
2190 vnc_lock_output(vs);
2191 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2192 vnc_write_u8(vs, 0);
2193 vnc_write_u16(vs, 1); /* number of rects */
2194 vnc_framebuffer_update(vs, 0, 0,
2195 pixman_image_get_width(vs->vd->server),
2196 pixman_image_get_height(vs->vd->server),
2197 VNC_ENCODING_WMVi);
2198 pixel_format_message(vs);
2199 vnc_unlock_output(vs);
2200 vnc_flush(vs);
2201 } else {
2202 set_pixel_conversion(vs);
2206 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2208 int i;
2209 uint16_t limit;
2210 VncDisplay *vd = vs->vd;
2212 if (data[0] > 3) {
2213 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2216 switch (data[0]) {
2217 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2218 if (len == 1)
2219 return 20;
2221 set_pixel_format(vs, read_u8(data, 4),
2222 read_u8(data, 6), read_u8(data, 7),
2223 read_u16(data, 8), read_u16(data, 10),
2224 read_u16(data, 12), read_u8(data, 14),
2225 read_u8(data, 15), read_u8(data, 16));
2226 break;
2227 case VNC_MSG_CLIENT_SET_ENCODINGS:
2228 if (len == 1)
2229 return 4;
2231 if (len == 4) {
2232 limit = read_u16(data, 2);
2233 if (limit > 0)
2234 return 4 + (limit * 4);
2235 } else
2236 limit = read_u16(data, 2);
2238 for (i = 0; i < limit; i++) {
2239 int32_t val = read_s32(data, 4 + (i * 4));
2240 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2243 set_encodings(vs, (int32_t *)(data + 4), limit);
2244 break;
2245 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2246 if (len == 1)
2247 return 10;
2249 framebuffer_update_request(vs,
2250 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2251 read_u16(data, 6), read_u16(data, 8));
2252 break;
2253 case VNC_MSG_CLIENT_KEY_EVENT:
2254 if (len == 1)
2255 return 8;
2257 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2258 break;
2259 case VNC_MSG_CLIENT_POINTER_EVENT:
2260 if (len == 1)
2261 return 6;
2263 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2264 break;
2265 case VNC_MSG_CLIENT_CUT_TEXT:
2266 if (len == 1) {
2267 return 8;
2269 if (len == 8) {
2270 uint32_t dlen = read_u32(data, 4);
2271 if (dlen > (1 << 20)) {
2272 error_report("vnc: client_cut_text msg payload has %u bytes"
2273 " which exceeds our limit of 1MB.", dlen);
2274 vnc_client_error(vs);
2275 break;
2277 if (dlen > 0) {
2278 return 8 + dlen;
2282 client_cut_text(vs, read_u32(data, 4), data + 8);
2283 break;
2284 case VNC_MSG_CLIENT_QEMU:
2285 if (len == 1)
2286 return 2;
2288 switch (read_u8(data, 1)) {
2289 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2290 if (len == 2)
2291 return 12;
2293 ext_key_event(vs, read_u16(data, 2),
2294 read_u32(data, 4), read_u32(data, 8));
2295 break;
2296 case VNC_MSG_CLIENT_QEMU_AUDIO:
2297 if (len == 2)
2298 return 4;
2300 switch (read_u16 (data, 2)) {
2301 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2302 audio_add(vs);
2303 break;
2304 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2305 audio_del(vs);
2306 break;
2307 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2308 if (len == 4)
2309 return 10;
2310 switch (read_u8(data, 4)) {
2311 case 0: vs->as.fmt = AUD_FMT_U8; break;
2312 case 1: vs->as.fmt = AUD_FMT_S8; break;
2313 case 2: vs->as.fmt = AUD_FMT_U16; break;
2314 case 3: vs->as.fmt = AUD_FMT_S16; break;
2315 case 4: vs->as.fmt = AUD_FMT_U32; break;
2316 case 5: vs->as.fmt = AUD_FMT_S32; break;
2317 default:
2318 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2319 vnc_client_error(vs);
2320 break;
2322 vs->as.nchannels = read_u8(data, 5);
2323 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2324 VNC_DEBUG("Invalid audio channel coount %d\n",
2325 read_u8(data, 5));
2326 vnc_client_error(vs);
2327 break;
2329 vs->as.freq = read_u32(data, 6);
2330 break;
2331 default:
2332 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2333 vnc_client_error(vs);
2334 break;
2336 break;
2338 default:
2339 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2340 vnc_client_error(vs);
2341 break;
2343 break;
2344 default:
2345 VNC_DEBUG("Msg: %d\n", data[0]);
2346 vnc_client_error(vs);
2347 break;
2350 vnc_read_when(vs, protocol_client_msg, 1);
2351 return 0;
2354 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2356 char buf[1024];
2357 VncShareMode mode;
2358 int size;
2360 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2361 switch (vs->vd->share_policy) {
2362 case VNC_SHARE_POLICY_IGNORE:
2364 * Ignore the shared flag. Nothing to do here.
2366 * Doesn't conform to the rfb spec but is traditional qemu
2367 * behavior, thus left here as option for compatibility
2368 * reasons.
2370 break;
2371 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2373 * Policy: Allow clients ask for exclusive access.
2375 * Implementation: When a client asks for exclusive access,
2376 * disconnect all others. Shared connects are allowed as long
2377 * as no exclusive connection exists.
2379 * This is how the rfb spec suggests to handle the shared flag.
2381 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2382 VncState *client;
2383 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2384 if (vs == client) {
2385 continue;
2387 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2388 client->share_mode != VNC_SHARE_MODE_SHARED) {
2389 continue;
2391 vnc_disconnect_start(client);
2394 if (mode == VNC_SHARE_MODE_SHARED) {
2395 if (vs->vd->num_exclusive > 0) {
2396 vnc_disconnect_start(vs);
2397 return 0;
2400 break;
2401 case VNC_SHARE_POLICY_FORCE_SHARED:
2403 * Policy: Shared connects only.
2404 * Implementation: Disallow clients asking for exclusive access.
2406 * Useful for shared desktop sessions where you don't want
2407 * someone forgetting to say -shared when running the vnc
2408 * client disconnect everybody else.
2410 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2411 vnc_disconnect_start(vs);
2412 return 0;
2414 break;
2416 vnc_set_share_mode(vs, mode);
2418 if (vs->vd->num_shared > vs->vd->connections_limit) {
2419 vnc_disconnect_start(vs);
2420 return 0;
2423 vs->client_width = pixman_image_get_width(vs->vd->server);
2424 vs->client_height = pixman_image_get_height(vs->vd->server);
2425 vnc_write_u16(vs, vs->client_width);
2426 vnc_write_u16(vs, vs->client_height);
2428 pixel_format_message(vs);
2430 if (qemu_name) {
2431 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2432 if (size > sizeof(buf)) {
2433 size = sizeof(buf);
2435 } else {
2436 size = snprintf(buf, sizeof(buf), "QEMU");
2439 vnc_write_u32(vs, size);
2440 vnc_write(vs, buf, size);
2441 vnc_flush(vs);
2443 vnc_client_cache_auth(vs);
2444 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2446 vnc_read_when(vs, protocol_client_msg, 1);
2448 return 0;
2451 void start_client_init(VncState *vs)
2453 vnc_read_when(vs, protocol_client_init, 1);
2456 static void make_challenge(VncState *vs)
2458 int i;
2460 srand(time(NULL)+getpid()+getpid()*987654+rand());
2462 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2463 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2466 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2468 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2469 size_t i, pwlen;
2470 unsigned char key[8];
2471 time_t now = time(NULL);
2472 QCryptoCipher *cipher = NULL;
2473 Error *err = NULL;
2475 if (!vs->vd->password) {
2476 VNC_DEBUG("No password configured on server");
2477 goto reject;
2479 if (vs->vd->expires < now) {
2480 VNC_DEBUG("Password is expired");
2481 goto reject;
2484 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2486 /* Calculate the expected challenge response */
2487 pwlen = strlen(vs->vd->password);
2488 for (i=0; i<sizeof(key); i++)
2489 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2491 cipher = qcrypto_cipher_new(
2492 QCRYPTO_CIPHER_ALG_DES_RFB,
2493 QCRYPTO_CIPHER_MODE_ECB,
2494 key, G_N_ELEMENTS(key),
2495 &err);
2496 if (!cipher) {
2497 VNC_DEBUG("Cannot initialize cipher %s",
2498 error_get_pretty(err));
2499 error_free(err);
2500 goto reject;
2503 if (qcrypto_cipher_encrypt(cipher,
2504 vs->challenge,
2505 response,
2506 VNC_AUTH_CHALLENGE_SIZE,
2507 &err) < 0) {
2508 VNC_DEBUG("Cannot encrypt challenge %s",
2509 error_get_pretty(err));
2510 error_free(err);
2511 goto reject;
2514 /* Compare expected vs actual challenge response */
2515 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2516 VNC_DEBUG("Client challenge response did not match\n");
2517 goto reject;
2518 } else {
2519 VNC_DEBUG("Accepting VNC challenge response\n");
2520 vnc_write_u32(vs, 0); /* Accept auth */
2521 vnc_flush(vs);
2523 start_client_init(vs);
2526 qcrypto_cipher_free(cipher);
2527 return 0;
2529 reject:
2530 vnc_write_u32(vs, 1); /* Reject auth */
2531 if (vs->minor >= 8) {
2532 static const char err[] = "Authentication failed";
2533 vnc_write_u32(vs, sizeof(err));
2534 vnc_write(vs, err, sizeof(err));
2536 vnc_flush(vs);
2537 vnc_client_error(vs);
2538 qcrypto_cipher_free(cipher);
2539 return 0;
2542 void start_auth_vnc(VncState *vs)
2544 make_challenge(vs);
2545 /* Send client a 'random' challenge */
2546 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2547 vnc_flush(vs);
2549 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2553 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2555 /* We only advertise 1 auth scheme at a time, so client
2556 * must pick the one we sent. Verify this */
2557 if (data[0] != vs->auth) { /* Reject auth */
2558 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2559 vnc_write_u32(vs, 1);
2560 if (vs->minor >= 8) {
2561 static const char err[] = "Authentication failed";
2562 vnc_write_u32(vs, sizeof(err));
2563 vnc_write(vs, err, sizeof(err));
2565 vnc_client_error(vs);
2566 } else { /* Accept requested auth */
2567 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2568 switch (vs->auth) {
2569 case VNC_AUTH_NONE:
2570 VNC_DEBUG("Accept auth none\n");
2571 if (vs->minor >= 8) {
2572 vnc_write_u32(vs, 0); /* Accept auth completion */
2573 vnc_flush(vs);
2575 start_client_init(vs);
2576 break;
2578 case VNC_AUTH_VNC:
2579 VNC_DEBUG("Start VNC auth\n");
2580 start_auth_vnc(vs);
2581 break;
2583 case VNC_AUTH_VENCRYPT:
2584 VNC_DEBUG("Accept VeNCrypt auth\n");
2585 start_auth_vencrypt(vs);
2586 break;
2588 #ifdef CONFIG_VNC_SASL
2589 case VNC_AUTH_SASL:
2590 VNC_DEBUG("Accept SASL auth\n");
2591 start_auth_sasl(vs);
2592 break;
2593 #endif /* CONFIG_VNC_SASL */
2595 default: /* Should not be possible, but just in case */
2596 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2597 vnc_write_u8(vs, 1);
2598 if (vs->minor >= 8) {
2599 static const char err[] = "Authentication failed";
2600 vnc_write_u32(vs, sizeof(err));
2601 vnc_write(vs, err, sizeof(err));
2603 vnc_client_error(vs);
2606 return 0;
2609 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2611 char local[13];
2613 memcpy(local, version, 12);
2614 local[12] = 0;
2616 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2617 VNC_DEBUG("Malformed protocol version %s\n", local);
2618 vnc_client_error(vs);
2619 return 0;
2621 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2622 if (vs->major != 3 ||
2623 (vs->minor != 3 &&
2624 vs->minor != 4 &&
2625 vs->minor != 5 &&
2626 vs->minor != 7 &&
2627 vs->minor != 8)) {
2628 VNC_DEBUG("Unsupported client version\n");
2629 vnc_write_u32(vs, VNC_AUTH_INVALID);
2630 vnc_flush(vs);
2631 vnc_client_error(vs);
2632 return 0;
2634 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2635 * as equivalent to v3.3 by servers
2637 if (vs->minor == 4 || vs->minor == 5)
2638 vs->minor = 3;
2640 if (vs->minor == 3) {
2641 if (vs->auth == VNC_AUTH_NONE) {
2642 VNC_DEBUG("Tell client auth none\n");
2643 vnc_write_u32(vs, vs->auth);
2644 vnc_flush(vs);
2645 start_client_init(vs);
2646 } else if (vs->auth == VNC_AUTH_VNC) {
2647 VNC_DEBUG("Tell client VNC auth\n");
2648 vnc_write_u32(vs, vs->auth);
2649 vnc_flush(vs);
2650 start_auth_vnc(vs);
2651 } else {
2652 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2653 vnc_write_u32(vs, VNC_AUTH_INVALID);
2654 vnc_flush(vs);
2655 vnc_client_error(vs);
2657 } else {
2658 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2659 vnc_write_u8(vs, 1); /* num auth */
2660 vnc_write_u8(vs, vs->auth);
2661 vnc_read_when(vs, protocol_client_auth, 1);
2662 vnc_flush(vs);
2665 return 0;
2668 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2670 struct VncSurface *vs = &vd->guest;
2672 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2675 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2677 int i, j;
2679 w = (x + w) / VNC_STAT_RECT;
2680 h = (y + h) / VNC_STAT_RECT;
2681 x /= VNC_STAT_RECT;
2682 y /= VNC_STAT_RECT;
2684 for (j = y; j <= h; j++) {
2685 for (i = x; i <= w; i++) {
2686 vs->lossy_rect[j][i] = 1;
2691 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2693 VncState *vs;
2694 int sty = y / VNC_STAT_RECT;
2695 int stx = x / VNC_STAT_RECT;
2696 int has_dirty = 0;
2698 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2699 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2701 QTAILQ_FOREACH(vs, &vd->clients, next) {
2702 int j;
2704 /* kernel send buffers are full -> refresh later */
2705 if (vs->output.offset) {
2706 continue;
2709 if (!vs->lossy_rect[sty][stx]) {
2710 continue;
2713 vs->lossy_rect[sty][stx] = 0;
2714 for (j = 0; j < VNC_STAT_RECT; ++j) {
2715 bitmap_set(vs->dirty[y + j],
2716 x / VNC_DIRTY_PIXELS_PER_BIT,
2717 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2719 has_dirty++;
2722 return has_dirty;
2725 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2727 int width = MIN(pixman_image_get_width(vd->guest.fb),
2728 pixman_image_get_width(vd->server));
2729 int height = MIN(pixman_image_get_height(vd->guest.fb),
2730 pixman_image_get_height(vd->server));
2731 int x, y;
2732 struct timeval res;
2733 int has_dirty = 0;
2735 for (y = 0; y < height; y += VNC_STAT_RECT) {
2736 for (x = 0; x < width; x += VNC_STAT_RECT) {
2737 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2739 rect->updated = false;
2743 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2745 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2746 return has_dirty;
2748 vd->guest.last_freq_check = *tv;
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);
2753 int count = ARRAY_SIZE(rect->times);
2754 struct timeval min, max;
2756 if (!timerisset(&rect->times[count - 1])) {
2757 continue ;
2760 max = rect->times[(rect->idx + count - 1) % count];
2761 qemu_timersub(tv, &max, &res);
2763 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2764 rect->freq = 0;
2765 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2766 memset(rect->times, 0, sizeof (rect->times));
2767 continue ;
2770 min = rect->times[rect->idx];
2771 max = rect->times[(rect->idx + count - 1) % count];
2772 qemu_timersub(&max, &min, &res);
2774 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2775 rect->freq /= count;
2776 rect->freq = 1. / rect->freq;
2779 return has_dirty;
2782 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2784 int i, j;
2785 double total = 0;
2786 int num = 0;
2788 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2789 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2791 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2792 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2793 total += vnc_stat_rect(vs->vd, i, j)->freq;
2794 num++;
2798 if (num) {
2799 return total / num;
2800 } else {
2801 return 0;
2805 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2807 VncRectStat *rect;
2809 rect = vnc_stat_rect(vd, x, y);
2810 if (rect->updated) {
2811 return ;
2813 rect->times[rect->idx] = *tv;
2814 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2815 rect->updated = true;
2818 static int vnc_refresh_server_surface(VncDisplay *vd)
2820 int width = MIN(pixman_image_get_width(vd->guest.fb),
2821 pixman_image_get_width(vd->server));
2822 int height = MIN(pixman_image_get_height(vd->guest.fb),
2823 pixman_image_get_height(vd->server));
2824 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2825 uint8_t *guest_row0 = NULL, *server_row0;
2826 VncState *vs;
2827 int has_dirty = 0;
2828 pixman_image_t *tmpbuf = NULL;
2830 struct timeval tv = { 0, 0 };
2832 if (!vd->non_adaptive) {
2833 gettimeofday(&tv, NULL);
2834 has_dirty = vnc_update_stats(vd, &tv);
2838 * Walk through the guest dirty map.
2839 * Check and copy modified bits from guest to server surface.
2840 * Update server dirty map.
2842 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2843 server_stride = guest_stride = guest_ll =
2844 pixman_image_get_stride(vd->server);
2845 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2846 server_stride);
2847 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2848 int width = pixman_image_get_width(vd->server);
2849 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2850 } else {
2851 int guest_bpp =
2852 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2853 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2854 guest_stride = pixman_image_get_stride(vd->guest.fb);
2855 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2857 line_bytes = MIN(server_stride, guest_ll);
2859 for (;;) {
2860 int x;
2861 uint8_t *guest_ptr, *server_ptr;
2862 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2863 height * VNC_DIRTY_BPL(&vd->guest),
2864 y * VNC_DIRTY_BPL(&vd->guest));
2865 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2866 /* no more dirty bits */
2867 break;
2869 y = offset / VNC_DIRTY_BPL(&vd->guest);
2870 x = offset % VNC_DIRTY_BPL(&vd->guest);
2872 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2874 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2875 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2876 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2877 } else {
2878 guest_ptr = guest_row0 + y * guest_stride;
2880 guest_ptr += x * cmp_bytes;
2882 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2883 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2884 int _cmp_bytes = cmp_bytes;
2885 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2886 continue;
2888 if ((x + 1) * cmp_bytes > line_bytes) {
2889 _cmp_bytes = line_bytes - x * cmp_bytes;
2891 assert(_cmp_bytes >= 0);
2892 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2893 continue;
2895 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2896 if (!vd->non_adaptive) {
2897 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2898 y, &tv);
2900 QTAILQ_FOREACH(vs, &vd->clients, next) {
2901 set_bit(x, vs->dirty[y]);
2903 has_dirty++;
2906 y++;
2908 qemu_pixman_image_unref(tmpbuf);
2909 return has_dirty;
2912 static void vnc_refresh(DisplayChangeListener *dcl)
2914 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2915 VncState *vs, *vn;
2916 int has_dirty, rects = 0;
2918 if (QTAILQ_EMPTY(&vd->clients)) {
2919 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2920 return;
2923 graphic_hw_update(vd->dcl.con);
2925 if (vnc_trylock_display(vd)) {
2926 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2927 return;
2930 has_dirty = vnc_refresh_server_surface(vd);
2931 vnc_unlock_display(vd);
2933 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2934 rects += vnc_update_client(vs, has_dirty, false);
2935 /* vs might be free()ed here */
2938 if (has_dirty && rects) {
2939 vd->dcl.update_interval /= 2;
2940 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2941 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2943 } else {
2944 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2945 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2946 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2951 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2952 bool skipauth, bool websocket)
2954 VncState *vs = g_new0(VncState, 1);
2955 bool first_client = QTAILQ_EMPTY(&vd->clients);
2956 int i;
2958 vs->sioc = sioc;
2959 object_ref(OBJECT(vs->sioc));
2960 vs->ioc = QIO_CHANNEL(sioc);
2961 object_ref(OBJECT(vs->ioc));
2962 vs->vd = vd;
2964 buffer_init(&vs->input, "vnc-input/%p", sioc);
2965 buffer_init(&vs->output, "vnc-output/%p", sioc);
2966 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2968 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2969 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2970 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2971 #ifdef CONFIG_VNC_JPEG
2972 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2973 #endif
2974 #ifdef CONFIG_VNC_PNG
2975 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2976 #endif
2977 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2978 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2979 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2980 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2982 if (skipauth) {
2983 vs->auth = VNC_AUTH_NONE;
2984 vs->subauth = VNC_AUTH_INVALID;
2985 } else {
2986 if (websocket) {
2987 vs->auth = vd->ws_auth;
2988 vs->subauth = VNC_AUTH_INVALID;
2989 } else {
2990 vs->auth = vd->auth;
2991 vs->subauth = vd->subauth;
2994 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2995 sioc, websocket, vs->auth, vs->subauth);
2997 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
2998 for (i = 0; i < VNC_STAT_ROWS; ++i) {
2999 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3002 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3003 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3004 qio_channel_set_blocking(vs->ioc, false, NULL);
3005 if (websocket) {
3006 vs->websocket = 1;
3007 if (vd->tlscreds) {
3008 vs->ioc_tag = qio_channel_add_watch(
3009 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3010 } else {
3011 vs->ioc_tag = qio_channel_add_watch(
3012 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
3014 } else {
3015 vs->ioc_tag = qio_channel_add_watch(
3016 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
3019 vnc_client_cache_addr(vs);
3020 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3021 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3023 vs->last_x = -1;
3024 vs->last_y = -1;
3026 vs->as.freq = 44100;
3027 vs->as.nchannels = 2;
3028 vs->as.fmt = AUD_FMT_S16;
3029 vs->as.endianness = 0;
3031 qemu_mutex_init(&vs->output_mutex);
3032 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3034 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3035 if (first_client) {
3036 vnc_update_server_surface(vd);
3039 graphic_hw_update(vd->dcl.con);
3041 if (!vs->websocket) {
3042 vnc_start_protocol(vs);
3045 if (vd->num_connecting > vd->connections_limit) {
3046 QTAILQ_FOREACH(vs, &vd->clients, next) {
3047 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3048 vnc_disconnect_start(vs);
3049 return;
3055 void vnc_start_protocol(VncState *vs)
3057 vnc_write(vs, "RFB 003.008\n", 12);
3058 vnc_flush(vs);
3059 vnc_read_when(vs, protocol_version, 12);
3061 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3062 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3065 static gboolean vnc_listen_io(QIOChannel *ioc,
3066 GIOCondition condition,
3067 void *opaque)
3069 VncDisplay *vd = opaque;
3070 QIOChannelSocket *sioc = NULL;
3071 Error *err = NULL;
3073 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3074 if (sioc != NULL) {
3075 qio_channel_set_name(QIO_CHANNEL(sioc),
3076 ioc != QIO_CHANNEL(vd->lsock) ?
3077 "vnc-ws-server" : "vnc-server");
3078 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3079 vnc_connect(vd, sioc, false,
3080 ioc != QIO_CHANNEL(vd->lsock));
3081 object_unref(OBJECT(sioc));
3082 } else {
3083 /* client probably closed connection before we got there */
3084 error_free(err);
3087 return TRUE;
3090 static const DisplayChangeListenerOps dcl_ops = {
3091 .dpy_name = "vnc",
3092 .dpy_refresh = vnc_refresh,
3093 .dpy_gfx_copy = vnc_dpy_copy,
3094 .dpy_gfx_update = vnc_dpy_update,
3095 .dpy_gfx_switch = vnc_dpy_switch,
3096 .dpy_gfx_check_format = qemu_pixman_check_format,
3097 .dpy_mouse_set = vnc_mouse_set,
3098 .dpy_cursor_define = vnc_dpy_cursor_define,
3101 void vnc_display_init(const char *id)
3103 VncDisplay *vd;
3105 if (vnc_display_find(id) != NULL) {
3106 return;
3108 vd = g_malloc0(sizeof(*vd));
3110 vd->id = strdup(id);
3111 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3113 QTAILQ_INIT(&vd->clients);
3114 vd->expires = TIME_MAX;
3116 if (keyboard_layout) {
3117 trace_vnc_key_map_init(keyboard_layout);
3118 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3119 } else {
3120 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3123 if (!vd->kbd_layout) {
3124 exit(1);
3127 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3128 vd->connections_limit = 32;
3130 qemu_mutex_init(&vd->mutex);
3131 vnc_start_worker_thread();
3133 vd->dcl.ops = &dcl_ops;
3134 register_displaychangelistener(&vd->dcl);
3138 static void vnc_display_close(VncDisplay *vd)
3140 if (!vd) {
3141 return;
3143 vd->is_unix = false;
3144 if (vd->lsock != NULL) {
3145 if (vd->lsock_tag) {
3146 g_source_remove(vd->lsock_tag);
3148 object_unref(OBJECT(vd->lsock));
3149 vd->lsock = NULL;
3151 if (vd->lwebsock != NULL) {
3152 if (vd->lwebsock_tag) {
3153 g_source_remove(vd->lwebsock_tag);
3155 object_unref(OBJECT(vd->lwebsock));
3156 vd->lwebsock = NULL;
3158 vd->auth = VNC_AUTH_INVALID;
3159 vd->subauth = VNC_AUTH_INVALID;
3160 if (vd->tlscreds) {
3161 object_unparent(OBJECT(vd->tlscreds));
3162 vd->tlscreds = NULL;
3164 g_free(vd->tlsaclname);
3165 vd->tlsaclname = NULL;
3166 if (vd->lock_key_sync) {
3167 qemu_remove_led_event_handler(vd->led);
3171 int vnc_display_password(const char *id, const char *password)
3173 VncDisplay *vd = vnc_display_find(id);
3175 if (!vd) {
3176 return -EINVAL;
3178 if (vd->auth == VNC_AUTH_NONE) {
3179 error_printf_unless_qmp("If you want use passwords please enable "
3180 "password auth using '-vnc ${dpy},password'.\n");
3181 return -EINVAL;
3184 g_free(vd->password);
3185 vd->password = g_strdup(password);
3187 return 0;
3190 int vnc_display_pw_expire(const char *id, time_t expires)
3192 VncDisplay *vd = vnc_display_find(id);
3194 if (!vd) {
3195 return -EINVAL;
3198 vd->expires = expires;
3199 return 0;
3202 static void vnc_display_print_local_addr(VncDisplay *vd)
3204 SocketAddress *addr;
3205 Error *err = NULL;
3207 addr = qio_channel_socket_get_local_address(vd->lsock, &err);
3208 if (!addr) {
3209 return;
3212 if (addr->type != SOCKET_ADDRESS_KIND_INET) {
3213 qapi_free_SocketAddress(addr);
3214 return;
3216 error_printf_unless_qmp("VNC server running on %s:%s\n",
3217 addr->u.inet.data->host,
3218 addr->u.inet.data->port);
3219 qapi_free_SocketAddress(addr);
3222 static QemuOptsList qemu_vnc_opts = {
3223 .name = "vnc",
3224 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3225 .implied_opt_name = "vnc",
3226 .desc = {
3228 .name = "vnc",
3229 .type = QEMU_OPT_STRING,
3231 .name = "websocket",
3232 .type = QEMU_OPT_STRING,
3234 .name = "tls-creds",
3235 .type = QEMU_OPT_STRING,
3237 /* Deprecated in favour of tls-creds */
3238 .name = "x509",
3239 .type = QEMU_OPT_STRING,
3241 .name = "share",
3242 .type = QEMU_OPT_STRING,
3244 .name = "display",
3245 .type = QEMU_OPT_STRING,
3247 .name = "head",
3248 .type = QEMU_OPT_NUMBER,
3250 .name = "connections",
3251 .type = QEMU_OPT_NUMBER,
3253 .name = "to",
3254 .type = QEMU_OPT_NUMBER,
3256 .name = "ipv4",
3257 .type = QEMU_OPT_BOOL,
3259 .name = "ipv6",
3260 .type = QEMU_OPT_BOOL,
3262 .name = "password",
3263 .type = QEMU_OPT_BOOL,
3265 .name = "reverse",
3266 .type = QEMU_OPT_BOOL,
3268 .name = "lock-key-sync",
3269 .type = QEMU_OPT_BOOL,
3271 .name = "key-delay-ms",
3272 .type = QEMU_OPT_NUMBER,
3274 .name = "sasl",
3275 .type = QEMU_OPT_BOOL,
3277 /* Deprecated in favour of tls-creds */
3278 .name = "tls",
3279 .type = QEMU_OPT_BOOL,
3281 /* Deprecated in favour of tls-creds */
3282 .name = "x509verify",
3283 .type = QEMU_OPT_STRING,
3285 .name = "acl",
3286 .type = QEMU_OPT_BOOL,
3288 .name = "lossy",
3289 .type = QEMU_OPT_BOOL,
3291 .name = "non-adaptive",
3292 .type = QEMU_OPT_BOOL,
3294 { /* end of list */ }
3299 static int
3300 vnc_display_setup_auth(int *auth,
3301 int *subauth,
3302 QCryptoTLSCreds *tlscreds,
3303 bool password,
3304 bool sasl,
3305 bool websocket,
3306 Error **errp)
3309 * We have a choice of 3 authentication options
3311 * 1. none
3312 * 2. vnc
3313 * 3. sasl
3315 * The channel can be run in 2 modes
3317 * 1. clear
3318 * 2. tls
3320 * And TLS can use 2 types of credentials
3322 * 1. anon
3323 * 2. x509
3325 * We thus have 9 possible logical combinations
3327 * 1. clear + none
3328 * 2. clear + vnc
3329 * 3. clear + sasl
3330 * 4. tls + anon + none
3331 * 5. tls + anon + vnc
3332 * 6. tls + anon + sasl
3333 * 7. tls + x509 + none
3334 * 8. tls + x509 + vnc
3335 * 9. tls + x509 + sasl
3337 * These need to be mapped into the VNC auth schemes
3338 * in an appropriate manner. In regular VNC, all the
3339 * TLS options get mapped into VNC_AUTH_VENCRYPT
3340 * sub-auth types.
3342 * In websockets, the https:// protocol already provides
3343 * TLS support, so there is no need to make use of the
3344 * VeNCrypt extension. Furthermore, websockets browser
3345 * clients could not use VeNCrypt even if they wanted to,
3346 * as they cannot control when the TLS handshake takes
3347 * place. Thus there is no option but to rely on https://,
3348 * meaning combinations 4->6 and 7->9 will be mapped to
3349 * VNC auth schemes in the same way as combos 1->3.
3351 * Regardless of fact that we have a different mapping to
3352 * VNC auth mechs for plain VNC vs websockets VNC, the end
3353 * result has the same security characteristics.
3355 if (websocket || !tlscreds) {
3356 if (password) {
3357 VNC_DEBUG("Initializing VNC server with password auth\n");
3358 *auth = VNC_AUTH_VNC;
3359 } else if (sasl) {
3360 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3361 *auth = VNC_AUTH_SASL;
3362 } else {
3363 VNC_DEBUG("Initializing VNC server with no auth\n");
3364 *auth = VNC_AUTH_NONE;
3366 *subauth = VNC_AUTH_INVALID;
3367 } else {
3368 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3369 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3370 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3371 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3373 if (!is_x509 && !is_anon) {
3374 error_setg(errp,
3375 "Unsupported TLS cred type %s",
3376 object_get_typename(OBJECT(tlscreds)));
3377 return -1;
3379 *auth = VNC_AUTH_VENCRYPT;
3380 if (password) {
3381 if (is_x509) {
3382 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3383 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3384 } else {
3385 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3386 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3389 } else if (sasl) {
3390 if (is_x509) {
3391 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3392 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3393 } else {
3394 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3395 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3397 } else {
3398 if (is_x509) {
3399 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3400 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3401 } else {
3402 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3403 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3407 return 0;
3412 * Handle back compat with old CLI syntax by creating some
3413 * suitable QCryptoTLSCreds objects
3415 static QCryptoTLSCreds *
3416 vnc_display_create_creds(bool x509,
3417 bool x509verify,
3418 const char *dir,
3419 const char *id,
3420 Error **errp)
3422 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3423 Object *parent = object_get_objects_root();
3424 Object *creds;
3425 Error *err = NULL;
3427 if (x509) {
3428 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3429 parent,
3430 credsid,
3431 &err,
3432 "endpoint", "server",
3433 "dir", dir,
3434 "verify-peer", x509verify ? "yes" : "no",
3435 NULL);
3436 } else {
3437 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3438 parent,
3439 credsid,
3440 &err,
3441 "endpoint", "server",
3442 NULL);
3445 g_free(credsid);
3447 if (err) {
3448 error_propagate(errp, err);
3449 return NULL;
3452 return QCRYPTO_TLS_CREDS(creds);
3456 void vnc_display_open(const char *id, Error **errp)
3458 VncDisplay *vd = vnc_display_find(id);
3459 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3460 SocketAddress *saddr = NULL, *wsaddr = NULL;
3461 const char *share, *device_id;
3462 QemuConsole *con;
3463 bool password = false;
3464 bool reverse = false;
3465 const char *vnc;
3466 char *h;
3467 const char *credid;
3468 int show_vnc_port = 0;
3469 bool sasl = false;
3470 #ifdef CONFIG_VNC_SASL
3471 int saslErr;
3472 #endif
3473 int acl = 0;
3474 int lock_key_sync = 1;
3475 int key_delay_ms;
3476 bool ws_enabled = false;
3478 if (!vd) {
3479 error_setg(errp, "VNC display not active");
3480 return;
3482 vnc_display_close(vd);
3484 if (!opts) {
3485 return;
3487 vnc = qemu_opt_get(opts, "vnc");
3488 if (!vnc || strcmp(vnc, "none") == 0) {
3489 return;
3492 h = strrchr(vnc, ':');
3493 if (h) {
3494 size_t hlen = h - vnc;
3496 const char *websocket = qemu_opt_get(opts, "websocket");
3497 int to = qemu_opt_get_number(opts, "to", 0);
3498 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3499 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3500 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3501 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3503 saddr = g_new0(SocketAddress, 1);
3504 if (websocket) {
3505 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3506 error_setg(errp,
3507 "SHA1 hash support is required for websockets");
3508 goto fail;
3511 wsaddr = g_new0(SocketAddress, 1);
3512 ws_enabled = true;
3515 if (strncmp(vnc, "unix:", 5) == 0) {
3516 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3517 saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
3518 saddr->u.q_unix.data->path = g_strdup(vnc + 5);
3520 if (ws_enabled) {
3521 error_setg(errp, "UNIX sockets not supported with websock");
3522 goto fail;
3524 } else {
3525 unsigned long long baseport;
3526 InetSocketAddress *inet;
3527 saddr->type = SOCKET_ADDRESS_KIND_INET;
3528 inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
3529 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3530 inet->host = g_strndup(vnc + 1, hlen - 2);
3531 } else {
3532 inet->host = g_strndup(vnc, hlen);
3534 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3535 error_setg(errp, "can't convert to a number: %s", h + 1);
3536 goto fail;
3538 if (baseport > 65535 ||
3539 baseport + 5900 > 65535) {
3540 error_setg(errp, "port %s out of range", h + 1);
3541 goto fail;
3543 inet->port = g_strdup_printf(
3544 "%d", (int)baseport + 5900);
3546 if (to) {
3547 inet->has_to = true;
3548 inet->to = to + 5900;
3549 show_vnc_port = 1;
3551 inet->ipv4 = ipv4;
3552 inet->has_ipv4 = has_ipv4;
3553 inet->ipv6 = ipv6;
3554 inet->has_ipv6 = has_ipv6;
3556 if (ws_enabled) {
3557 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3558 inet = wsaddr->u.inet.data = g_new0(InetSocketAddress, 1);
3559 inet->host = g_strdup(saddr->u.inet.data->host);
3560 inet->port = g_strdup(websocket);
3562 if (to) {
3563 inet->has_to = true;
3564 inet->to = to;
3566 inet->ipv4 = ipv4;
3567 inet->has_ipv4 = has_ipv4;
3568 inet->ipv6 = ipv6;
3569 inet->has_ipv6 = has_ipv6;
3572 } else {
3573 error_setg(errp, "no vnc port specified");
3574 goto fail;
3577 password = qemu_opt_get_bool(opts, "password", false);
3578 if (password) {
3579 if (fips_get_state()) {
3580 error_setg(errp,
3581 "VNC password auth disabled due to FIPS mode, "
3582 "consider using the VeNCrypt or SASL authentication "
3583 "methods as an alternative");
3584 goto fail;
3586 if (!qcrypto_cipher_supports(
3587 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3588 error_setg(errp,
3589 "Cipher backend does not support DES RFB algorithm");
3590 goto fail;
3594 reverse = qemu_opt_get_bool(opts, "reverse", false);
3595 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3596 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
3597 sasl = qemu_opt_get_bool(opts, "sasl", false);
3598 #ifndef CONFIG_VNC_SASL
3599 if (sasl) {
3600 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3601 goto fail;
3603 #endif /* CONFIG_VNC_SASL */
3604 credid = qemu_opt_get(opts, "tls-creds");
3605 if (credid) {
3606 Object *creds;
3607 if (qemu_opt_get(opts, "tls") ||
3608 qemu_opt_get(opts, "x509") ||
3609 qemu_opt_get(opts, "x509verify")) {
3610 error_setg(errp,
3611 "'tls-creds' parameter is mutually exclusive with "
3612 "'tls', 'x509' and 'x509verify' parameters");
3613 goto fail;
3616 creds = object_resolve_path_component(
3617 object_get_objects_root(), credid);
3618 if (!creds) {
3619 error_setg(errp, "No TLS credentials with id '%s'",
3620 credid);
3621 goto fail;
3623 vd->tlscreds = (QCryptoTLSCreds *)
3624 object_dynamic_cast(creds,
3625 TYPE_QCRYPTO_TLS_CREDS);
3626 if (!vd->tlscreds) {
3627 error_setg(errp, "Object with id '%s' is not TLS credentials",
3628 credid);
3629 goto fail;
3631 object_ref(OBJECT(vd->tlscreds));
3633 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3634 error_setg(errp,
3635 "Expecting TLS credentials with a server endpoint");
3636 goto fail;
3638 } else {
3639 const char *path;
3640 bool tls = false, x509 = false, x509verify = false;
3641 tls = qemu_opt_get_bool(opts, "tls", false);
3642 if (tls) {
3643 path = qemu_opt_get(opts, "x509");
3645 if (path) {
3646 x509 = true;
3647 } else {
3648 path = qemu_opt_get(opts, "x509verify");
3649 if (path) {
3650 x509 = true;
3651 x509verify = true;
3654 vd->tlscreds = vnc_display_create_creds(x509,
3655 x509verify,
3656 path,
3657 vd->id,
3658 errp);
3659 if (!vd->tlscreds) {
3660 goto fail;
3664 acl = qemu_opt_get_bool(opts, "acl", false);
3666 share = qemu_opt_get(opts, "share");
3667 if (share) {
3668 if (strcmp(share, "ignore") == 0) {
3669 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
3670 } else if (strcmp(share, "allow-exclusive") == 0) {
3671 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3672 } else if (strcmp(share, "force-shared") == 0) {
3673 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3674 } else {
3675 error_setg(errp, "unknown vnc share= option");
3676 goto fail;
3678 } else {
3679 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3681 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3683 #ifdef CONFIG_VNC_JPEG
3684 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
3685 #endif
3686 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3687 /* adaptive updates are only used with tight encoding and
3688 * if lossy updates are enabled so we can disable all the
3689 * calculations otherwise */
3690 if (!vd->lossy) {
3691 vd->non_adaptive = true;
3694 if (acl) {
3695 if (strcmp(vd->id, "default") == 0) {
3696 vd->tlsaclname = g_strdup("vnc.x509dname");
3697 } else {
3698 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
3700 qemu_acl_init(vd->tlsaclname);
3702 #ifdef CONFIG_VNC_SASL
3703 if (acl && sasl) {
3704 char *aclname;
3706 if (strcmp(vd->id, "default") == 0) {
3707 aclname = g_strdup("vnc.username");
3708 } else {
3709 aclname = g_strdup_printf("vnc.%s.username", vd->id);
3711 vd->sasl.acl = qemu_acl_init(aclname);
3712 g_free(aclname);
3714 #endif
3716 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
3717 vd->tlscreds, password,
3718 sasl, false, errp) < 0) {
3719 goto fail;
3722 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
3723 vd->tlscreds, password,
3724 sasl, true, errp) < 0) {
3725 goto fail;
3728 #ifdef CONFIG_VNC_SASL
3729 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3730 error_setg(errp, "Failed to initialize SASL auth: %s",
3731 sasl_errstring(saslErr, NULL, NULL));
3732 goto fail;
3734 #endif
3735 vd->lock_key_sync = lock_key_sync;
3736 if (lock_key_sync) {
3737 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
3739 vd->ledstate = 0;
3740 vd->key_delay_ms = key_delay_ms;
3742 device_id = qemu_opt_get(opts, "display");
3743 if (device_id) {
3744 int head = qemu_opt_get_number(opts, "head", 0);
3745 Error *err = NULL;
3747 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3748 if (err) {
3749 error_propagate(errp, err);
3750 goto fail;
3752 } else {
3753 con = NULL;
3756 if (con != vd->dcl.con) {
3757 unregister_displaychangelistener(&vd->dcl);
3758 vd->dcl.con = con;
3759 register_displaychangelistener(&vd->dcl);
3762 if (reverse) {
3763 /* connect to viewer */
3764 QIOChannelSocket *sioc = NULL;
3765 vd->lsock = NULL;
3766 vd->lwebsock = NULL;
3767 if (ws_enabled) {
3768 error_setg(errp, "Cannot use websockets in reverse mode");
3769 goto fail;
3771 vd->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3772 sioc = qio_channel_socket_new();
3773 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3774 if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
3775 goto fail;
3777 vnc_connect(vd, sioc, false, false);
3778 object_unref(OBJECT(sioc));
3779 } else {
3780 vd->lsock = qio_channel_socket_new();
3781 qio_channel_set_name(QIO_CHANNEL(vd->lsock), "vnc-listen");
3782 if (qio_channel_socket_listen_sync(vd->lsock, saddr, errp) < 0) {
3783 goto fail;
3785 vd->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3787 if (ws_enabled) {
3788 vd->lwebsock = qio_channel_socket_new();
3789 qio_channel_set_name(QIO_CHANNEL(vd->lwebsock), "vnc-ws-listen");
3790 if (qio_channel_socket_listen_sync(vd->lwebsock,
3791 wsaddr, errp) < 0) {
3792 object_unref(OBJECT(vd->lsock));
3793 vd->lsock = NULL;
3794 goto fail;
3798 vd->lsock_tag = qio_channel_add_watch(
3799 QIO_CHANNEL(vd->lsock),
3800 G_IO_IN, vnc_listen_io, vd, NULL);
3801 if (ws_enabled) {
3802 vd->lwebsock_tag = qio_channel_add_watch(
3803 QIO_CHANNEL(vd->lwebsock),
3804 G_IO_IN, vnc_listen_io, vd, NULL);
3808 if (show_vnc_port) {
3809 vnc_display_print_local_addr(vd);
3812 qapi_free_SocketAddress(saddr);
3813 qapi_free_SocketAddress(wsaddr);
3814 return;
3816 fail:
3817 qapi_free_SocketAddress(saddr);
3818 qapi_free_SocketAddress(wsaddr);
3819 ws_enabled = false;
3822 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3824 VncDisplay *vd = vnc_display_find(id);
3825 QIOChannelSocket *sioc;
3827 if (!vd) {
3828 return;
3831 sioc = qio_channel_socket_new_fd(csock, NULL);
3832 if (sioc) {
3833 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
3834 vnc_connect(vd, sioc, skipauth, false);
3835 object_unref(OBJECT(sioc));
3839 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3841 int i = 2;
3842 char *id;
3844 id = g_strdup("default");
3845 while (qemu_opts_find(olist, id)) {
3846 g_free(id);
3847 id = g_strdup_printf("vnc%d", i++);
3849 qemu_opts_set_id(opts, id);
3852 QemuOpts *vnc_parse(const char *str, Error **errp)
3854 QemuOptsList *olist = qemu_find_opts("vnc");
3855 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3856 const char *id;
3858 if (!opts) {
3859 return NULL;
3862 id = qemu_opts_id(opts);
3863 if (!id) {
3864 /* auto-assign id if not present */
3865 vnc_auto_assign_id(olist, opts);
3867 return opts;
3870 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3872 Error *local_err = NULL;
3873 char *id = (char *)qemu_opts_id(opts);
3875 assert(id);
3876 vnc_display_init(id);
3877 vnc_display_open(id, &local_err);
3878 if (local_err != NULL) {
3879 error_reportf_err(local_err, "Failed to start VNC server: ");
3880 exit(1);
3882 return 0;
3885 static void vnc_register_config(void)
3887 qemu_add_opts(&qemu_vnc_opts);
3889 opts_init(vnc_register_config);