slirp: fix segv when init failed
[qemu.git] / ui / vnc.c
blob853b57e982b2e095b4529f85f3a32ef62092081f
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "vnc.h"
29 #include "vnc-jobs.h"
30 #include "trace.h"
31 #include "hw/qdev.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
36 #include "qemu/acl.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
59 QTAILQ_HEAD_INITIALIZER(vnc_displays);
61 static int vnc_cursor_define(VncState *vs);
62 static void vnc_release_modifiers(VncState *vs);
64 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
66 #ifdef _VNC_DEBUG
67 static const char *mn[] = {
68 [0] = "undefined",
69 [VNC_SHARE_MODE_CONNECTING] = "connecting",
70 [VNC_SHARE_MODE_SHARED] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
74 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
75 vs->ioc, mn[vs->share_mode], mn[mode]);
76 #endif
78 switch (vs->share_mode) {
79 case VNC_SHARE_MODE_CONNECTING:
80 vs->vd->num_connecting--;
81 break;
82 case VNC_SHARE_MODE_SHARED:
83 vs->vd->num_shared--;
84 break;
85 case VNC_SHARE_MODE_EXCLUSIVE:
86 vs->vd->num_exclusive--;
87 break;
88 default:
89 break;
92 vs->share_mode = mode;
94 switch (vs->share_mode) {
95 case VNC_SHARE_MODE_CONNECTING:
96 vs->vd->num_connecting++;
97 break;
98 case VNC_SHARE_MODE_SHARED:
99 vs->vd->num_shared++;
100 break;
101 case VNC_SHARE_MODE_EXCLUSIVE:
102 vs->vd->num_exclusive++;
103 break;
104 default:
105 break;
110 static void vnc_init_basic_info(SocketAddress *addr,
111 VncBasicInfo *info,
112 Error **errp)
114 switch (addr->type) {
115 case SOCKET_ADDRESS_KIND_INET:
116 info->host = g_strdup(addr->u.inet.data->host);
117 info->service = g_strdup(addr->u.inet.data->port);
118 if (addr->u.inet.data->ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_KIND_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.data->path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 default:
132 error_setg(errp, "Unsupported socket kind %d",
133 addr->type);
134 break;
137 return;
140 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
141 VncBasicInfo *info,
142 Error **errp)
144 SocketAddress *addr = NULL;
146 if (!ioc) {
147 error_setg(errp, "No listener socket available");
148 return;
151 addr = qio_channel_socket_get_local_address(ioc, errp);
152 if (!addr) {
153 return;
156 vnc_init_basic_info(addr, info, errp);
157 qapi_free_SocketAddress(addr);
160 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
161 VncBasicInfo *info,
162 Error **errp)
164 SocketAddress *addr = NULL;
166 addr = qio_channel_socket_get_remote_address(ioc, errp);
167 if (!addr) {
168 return;
171 vnc_init_basic_info(addr, info, errp);
172 qapi_free_SocketAddress(addr);
175 static const char *vnc_auth_name(VncDisplay *vd) {
176 switch (vd->auth) {
177 case VNC_AUTH_INVALID:
178 return "invalid";
179 case VNC_AUTH_NONE:
180 return "none";
181 case VNC_AUTH_VNC:
182 return "vnc";
183 case VNC_AUTH_RA2:
184 return "ra2";
185 case VNC_AUTH_RA2NE:
186 return "ra2ne";
187 case VNC_AUTH_TIGHT:
188 return "tight";
189 case VNC_AUTH_ULTRA:
190 return "ultra";
191 case VNC_AUTH_TLS:
192 return "tls";
193 case VNC_AUTH_VENCRYPT:
194 switch (vd->subauth) {
195 case VNC_AUTH_VENCRYPT_PLAIN:
196 return "vencrypt+plain";
197 case VNC_AUTH_VENCRYPT_TLSNONE:
198 return "vencrypt+tls+none";
199 case VNC_AUTH_VENCRYPT_TLSVNC:
200 return "vencrypt+tls+vnc";
201 case VNC_AUTH_VENCRYPT_TLSPLAIN:
202 return "vencrypt+tls+plain";
203 case VNC_AUTH_VENCRYPT_X509NONE:
204 return "vencrypt+x509+none";
205 case VNC_AUTH_VENCRYPT_X509VNC:
206 return "vencrypt+x509+vnc";
207 case VNC_AUTH_VENCRYPT_X509PLAIN:
208 return "vencrypt+x509+plain";
209 case VNC_AUTH_VENCRYPT_TLSSASL:
210 return "vencrypt+tls+sasl";
211 case VNC_AUTH_VENCRYPT_X509SASL:
212 return "vencrypt+x509+sasl";
213 default:
214 return "vencrypt";
216 case VNC_AUTH_SASL:
217 return "sasl";
219 return "unknown";
222 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
224 VncServerInfo *info;
225 Error *err = NULL;
227 info = g_malloc0(sizeof(*info));
228 vnc_init_basic_info_from_server_addr(vd->lsock,
229 qapi_VncServerInfo_base(info), &err);
230 info->has_auth = true;
231 info->auth = g_strdup(vnc_auth_name(vd));
232 if (err) {
233 qapi_free_VncServerInfo(info);
234 info = NULL;
235 error_free(err);
237 return info;
240 static void vnc_client_cache_auth(VncState *client)
242 if (!client->info) {
243 return;
246 if (client->tls) {
247 client->info->x509_dname =
248 qcrypto_tls_session_get_peer_name(client->tls);
249 client->info->has_x509_dname =
250 client->info->x509_dname != NULL;
252 #ifdef CONFIG_VNC_SASL
253 if (client->sasl.conn &&
254 client->sasl.username) {
255 client->info->has_sasl_username = true;
256 client->info->sasl_username = g_strdup(client->sasl.username);
258 #endif
261 static void vnc_client_cache_addr(VncState *client)
263 Error *err = NULL;
265 client->info = g_malloc0(sizeof(*client->info));
266 vnc_init_basic_info_from_remote_addr(client->sioc,
267 qapi_VncClientInfo_base(client->info),
268 &err);
269 if (err) {
270 qapi_free_VncClientInfo(client->info);
271 client->info = NULL;
272 error_free(err);
276 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
278 VncServerInfo *si;
280 if (!vs->info) {
281 return;
284 si = vnc_server_info_get(vs->vd);
285 if (!si) {
286 return;
289 switch (event) {
290 case QAPI_EVENT_VNC_CONNECTED:
291 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
292 &error_abort);
293 break;
294 case QAPI_EVENT_VNC_INITIALIZED:
295 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
296 break;
297 case QAPI_EVENT_VNC_DISCONNECTED:
298 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
299 break;
300 default:
301 break;
304 qapi_free_VncServerInfo(si);
307 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
309 VncClientInfo *info;
310 Error *err = NULL;
312 info = g_malloc0(sizeof(*info));
314 vnc_init_basic_info_from_remote_addr(client->sioc,
315 qapi_VncClientInfo_base(info),
316 &err);
317 if (err) {
318 error_free(err);
319 qapi_free_VncClientInfo(info);
320 return NULL;
323 info->websocket = client->websocket;
325 if (client->tls) {
326 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
327 info->has_x509_dname = info->x509_dname != NULL;
329 #ifdef CONFIG_VNC_SASL
330 if (client->sasl.conn && client->sasl.username) {
331 info->has_sasl_username = true;
332 info->sasl_username = g_strdup(client->sasl.username);
334 #endif
336 return info;
339 static VncDisplay *vnc_display_find(const char *id)
341 VncDisplay *vd;
343 if (id == NULL) {
344 return QTAILQ_FIRST(&vnc_displays);
346 QTAILQ_FOREACH(vd, &vnc_displays, next) {
347 if (strcmp(id, vd->id) == 0) {
348 return vd;
351 return NULL;
354 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
356 VncClientInfoList *cinfo, *prev = NULL;
357 VncState *client;
359 QTAILQ_FOREACH(client, &vd->clients, next) {
360 cinfo = g_new0(VncClientInfoList, 1);
361 cinfo->value = qmp_query_vnc_client(client);
362 cinfo->next = prev;
363 prev = cinfo;
365 return prev;
368 VncInfo *qmp_query_vnc(Error **errp)
370 VncInfo *info = g_malloc0(sizeof(*info));
371 VncDisplay *vd = vnc_display_find(NULL);
372 SocketAddress *addr = NULL;
374 if (vd == NULL || !vd->enabled) {
375 info->enabled = false;
376 } else {
377 info->enabled = true;
379 /* for compatibility with the original command */
380 info->has_clients = true;
381 info->clients = qmp_query_client_list(vd);
383 if (vd->lsock == NULL) {
384 return info;
387 addr = qio_channel_socket_get_local_address(vd->lsock, errp);
388 if (!addr) {
389 goto out_error;
392 switch (addr->type) {
393 case SOCKET_ADDRESS_KIND_INET:
394 info->host = g_strdup(addr->u.inet.data->host);
395 info->service = g_strdup(addr->u.inet.data->port);
396 if (addr->u.inet.data->ipv6) {
397 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
398 } else {
399 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
401 break;
403 case SOCKET_ADDRESS_KIND_UNIX:
404 info->host = g_strdup("");
405 info->service = g_strdup(addr->u.q_unix.data->path);
406 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
407 break;
409 default:
410 error_setg(errp, "Unsupported socket kind %d",
411 addr->type);
412 goto out_error;
415 info->has_host = true;
416 info->has_service = true;
417 info->has_family = true;
419 info->has_auth = true;
420 info->auth = g_strdup(vnc_auth_name(vd));
423 qapi_free_SocketAddress(addr);
424 return info;
426 out_error:
427 qapi_free_SocketAddress(addr);
428 qapi_free_VncInfo(info);
429 return NULL;
432 static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,
433 bool websocket,
434 VncBasicInfoList *prev)
436 VncBasicInfoList *list;
437 VncBasicInfo *info;
438 Error *err = NULL;
439 SocketAddress *addr;
441 addr = qio_channel_socket_get_local_address(ioc, &err);
442 if (!addr) {
443 error_free(err);
444 return prev;
447 info = g_new0(VncBasicInfo, 1);
448 vnc_init_basic_info(addr, info, &err);
449 qapi_free_SocketAddress(addr);
450 if (err) {
451 qapi_free_VncBasicInfo(info);
452 error_free(err);
453 return prev;
455 info->websocket = websocket;
457 list = g_new0(VncBasicInfoList, 1);
458 list->value = info;
459 list->next = prev;
460 return list;
463 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
465 switch (vd->auth) {
466 case VNC_AUTH_VNC:
467 info->auth = VNC_PRIMARY_AUTH_VNC;
468 break;
469 case VNC_AUTH_RA2:
470 info->auth = VNC_PRIMARY_AUTH_RA2;
471 break;
472 case VNC_AUTH_RA2NE:
473 info->auth = VNC_PRIMARY_AUTH_RA2NE;
474 break;
475 case VNC_AUTH_TIGHT:
476 info->auth = VNC_PRIMARY_AUTH_TIGHT;
477 break;
478 case VNC_AUTH_ULTRA:
479 info->auth = VNC_PRIMARY_AUTH_ULTRA;
480 break;
481 case VNC_AUTH_TLS:
482 info->auth = VNC_PRIMARY_AUTH_TLS;
483 break;
484 case VNC_AUTH_VENCRYPT:
485 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
486 info->has_vencrypt = true;
487 switch (vd->subauth) {
488 case VNC_AUTH_VENCRYPT_PLAIN:
489 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
490 break;
491 case VNC_AUTH_VENCRYPT_TLSNONE:
492 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
493 break;
494 case VNC_AUTH_VENCRYPT_TLSVNC:
495 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
496 break;
497 case VNC_AUTH_VENCRYPT_TLSPLAIN:
498 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
499 break;
500 case VNC_AUTH_VENCRYPT_X509NONE:
501 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
502 break;
503 case VNC_AUTH_VENCRYPT_X509VNC:
504 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
505 break;
506 case VNC_AUTH_VENCRYPT_X509PLAIN:
507 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
508 break;
509 case VNC_AUTH_VENCRYPT_TLSSASL:
510 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
511 break;
512 case VNC_AUTH_VENCRYPT_X509SASL:
513 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
514 break;
515 default:
516 info->has_vencrypt = false;
517 break;
519 break;
520 case VNC_AUTH_SASL:
521 info->auth = VNC_PRIMARY_AUTH_SASL;
522 break;
523 case VNC_AUTH_NONE:
524 default:
525 info->auth = VNC_PRIMARY_AUTH_NONE;
526 break;
530 VncInfo2List *qmp_query_vnc_servers(Error **errp)
532 VncInfo2List *item, *prev = NULL;
533 VncInfo2 *info;
534 VncDisplay *vd;
535 DeviceState *dev;
537 QTAILQ_FOREACH(vd, &vnc_displays, next) {
538 info = g_new0(VncInfo2, 1);
539 info->id = g_strdup(vd->id);
540 info->clients = qmp_query_client_list(vd);
541 qmp_query_auth(vd, info);
542 if (vd->dcl.con) {
543 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
544 "device", NULL));
545 info->has_display = true;
546 info->display = g_strdup(dev->id);
548 if (vd->lsock != NULL) {
549 info->server = qmp_query_server_entry(
550 vd->lsock, false, info->server);
552 if (vd->lwebsock != NULL) {
553 info->server = qmp_query_server_entry(
554 vd->lwebsock, true, info->server);
557 item = g_new0(VncInfo2List, 1);
558 item->value = info;
559 item->next = prev;
560 prev = item;
562 return prev;
565 /* TODO
566 1) Get the queue working for IO.
567 2) there is some weirdness when using the -S option (the screen is grey
568 and not totally invalidated
569 3) resolutions > 1024
572 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
573 static void vnc_disconnect_start(VncState *vs);
575 static void vnc_colordepth(VncState *vs);
576 static void framebuffer_update_request(VncState *vs, int incremental,
577 int x_position, int y_position,
578 int w, int h);
579 static void vnc_refresh(DisplayChangeListener *dcl);
580 static int vnc_refresh_server_surface(VncDisplay *vd);
582 static int vnc_width(VncDisplay *vd)
584 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
585 VNC_DIRTY_PIXELS_PER_BIT));
588 static int vnc_height(VncDisplay *vd)
590 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
593 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
594 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
595 VncDisplay *vd,
596 int x, int y, int w, int h)
598 int width = vnc_width(vd);
599 int height = vnc_height(vd);
601 /* this is needed this to ensure we updated all affected
602 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
603 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
604 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
606 x = MIN(x, width);
607 y = MIN(y, height);
608 w = MIN(x + w, width) - x;
609 h = MIN(y + h, height);
611 for (; y < h; y++) {
612 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
613 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
617 static void vnc_dpy_update(DisplayChangeListener *dcl,
618 int x, int y, int w, int h)
620 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
621 struct VncSurface *s = &vd->guest;
623 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
626 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
627 int32_t encoding)
629 vnc_write_u16(vs, x);
630 vnc_write_u16(vs, y);
631 vnc_write_u16(vs, w);
632 vnc_write_u16(vs, h);
634 vnc_write_s32(vs, encoding);
638 static void vnc_desktop_resize(VncState *vs)
640 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
641 return;
643 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
644 vs->client_height == pixman_image_get_height(vs->vd->server)) {
645 return;
647 vs->client_width = pixman_image_get_width(vs->vd->server);
648 vs->client_height = pixman_image_get_height(vs->vd->server);
649 vnc_lock_output(vs);
650 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
651 vnc_write_u8(vs, 0);
652 vnc_write_u16(vs, 1); /* number of rects */
653 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
654 VNC_ENCODING_DESKTOPRESIZE);
655 vnc_unlock_output(vs);
656 vnc_flush(vs);
659 static void vnc_abort_display_jobs(VncDisplay *vd)
661 VncState *vs;
663 QTAILQ_FOREACH(vs, &vd->clients, next) {
664 vnc_lock_output(vs);
665 vs->abort = true;
666 vnc_unlock_output(vs);
668 QTAILQ_FOREACH(vs, &vd->clients, next) {
669 vnc_jobs_join(vs);
671 QTAILQ_FOREACH(vs, &vd->clients, next) {
672 vnc_lock_output(vs);
673 vs->abort = false;
674 vnc_unlock_output(vs);
678 int vnc_server_fb_stride(VncDisplay *vd)
680 return pixman_image_get_stride(vd->server);
683 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
685 uint8_t *ptr;
687 ptr = (uint8_t *)pixman_image_get_data(vd->server);
688 ptr += y * vnc_server_fb_stride(vd);
689 ptr += x * VNC_SERVER_FB_BYTES;
690 return ptr;
693 static void vnc_update_server_surface(VncDisplay *vd)
695 qemu_pixman_image_unref(vd->server);
696 vd->server = NULL;
698 if (QTAILQ_EMPTY(&vd->clients)) {
699 return;
702 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
703 vnc_width(vd),
704 vnc_height(vd),
705 NULL, 0);
708 static void vnc_dpy_switch(DisplayChangeListener *dcl,
709 DisplaySurface *surface)
711 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
712 VncState *vs;
713 int width, height;
715 vnc_abort_display_jobs(vd);
716 vd->ds = surface;
718 /* server surface */
719 vnc_update_server_surface(vd);
721 /* guest surface */
722 qemu_pixman_image_unref(vd->guest.fb);
723 vd->guest.fb = pixman_image_ref(surface->image);
724 vd->guest.format = surface->format;
725 width = vnc_width(vd);
726 height = vnc_height(vd);
727 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
728 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
729 width, height);
731 QTAILQ_FOREACH(vs, &vd->clients, next) {
732 vnc_colordepth(vs);
733 vnc_desktop_resize(vs);
734 if (vs->vd->cursor) {
735 vnc_cursor_define(vs);
737 memset(vs->dirty, 0x00, sizeof(vs->dirty));
738 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
739 width, height);
743 /* fastest code */
744 static void vnc_write_pixels_copy(VncState *vs,
745 void *pixels, int size)
747 vnc_write(vs, pixels, size);
750 /* slowest but generic code. */
751 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
753 uint8_t r, g, b;
755 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
756 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
757 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
758 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
759 #else
760 # error need some bits here if you change VNC_SERVER_FB_FORMAT
761 #endif
762 v = (r << vs->client_pf.rshift) |
763 (g << vs->client_pf.gshift) |
764 (b << vs->client_pf.bshift);
765 switch (vs->client_pf.bytes_per_pixel) {
766 case 1:
767 buf[0] = v;
768 break;
769 case 2:
770 if (vs->client_be) {
771 buf[0] = v >> 8;
772 buf[1] = v;
773 } else {
774 buf[1] = v >> 8;
775 buf[0] = v;
777 break;
778 default:
779 case 4:
780 if (vs->client_be) {
781 buf[0] = v >> 24;
782 buf[1] = v >> 16;
783 buf[2] = v >> 8;
784 buf[3] = v;
785 } else {
786 buf[3] = v >> 24;
787 buf[2] = v >> 16;
788 buf[1] = v >> 8;
789 buf[0] = v;
791 break;
795 static void vnc_write_pixels_generic(VncState *vs,
796 void *pixels1, int size)
798 uint8_t buf[4];
800 if (VNC_SERVER_FB_BYTES == 4) {
801 uint32_t *pixels = pixels1;
802 int n, i;
803 n = size >> 2;
804 for (i = 0; i < n; i++) {
805 vnc_convert_pixel(vs, buf, pixels[i]);
806 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
811 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
813 int i;
814 uint8_t *row;
815 VncDisplay *vd = vs->vd;
817 row = vnc_server_fb_ptr(vd, x, y);
818 for (i = 0; i < h; i++) {
819 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
820 row += vnc_server_fb_stride(vd);
822 return 1;
825 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
827 int n = 0;
828 bool encode_raw = false;
829 size_t saved_offs = vs->output.offset;
831 switch(vs->vnc_encoding) {
832 case VNC_ENCODING_ZLIB:
833 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
834 break;
835 case VNC_ENCODING_HEXTILE:
836 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
837 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
838 break;
839 case VNC_ENCODING_TIGHT:
840 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
841 break;
842 case VNC_ENCODING_TIGHT_PNG:
843 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
844 break;
845 case VNC_ENCODING_ZRLE:
846 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
847 break;
848 case VNC_ENCODING_ZYWRLE:
849 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
850 break;
851 default:
852 encode_raw = true;
853 break;
856 /* If the client has the same pixel format as our internal buffer and
857 * a RAW encoding would need less space fall back to RAW encoding to
858 * save bandwidth and processing power in the client. */
859 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
860 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
861 vs->output.offset = saved_offs;
862 encode_raw = true;
865 if (encode_raw) {
866 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
867 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
870 return n;
873 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
875 /* send bitblit op to the vnc client */
876 vnc_lock_output(vs);
877 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
878 vnc_write_u8(vs, 0);
879 vnc_write_u16(vs, 1); /* number of rects */
880 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
881 vnc_write_u16(vs, src_x);
882 vnc_write_u16(vs, src_y);
883 vnc_unlock_output(vs);
884 vnc_flush(vs);
887 static void vnc_dpy_copy(DisplayChangeListener *dcl,
888 int src_x, int src_y,
889 int dst_x, int dst_y, int w, int h)
891 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
892 VncState *vs, *vn;
893 uint8_t *src_row;
894 uint8_t *dst_row;
895 int i, x, y, pitch, inc, w_lim, s;
896 int cmp_bytes;
898 if (!vd->server) {
899 /* no client connected */
900 return;
903 vnc_refresh_server_surface(vd);
904 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
905 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
906 vs->force_update = 1;
907 vnc_update_client(vs, 1, true);
908 /* vs might be free()ed here */
912 /* do bitblit op on the local surface too */
913 pitch = vnc_server_fb_stride(vd);
914 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
915 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
916 y = dst_y;
917 inc = 1;
918 if (dst_y > src_y) {
919 /* copy backwards */
920 src_row += pitch * (h-1);
921 dst_row += pitch * (h-1);
922 pitch = -pitch;
923 y = dst_y + h - 1;
924 inc = -1;
926 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
927 if (w_lim < 0) {
928 w_lim = w;
929 } else {
930 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
932 for (i = 0; i < h; i++) {
933 for (x = 0; x <= w_lim;
934 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
935 if (x == w_lim) {
936 if ((s = w - w_lim) == 0)
937 break;
938 } else if (!x) {
939 s = (VNC_DIRTY_PIXELS_PER_BIT -
940 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
941 s = MIN(s, w_lim);
942 } else {
943 s = VNC_DIRTY_PIXELS_PER_BIT;
945 cmp_bytes = s * VNC_SERVER_FB_BYTES;
946 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
947 continue;
948 memmove(dst_row, src_row, cmp_bytes);
949 QTAILQ_FOREACH(vs, &vd->clients, next) {
950 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
951 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
952 vs->dirty[y]);
956 src_row += pitch - w * VNC_SERVER_FB_BYTES;
957 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
958 y += inc;
961 QTAILQ_FOREACH(vs, &vd->clients, next) {
962 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
963 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
968 static void vnc_mouse_set(DisplayChangeListener *dcl,
969 int x, int y, int visible)
971 /* can we ask the client(s) to move the pointer ??? */
974 static int vnc_cursor_define(VncState *vs)
976 QEMUCursor *c = vs->vd->cursor;
977 int isize;
979 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
980 vnc_lock_output(vs);
981 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
982 vnc_write_u8(vs, 0); /* padding */
983 vnc_write_u16(vs, 1); /* # of rects */
984 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
985 VNC_ENCODING_RICH_CURSOR);
986 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
987 vnc_write_pixels_generic(vs, c->data, isize);
988 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
989 vnc_unlock_output(vs);
990 return 0;
992 return -1;
995 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
996 QEMUCursor *c)
998 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
999 VncState *vs;
1001 cursor_put(vd->cursor);
1002 g_free(vd->cursor_mask);
1004 vd->cursor = c;
1005 cursor_get(vd->cursor);
1006 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1007 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1008 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1010 QTAILQ_FOREACH(vs, &vd->clients, next) {
1011 vnc_cursor_define(vs);
1015 static int find_and_clear_dirty_height(VncState *vs,
1016 int y, int last_x, int x, int height)
1018 int h;
1020 for (h = 1; h < (height - y); h++) {
1021 if (!test_bit(last_x, vs->dirty[y + h])) {
1022 break;
1024 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1027 return h;
1030 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1032 if (vs->disconnecting) {
1033 vnc_disconnect_finish(vs);
1034 return 0;
1037 vs->has_dirty += has_dirty;
1038 if (vs->need_update && !vs->disconnecting) {
1039 VncDisplay *vd = vs->vd;
1040 VncJob *job;
1041 int y;
1042 int height, width;
1043 int n = 0;
1045 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1046 /* kernel send buffers are full -> drop frames to throttle */
1047 return 0;
1049 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1050 return 0;
1053 * Send screen updates to the vnc client using the server
1054 * surface and server dirty map. guest surface updates
1055 * happening in parallel don't disturb us, the next pass will
1056 * send them to the client.
1058 job = vnc_job_new(vs);
1060 height = pixman_image_get_height(vd->server);
1061 width = pixman_image_get_width(vd->server);
1063 y = 0;
1064 for (;;) {
1065 int x, h;
1066 unsigned long x2;
1067 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1068 height * VNC_DIRTY_BPL(vs),
1069 y * VNC_DIRTY_BPL(vs));
1070 if (offset == height * VNC_DIRTY_BPL(vs)) {
1071 /* no more dirty bits */
1072 break;
1074 y = offset / VNC_DIRTY_BPL(vs);
1075 x = offset % VNC_DIRTY_BPL(vs);
1076 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1077 VNC_DIRTY_BPL(vs), x);
1078 bitmap_clear(vs->dirty[y], x, x2 - x);
1079 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1080 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1081 if (x2 > x) {
1082 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1083 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1085 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1086 y += h;
1087 if (y == height) {
1088 break;
1093 vnc_job_push(job);
1094 if (sync) {
1095 vnc_jobs_join(vs);
1097 vs->force_update = 0;
1098 vs->has_dirty = 0;
1099 return n;
1102 if (vs->disconnecting) {
1103 vnc_disconnect_finish(vs);
1104 } else if (sync) {
1105 vnc_jobs_join(vs);
1108 return 0;
1111 /* audio */
1112 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1114 VncState *vs = opaque;
1116 switch (cmd) {
1117 case AUD_CNOTIFY_DISABLE:
1118 vnc_lock_output(vs);
1119 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1120 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1121 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1122 vnc_unlock_output(vs);
1123 vnc_flush(vs);
1124 break;
1126 case AUD_CNOTIFY_ENABLE:
1127 vnc_lock_output(vs);
1128 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1129 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1130 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1131 vnc_unlock_output(vs);
1132 vnc_flush(vs);
1133 break;
1137 static void audio_capture_destroy(void *opaque)
1141 static void audio_capture(void *opaque, void *buf, int size)
1143 VncState *vs = opaque;
1145 vnc_lock_output(vs);
1146 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1147 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1148 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1149 vnc_write_u32(vs, size);
1150 vnc_write(vs, buf, size);
1151 vnc_unlock_output(vs);
1152 vnc_flush(vs);
1155 static void audio_add(VncState *vs)
1157 struct audio_capture_ops ops;
1159 if (vs->audio_cap) {
1160 error_report("audio already running");
1161 return;
1164 ops.notify = audio_capture_notify;
1165 ops.destroy = audio_capture_destroy;
1166 ops.capture = audio_capture;
1168 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1169 if (!vs->audio_cap) {
1170 error_report("Failed to add audio capture");
1174 static void audio_del(VncState *vs)
1176 if (vs->audio_cap) {
1177 AUD_del_capture(vs->audio_cap, vs);
1178 vs->audio_cap = NULL;
1182 static void vnc_disconnect_start(VncState *vs)
1184 if (vs->disconnecting) {
1185 return;
1187 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1188 if (vs->ioc_tag) {
1189 g_source_remove(vs->ioc_tag);
1191 qio_channel_close(vs->ioc, NULL);
1192 vs->disconnecting = TRUE;
1195 void vnc_disconnect_finish(VncState *vs)
1197 int i;
1199 vnc_jobs_join(vs); /* Wait encoding jobs */
1201 vnc_lock_output(vs);
1202 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1204 buffer_free(&vs->input);
1205 buffer_free(&vs->output);
1207 qapi_free_VncClientInfo(vs->info);
1209 vnc_zlib_clear(vs);
1210 vnc_tight_clear(vs);
1211 vnc_zrle_clear(vs);
1213 #ifdef CONFIG_VNC_SASL
1214 vnc_sasl_client_cleanup(vs);
1215 #endif /* CONFIG_VNC_SASL */
1216 audio_del(vs);
1217 vnc_release_modifiers(vs);
1219 if (vs->initialized) {
1220 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1221 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1222 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1223 /* last client gone */
1224 vnc_update_server_surface(vs->vd);
1228 if (vs->vd->lock_key_sync)
1229 qemu_remove_led_event_handler(vs->led);
1230 vnc_unlock_output(vs);
1232 qemu_mutex_destroy(&vs->output_mutex);
1233 if (vs->bh != NULL) {
1234 qemu_bh_delete(vs->bh);
1236 buffer_free(&vs->jobs_buffer);
1238 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1239 g_free(vs->lossy_rect[i]);
1241 g_free(vs->lossy_rect);
1243 object_unref(OBJECT(vs->ioc));
1244 vs->ioc = NULL;
1245 object_unref(OBJECT(vs->sioc));
1246 vs->sioc = NULL;
1247 g_free(vs);
1250 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1252 if (ret <= 0) {
1253 if (ret == 0) {
1254 VNC_DEBUG("Closing down client sock: EOF\n");
1255 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1256 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1257 ret, errp ? error_get_pretty(*errp) : "Unknown");
1260 vnc_disconnect_start(vs);
1261 if (errp) {
1262 error_free(*errp);
1263 *errp = NULL;
1265 return 0;
1267 return ret;
1271 void vnc_client_error(VncState *vs)
1273 VNC_DEBUG("Closing down client sock: protocol error\n");
1274 vnc_disconnect_start(vs);
1279 * Called to write a chunk of data to the client socket. The data may
1280 * be the raw data, or may have already been encoded by SASL.
1281 * The data will be written either straight onto the socket, or
1282 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1284 * NB, it is theoretically possible to have 2 layers of encryption,
1285 * both SASL, and this TLS layer. It is highly unlikely in practice
1286 * though, since SASL encryption will typically be a no-op if TLS
1287 * is active
1289 * Returns the number of bytes written, which may be less than
1290 * the requested 'datalen' if the socket would block. Returns
1291 * -1 on error, and disconnects the client socket.
1293 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1295 Error *err = NULL;
1296 ssize_t ret;
1297 ret = qio_channel_write(
1298 vs->ioc, (const char *)data, datalen, &err);
1299 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1300 return vnc_client_io_error(vs, ret, &err);
1305 * Called to write buffered data to the client socket, when not
1306 * using any SASL SSF encryption layers. Will write as much data
1307 * as possible without blocking. If all buffered data is written,
1308 * will switch the FD poll() handler back to read monitoring.
1310 * Returns the number of bytes written, which may be less than
1311 * the buffered output data if the socket would block. Returns
1312 * -1 on error, and disconnects the client socket.
1314 static ssize_t vnc_client_write_plain(VncState *vs)
1316 ssize_t ret;
1318 #ifdef CONFIG_VNC_SASL
1319 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1320 vs->output.buffer, vs->output.capacity, vs->output.offset,
1321 vs->sasl.waitWriteSSF);
1323 if (vs->sasl.conn &&
1324 vs->sasl.runSSF &&
1325 vs->sasl.waitWriteSSF) {
1326 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1327 if (ret)
1328 vs->sasl.waitWriteSSF -= ret;
1329 } else
1330 #endif /* CONFIG_VNC_SASL */
1331 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1332 if (!ret)
1333 return 0;
1335 buffer_advance(&vs->output, ret);
1337 if (vs->output.offset == 0) {
1338 if (vs->ioc_tag) {
1339 g_source_remove(vs->ioc_tag);
1341 vs->ioc_tag = qio_channel_add_watch(
1342 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1345 return ret;
1350 * First function called whenever there is data to be written to
1351 * the client socket. Will delegate actual work according to whether
1352 * SASL SSF layers are enabled (thus requiring encryption calls)
1354 static void vnc_client_write_locked(VncState *vs)
1356 #ifdef CONFIG_VNC_SASL
1357 if (vs->sasl.conn &&
1358 vs->sasl.runSSF &&
1359 !vs->sasl.waitWriteSSF) {
1360 vnc_client_write_sasl(vs);
1361 } else
1362 #endif /* CONFIG_VNC_SASL */
1364 vnc_client_write_plain(vs);
1368 static void vnc_client_write(VncState *vs)
1371 vnc_lock_output(vs);
1372 if (vs->output.offset) {
1373 vnc_client_write_locked(vs);
1374 } else if (vs->ioc != NULL) {
1375 if (vs->ioc_tag) {
1376 g_source_remove(vs->ioc_tag);
1378 vs->ioc_tag = qio_channel_add_watch(
1379 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1381 vnc_unlock_output(vs);
1384 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1386 vs->read_handler = func;
1387 vs->read_handler_expect = expecting;
1392 * Called to read a chunk of data from the client socket. The data may
1393 * be the raw data, or may need to be further decoded by SASL.
1394 * The data will be read either straight from to the socket, or
1395 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1397 * NB, it is theoretically possible to have 2 layers of encryption,
1398 * both SASL, and this TLS layer. It is highly unlikely in practice
1399 * though, since SASL encryption will typically be a no-op if TLS
1400 * is active
1402 * Returns the number of bytes read, which may be less than
1403 * the requested 'datalen' if the socket would block. Returns
1404 * -1 on error, and disconnects the client socket.
1406 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1408 ssize_t ret;
1409 Error *err = NULL;
1410 ret = qio_channel_read(
1411 vs->ioc, (char *)data, datalen, &err);
1412 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1413 return vnc_client_io_error(vs, ret, &err);
1418 * Called to read data from the client socket to the input buffer,
1419 * when not using any SASL SSF encryption layers. Will read as much
1420 * data as possible without blocking.
1422 * Returns the number of bytes read. Returns -1 on error, and
1423 * disconnects the client socket.
1425 static ssize_t vnc_client_read_plain(VncState *vs)
1427 ssize_t ret;
1428 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1429 vs->input.buffer, vs->input.capacity, vs->input.offset);
1430 buffer_reserve(&vs->input, 4096);
1431 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1432 if (!ret)
1433 return 0;
1434 vs->input.offset += ret;
1435 return ret;
1438 static void vnc_jobs_bh(void *opaque)
1440 VncState *vs = opaque;
1442 vnc_jobs_consume_buffer(vs);
1446 * First function called whenever there is more data to be read from
1447 * the client socket. Will delegate actual work according to whether
1448 * SASL SSF layers are enabled (thus requiring decryption calls)
1449 * Returns 0 on success, -1 if client disconnected
1451 static int vnc_client_read(VncState *vs)
1453 ssize_t ret;
1455 #ifdef CONFIG_VNC_SASL
1456 if (vs->sasl.conn && vs->sasl.runSSF)
1457 ret = vnc_client_read_sasl(vs);
1458 else
1459 #endif /* CONFIG_VNC_SASL */
1460 ret = vnc_client_read_plain(vs);
1461 if (!ret) {
1462 if (vs->disconnecting) {
1463 vnc_disconnect_finish(vs);
1464 return -1;
1466 return 0;
1469 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1470 size_t len = vs->read_handler_expect;
1471 int ret;
1473 ret = vs->read_handler(vs, vs->input.buffer, len);
1474 if (vs->disconnecting) {
1475 vnc_disconnect_finish(vs);
1476 return -1;
1479 if (!ret) {
1480 buffer_advance(&vs->input, len);
1481 } else {
1482 vs->read_handler_expect = ret;
1485 return 0;
1488 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1489 GIOCondition condition, void *opaque)
1491 VncState *vs = opaque;
1492 if (condition & G_IO_IN) {
1493 if (vnc_client_read(vs) < 0) {
1494 return TRUE;
1497 if (condition & G_IO_OUT) {
1498 vnc_client_write(vs);
1500 return TRUE;
1504 void vnc_write(VncState *vs, const void *data, size_t len)
1506 buffer_reserve(&vs->output, len);
1508 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1509 if (vs->ioc_tag) {
1510 g_source_remove(vs->ioc_tag);
1512 vs->ioc_tag = qio_channel_add_watch(
1513 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1516 buffer_append(&vs->output, data, len);
1519 void vnc_write_s32(VncState *vs, int32_t value)
1521 vnc_write_u32(vs, *(uint32_t *)&value);
1524 void vnc_write_u32(VncState *vs, uint32_t value)
1526 uint8_t buf[4];
1528 buf[0] = (value >> 24) & 0xFF;
1529 buf[1] = (value >> 16) & 0xFF;
1530 buf[2] = (value >> 8) & 0xFF;
1531 buf[3] = value & 0xFF;
1533 vnc_write(vs, buf, 4);
1536 void vnc_write_u16(VncState *vs, uint16_t value)
1538 uint8_t buf[2];
1540 buf[0] = (value >> 8) & 0xFF;
1541 buf[1] = value & 0xFF;
1543 vnc_write(vs, buf, 2);
1546 void vnc_write_u8(VncState *vs, uint8_t value)
1548 vnc_write(vs, (char *)&value, 1);
1551 void vnc_flush(VncState *vs)
1553 vnc_lock_output(vs);
1554 if (vs->ioc != NULL && vs->output.offset) {
1555 vnc_client_write_locked(vs);
1557 vnc_unlock_output(vs);
1560 static uint8_t read_u8(uint8_t *data, size_t offset)
1562 return data[offset];
1565 static uint16_t read_u16(uint8_t *data, size_t offset)
1567 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1570 static int32_t read_s32(uint8_t *data, size_t offset)
1572 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1573 (data[offset + 2] << 8) | data[offset + 3]);
1576 uint32_t read_u32(uint8_t *data, size_t offset)
1578 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1579 (data[offset + 2] << 8) | data[offset + 3]);
1582 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1586 static void check_pointer_type_change(Notifier *notifier, void *data)
1588 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1589 int absolute = qemu_input_is_absolute();
1591 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1592 vnc_lock_output(vs);
1593 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1594 vnc_write_u8(vs, 0);
1595 vnc_write_u16(vs, 1);
1596 vnc_framebuffer_update(vs, absolute, 0,
1597 pixman_image_get_width(vs->vd->server),
1598 pixman_image_get_height(vs->vd->server),
1599 VNC_ENCODING_POINTER_TYPE_CHANGE);
1600 vnc_unlock_output(vs);
1601 vnc_flush(vs);
1603 vs->absolute = absolute;
1606 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1608 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1609 [INPUT_BUTTON_LEFT] = 0x01,
1610 [INPUT_BUTTON_MIDDLE] = 0x02,
1611 [INPUT_BUTTON_RIGHT] = 0x04,
1612 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1613 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1615 QemuConsole *con = vs->vd->dcl.con;
1616 int width = pixman_image_get_width(vs->vd->server);
1617 int height = pixman_image_get_height(vs->vd->server);
1619 if (vs->last_bmask != button_mask) {
1620 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1621 vs->last_bmask = button_mask;
1624 if (vs->absolute) {
1625 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1626 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1627 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1628 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1629 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1630 } else {
1631 if (vs->last_x != -1) {
1632 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1633 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1635 vs->last_x = x;
1636 vs->last_y = y;
1638 qemu_input_event_sync();
1641 static void reset_keys(VncState *vs)
1643 int i;
1644 for(i = 0; i < 256; i++) {
1645 if (vs->modifiers_state[i]) {
1646 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1647 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1648 vs->modifiers_state[i] = 0;
1653 static void press_key(VncState *vs, int keysym)
1655 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1656 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1657 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1658 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1659 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1662 static int current_led_state(VncState *vs)
1664 int ledstate = 0;
1666 if (vs->modifiers_state[0x46]) {
1667 ledstate |= QEMU_SCROLL_LOCK_LED;
1669 if (vs->modifiers_state[0x45]) {
1670 ledstate |= QEMU_NUM_LOCK_LED;
1672 if (vs->modifiers_state[0x3a]) {
1673 ledstate |= QEMU_CAPS_LOCK_LED;
1676 return ledstate;
1679 static void vnc_led_state_change(VncState *vs)
1681 int ledstate = 0;
1683 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1684 return;
1687 ledstate = current_led_state(vs);
1688 vnc_lock_output(vs);
1689 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1690 vnc_write_u8(vs, 0);
1691 vnc_write_u16(vs, 1);
1692 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1693 vnc_write_u8(vs, ledstate);
1694 vnc_unlock_output(vs);
1695 vnc_flush(vs);
1698 static void kbd_leds(void *opaque, int ledstate)
1700 VncState *vs = opaque;
1701 int caps, num, scr;
1702 bool has_changed = (ledstate != current_led_state(vs));
1704 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1705 (ledstate & QEMU_NUM_LOCK_LED),
1706 (ledstate & QEMU_SCROLL_LOCK_LED));
1708 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1709 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1710 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1712 if (vs->modifiers_state[0x3a] != caps) {
1713 vs->modifiers_state[0x3a] = caps;
1715 if (vs->modifiers_state[0x45] != num) {
1716 vs->modifiers_state[0x45] = num;
1718 if (vs->modifiers_state[0x46] != scr) {
1719 vs->modifiers_state[0x46] = scr;
1722 /* Sending the current led state message to the client */
1723 if (has_changed) {
1724 vnc_led_state_change(vs);
1728 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1730 /* QEMU console switch */
1731 switch(keycode) {
1732 case 0x2a: /* Left Shift */
1733 case 0x36: /* Right Shift */
1734 case 0x1d: /* Left CTRL */
1735 case 0x9d: /* Right CTRL */
1736 case 0x38: /* Left ALT */
1737 case 0xb8: /* Right ALT */
1738 if (down)
1739 vs->modifiers_state[keycode] = 1;
1740 else
1741 vs->modifiers_state[keycode] = 0;
1742 break;
1743 case 0x02 ... 0x0a: /* '1' to '9' keys */
1744 if (vs->vd->dcl.con == NULL &&
1745 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1746 /* Reset the modifiers sent to the current console */
1747 reset_keys(vs);
1748 console_select(keycode - 0x02);
1749 return;
1751 break;
1752 case 0x3a: /* CapsLock */
1753 case 0x45: /* NumLock */
1754 if (down)
1755 vs->modifiers_state[keycode] ^= 1;
1756 break;
1759 /* Turn off the lock state sync logic if the client support the led
1760 state extension.
1762 if (down && vs->vd->lock_key_sync &&
1763 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1764 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1765 /* If the numlock state needs to change then simulate an additional
1766 keypress before sending this one. This will happen if the user
1767 toggles numlock away from the VNC window.
1769 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1770 if (!vs->modifiers_state[0x45]) {
1771 trace_vnc_key_sync_numlock(true);
1772 vs->modifiers_state[0x45] = 1;
1773 press_key(vs, 0xff7f);
1775 } else {
1776 if (vs->modifiers_state[0x45]) {
1777 trace_vnc_key_sync_numlock(false);
1778 vs->modifiers_state[0x45] = 0;
1779 press_key(vs, 0xff7f);
1784 if (down && vs->vd->lock_key_sync &&
1785 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1786 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1787 /* If the capslock state needs to change then simulate an additional
1788 keypress before sending this one. This will happen if the user
1789 toggles capslock away from the VNC window.
1791 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1792 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1793 int capslock = !!(vs->modifiers_state[0x3a]);
1794 if (capslock) {
1795 if (uppercase == shift) {
1796 trace_vnc_key_sync_capslock(false);
1797 vs->modifiers_state[0x3a] = 0;
1798 press_key(vs, 0xffe5);
1800 } else {
1801 if (uppercase != shift) {
1802 trace_vnc_key_sync_capslock(true);
1803 vs->modifiers_state[0x3a] = 1;
1804 press_key(vs, 0xffe5);
1809 if (qemu_console_is_graphic(NULL)) {
1810 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1811 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1812 } else {
1813 bool numlock = vs->modifiers_state[0x45];
1814 bool control = (vs->modifiers_state[0x1d] ||
1815 vs->modifiers_state[0x9d]);
1816 /* QEMU console emulation */
1817 if (down) {
1818 switch (keycode) {
1819 case 0x2a: /* Left Shift */
1820 case 0x36: /* Right Shift */
1821 case 0x1d: /* Left CTRL */
1822 case 0x9d: /* Right CTRL */
1823 case 0x38: /* Left ALT */
1824 case 0xb8: /* Right ALT */
1825 break;
1826 case 0xc8:
1827 kbd_put_keysym(QEMU_KEY_UP);
1828 break;
1829 case 0xd0:
1830 kbd_put_keysym(QEMU_KEY_DOWN);
1831 break;
1832 case 0xcb:
1833 kbd_put_keysym(QEMU_KEY_LEFT);
1834 break;
1835 case 0xcd:
1836 kbd_put_keysym(QEMU_KEY_RIGHT);
1837 break;
1838 case 0xd3:
1839 kbd_put_keysym(QEMU_KEY_DELETE);
1840 break;
1841 case 0xc7:
1842 kbd_put_keysym(QEMU_KEY_HOME);
1843 break;
1844 case 0xcf:
1845 kbd_put_keysym(QEMU_KEY_END);
1846 break;
1847 case 0xc9:
1848 kbd_put_keysym(QEMU_KEY_PAGEUP);
1849 break;
1850 case 0xd1:
1851 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1852 break;
1854 case 0x47:
1855 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1856 break;
1857 case 0x48:
1858 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1859 break;
1860 case 0x49:
1861 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1862 break;
1863 case 0x4b:
1864 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1865 break;
1866 case 0x4c:
1867 kbd_put_keysym('5');
1868 break;
1869 case 0x4d:
1870 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1871 break;
1872 case 0x4f:
1873 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1874 break;
1875 case 0x50:
1876 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1877 break;
1878 case 0x51:
1879 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1880 break;
1881 case 0x52:
1882 kbd_put_keysym('0');
1883 break;
1884 case 0x53:
1885 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1886 break;
1888 case 0xb5:
1889 kbd_put_keysym('/');
1890 break;
1891 case 0x37:
1892 kbd_put_keysym('*');
1893 break;
1894 case 0x4a:
1895 kbd_put_keysym('-');
1896 break;
1897 case 0x4e:
1898 kbd_put_keysym('+');
1899 break;
1900 case 0x9c:
1901 kbd_put_keysym('\n');
1902 break;
1904 default:
1905 if (control) {
1906 kbd_put_keysym(sym & 0x1f);
1907 } else {
1908 kbd_put_keysym(sym);
1910 break;
1916 static void vnc_release_modifiers(VncState *vs)
1918 static const int keycodes[] = {
1919 /* shift, control, alt keys, both left & right */
1920 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1922 int i, keycode;
1924 if (!qemu_console_is_graphic(NULL)) {
1925 return;
1927 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1928 keycode = keycodes[i];
1929 if (!vs->modifiers_state[keycode]) {
1930 continue;
1932 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1933 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1937 static const char *code2name(int keycode)
1939 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1942 static void key_event(VncState *vs, int down, uint32_t sym)
1944 int keycode;
1945 int lsym = sym;
1947 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1948 lsym = lsym - 'A' + 'a';
1951 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1952 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1953 do_key_event(vs, down, keycode, sym);
1956 static void ext_key_event(VncState *vs, int down,
1957 uint32_t sym, uint16_t keycode)
1959 /* if the user specifies a keyboard layout, always use it */
1960 if (keyboard_layout) {
1961 key_event(vs, down, sym);
1962 } else {
1963 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1964 do_key_event(vs, down, keycode, sym);
1968 static void framebuffer_update_request(VncState *vs, int incremental,
1969 int x, int y, int w, int h)
1971 vs->need_update = 1;
1973 if (incremental) {
1974 return;
1977 vs->force_update = 1;
1978 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1981 static void send_ext_key_event_ack(VncState *vs)
1983 vnc_lock_output(vs);
1984 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1985 vnc_write_u8(vs, 0);
1986 vnc_write_u16(vs, 1);
1987 vnc_framebuffer_update(vs, 0, 0,
1988 pixman_image_get_width(vs->vd->server),
1989 pixman_image_get_height(vs->vd->server),
1990 VNC_ENCODING_EXT_KEY_EVENT);
1991 vnc_unlock_output(vs);
1992 vnc_flush(vs);
1995 static void send_ext_audio_ack(VncState *vs)
1997 vnc_lock_output(vs);
1998 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1999 vnc_write_u8(vs, 0);
2000 vnc_write_u16(vs, 1);
2001 vnc_framebuffer_update(vs, 0, 0,
2002 pixman_image_get_width(vs->vd->server),
2003 pixman_image_get_height(vs->vd->server),
2004 VNC_ENCODING_AUDIO);
2005 vnc_unlock_output(vs);
2006 vnc_flush(vs);
2009 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2011 int i;
2012 unsigned int enc = 0;
2014 vs->features = 0;
2015 vs->vnc_encoding = 0;
2016 vs->tight.compression = 9;
2017 vs->tight.quality = -1; /* Lossless by default */
2018 vs->absolute = -1;
2021 * Start from the end because the encodings are sent in order of preference.
2022 * This way the preferred encoding (first encoding defined in the array)
2023 * will be set at the end of the loop.
2025 for (i = n_encodings - 1; i >= 0; i--) {
2026 enc = encodings[i];
2027 switch (enc) {
2028 case VNC_ENCODING_RAW:
2029 vs->vnc_encoding = enc;
2030 break;
2031 case VNC_ENCODING_COPYRECT:
2032 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2033 break;
2034 case VNC_ENCODING_HEXTILE:
2035 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2036 vs->vnc_encoding = enc;
2037 break;
2038 case VNC_ENCODING_TIGHT:
2039 vs->features |= VNC_FEATURE_TIGHT_MASK;
2040 vs->vnc_encoding = enc;
2041 break;
2042 #ifdef CONFIG_VNC_PNG
2043 case VNC_ENCODING_TIGHT_PNG:
2044 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2045 vs->vnc_encoding = enc;
2046 break;
2047 #endif
2048 case VNC_ENCODING_ZLIB:
2049 vs->features |= VNC_FEATURE_ZLIB_MASK;
2050 vs->vnc_encoding = enc;
2051 break;
2052 case VNC_ENCODING_ZRLE:
2053 vs->features |= VNC_FEATURE_ZRLE_MASK;
2054 vs->vnc_encoding = enc;
2055 break;
2056 case VNC_ENCODING_ZYWRLE:
2057 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2058 vs->vnc_encoding = enc;
2059 break;
2060 case VNC_ENCODING_DESKTOPRESIZE:
2061 vs->features |= VNC_FEATURE_RESIZE_MASK;
2062 break;
2063 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2064 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2065 break;
2066 case VNC_ENCODING_RICH_CURSOR:
2067 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2068 if (vs->vd->cursor) {
2069 vnc_cursor_define(vs);
2071 break;
2072 case VNC_ENCODING_EXT_KEY_EVENT:
2073 send_ext_key_event_ack(vs);
2074 break;
2075 case VNC_ENCODING_AUDIO:
2076 send_ext_audio_ack(vs);
2077 break;
2078 case VNC_ENCODING_WMVi:
2079 vs->features |= VNC_FEATURE_WMVI_MASK;
2080 break;
2081 case VNC_ENCODING_LED_STATE:
2082 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2083 break;
2084 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2085 vs->tight.compression = (enc & 0x0F);
2086 break;
2087 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2088 if (vs->vd->lossy) {
2089 vs->tight.quality = (enc & 0x0F);
2091 break;
2092 default:
2093 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2094 break;
2097 vnc_desktop_resize(vs);
2098 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2099 vnc_led_state_change(vs);
2102 static void set_pixel_conversion(VncState *vs)
2104 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2106 if (fmt == VNC_SERVER_FB_FORMAT) {
2107 vs->write_pixels = vnc_write_pixels_copy;
2108 vnc_hextile_set_pixel_conversion(vs, 0);
2109 } else {
2110 vs->write_pixels = vnc_write_pixels_generic;
2111 vnc_hextile_set_pixel_conversion(vs, 1);
2115 static void send_color_map(VncState *vs)
2117 int i;
2119 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2120 vnc_write_u8(vs, 0); /* padding */
2121 vnc_write_u16(vs, 0); /* first color */
2122 vnc_write_u16(vs, 256); /* # of colors */
2124 for (i = 0; i < 256; i++) {
2125 PixelFormat *pf = &vs->client_pf;
2127 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2128 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2129 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2133 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2134 int big_endian_flag, int true_color_flag,
2135 int red_max, int green_max, int blue_max,
2136 int red_shift, int green_shift, int blue_shift)
2138 if (!true_color_flag) {
2139 /* Expose a reasonable default 256 color map */
2140 bits_per_pixel = 8;
2141 red_max = 7;
2142 green_max = 7;
2143 blue_max = 3;
2144 red_shift = 0;
2145 green_shift = 3;
2146 blue_shift = 6;
2149 switch (bits_per_pixel) {
2150 case 8:
2151 case 16:
2152 case 32:
2153 break;
2154 default:
2155 vnc_client_error(vs);
2156 return;
2159 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2160 vs->client_pf.rbits = hweight_long(red_max);
2161 vs->client_pf.rshift = red_shift;
2162 vs->client_pf.rmask = red_max << red_shift;
2163 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2164 vs->client_pf.gbits = hweight_long(green_max);
2165 vs->client_pf.gshift = green_shift;
2166 vs->client_pf.gmask = green_max << green_shift;
2167 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2168 vs->client_pf.bbits = hweight_long(blue_max);
2169 vs->client_pf.bshift = blue_shift;
2170 vs->client_pf.bmask = blue_max << blue_shift;
2171 vs->client_pf.bits_per_pixel = bits_per_pixel;
2172 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2173 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2174 vs->client_be = big_endian_flag;
2176 if (!true_color_flag) {
2177 send_color_map(vs);
2180 set_pixel_conversion(vs);
2182 graphic_hw_invalidate(vs->vd->dcl.con);
2183 graphic_hw_update(vs->vd->dcl.con);
2186 static void pixel_format_message (VncState *vs) {
2187 char pad[3] = { 0, 0, 0 };
2189 vs->client_pf = qemu_default_pixelformat(32);
2191 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2192 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2194 #ifdef HOST_WORDS_BIGENDIAN
2195 vnc_write_u8(vs, 1); /* big-endian-flag */
2196 #else
2197 vnc_write_u8(vs, 0); /* big-endian-flag */
2198 #endif
2199 vnc_write_u8(vs, 1); /* true-color-flag */
2200 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2201 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2202 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2203 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2204 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2205 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2206 vnc_write(vs, pad, 3); /* padding */
2208 vnc_hextile_set_pixel_conversion(vs, 0);
2209 vs->write_pixels = vnc_write_pixels_copy;
2212 static void vnc_colordepth(VncState *vs)
2214 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2215 /* Sending a WMVi message to notify the client*/
2216 vnc_lock_output(vs);
2217 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2218 vnc_write_u8(vs, 0);
2219 vnc_write_u16(vs, 1); /* number of rects */
2220 vnc_framebuffer_update(vs, 0, 0,
2221 pixman_image_get_width(vs->vd->server),
2222 pixman_image_get_height(vs->vd->server),
2223 VNC_ENCODING_WMVi);
2224 pixel_format_message(vs);
2225 vnc_unlock_output(vs);
2226 vnc_flush(vs);
2227 } else {
2228 set_pixel_conversion(vs);
2232 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2234 int i;
2235 uint16_t limit;
2236 VncDisplay *vd = vs->vd;
2238 if (data[0] > 3) {
2239 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2242 switch (data[0]) {
2243 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2244 if (len == 1)
2245 return 20;
2247 set_pixel_format(vs, read_u8(data, 4),
2248 read_u8(data, 6), read_u8(data, 7),
2249 read_u16(data, 8), read_u16(data, 10),
2250 read_u16(data, 12), read_u8(data, 14),
2251 read_u8(data, 15), read_u8(data, 16));
2252 break;
2253 case VNC_MSG_CLIENT_SET_ENCODINGS:
2254 if (len == 1)
2255 return 4;
2257 if (len == 4) {
2258 limit = read_u16(data, 2);
2259 if (limit > 0)
2260 return 4 + (limit * 4);
2261 } else
2262 limit = read_u16(data, 2);
2264 for (i = 0; i < limit; i++) {
2265 int32_t val = read_s32(data, 4 + (i * 4));
2266 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2269 set_encodings(vs, (int32_t *)(data + 4), limit);
2270 break;
2271 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2272 if (len == 1)
2273 return 10;
2275 framebuffer_update_request(vs,
2276 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2277 read_u16(data, 6), read_u16(data, 8));
2278 break;
2279 case VNC_MSG_CLIENT_KEY_EVENT:
2280 if (len == 1)
2281 return 8;
2283 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2284 break;
2285 case VNC_MSG_CLIENT_POINTER_EVENT:
2286 if (len == 1)
2287 return 6;
2289 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2290 break;
2291 case VNC_MSG_CLIENT_CUT_TEXT:
2292 if (len == 1) {
2293 return 8;
2295 if (len == 8) {
2296 uint32_t dlen = read_u32(data, 4);
2297 if (dlen > (1 << 20)) {
2298 error_report("vnc: client_cut_text msg payload has %u bytes"
2299 " which exceeds our limit of 1MB.", dlen);
2300 vnc_client_error(vs);
2301 break;
2303 if (dlen > 0) {
2304 return 8 + dlen;
2308 client_cut_text(vs, read_u32(data, 4), data + 8);
2309 break;
2310 case VNC_MSG_CLIENT_QEMU:
2311 if (len == 1)
2312 return 2;
2314 switch (read_u8(data, 1)) {
2315 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2316 if (len == 2)
2317 return 12;
2319 ext_key_event(vs, read_u16(data, 2),
2320 read_u32(data, 4), read_u32(data, 8));
2321 break;
2322 case VNC_MSG_CLIENT_QEMU_AUDIO:
2323 if (len == 2)
2324 return 4;
2326 switch (read_u16 (data, 2)) {
2327 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2328 audio_add(vs);
2329 break;
2330 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2331 audio_del(vs);
2332 break;
2333 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2334 if (len == 4)
2335 return 10;
2336 switch (read_u8(data, 4)) {
2337 case 0: vs->as.fmt = AUD_FMT_U8; break;
2338 case 1: vs->as.fmt = AUD_FMT_S8; break;
2339 case 2: vs->as.fmt = AUD_FMT_U16; break;
2340 case 3: vs->as.fmt = AUD_FMT_S16; break;
2341 case 4: vs->as.fmt = AUD_FMT_U32; break;
2342 case 5: vs->as.fmt = AUD_FMT_S32; break;
2343 default:
2344 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2345 vnc_client_error(vs);
2346 break;
2348 vs->as.nchannels = read_u8(data, 5);
2349 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2350 VNC_DEBUG("Invalid audio channel coount %d\n",
2351 read_u8(data, 5));
2352 vnc_client_error(vs);
2353 break;
2355 vs->as.freq = read_u32(data, 6);
2356 break;
2357 default:
2358 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2359 vnc_client_error(vs);
2360 break;
2362 break;
2364 default:
2365 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2366 vnc_client_error(vs);
2367 break;
2369 break;
2370 default:
2371 VNC_DEBUG("Msg: %d\n", data[0]);
2372 vnc_client_error(vs);
2373 break;
2376 vnc_read_when(vs, protocol_client_msg, 1);
2377 return 0;
2380 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2382 char buf[1024];
2383 VncShareMode mode;
2384 int size;
2386 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2387 switch (vs->vd->share_policy) {
2388 case VNC_SHARE_POLICY_IGNORE:
2390 * Ignore the shared flag. Nothing to do here.
2392 * Doesn't conform to the rfb spec but is traditional qemu
2393 * behavior, thus left here as option for compatibility
2394 * reasons.
2396 break;
2397 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2399 * Policy: Allow clients ask for exclusive access.
2401 * Implementation: When a client asks for exclusive access,
2402 * disconnect all others. Shared connects are allowed as long
2403 * as no exclusive connection exists.
2405 * This is how the rfb spec suggests to handle the shared flag.
2407 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2408 VncState *client;
2409 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2410 if (vs == client) {
2411 continue;
2413 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2414 client->share_mode != VNC_SHARE_MODE_SHARED) {
2415 continue;
2417 vnc_disconnect_start(client);
2420 if (mode == VNC_SHARE_MODE_SHARED) {
2421 if (vs->vd->num_exclusive > 0) {
2422 vnc_disconnect_start(vs);
2423 return 0;
2426 break;
2427 case VNC_SHARE_POLICY_FORCE_SHARED:
2429 * Policy: Shared connects only.
2430 * Implementation: Disallow clients asking for exclusive access.
2432 * Useful for shared desktop sessions where you don't want
2433 * someone forgetting to say -shared when running the vnc
2434 * client disconnect everybody else.
2436 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2437 vnc_disconnect_start(vs);
2438 return 0;
2440 break;
2442 vnc_set_share_mode(vs, mode);
2444 if (vs->vd->num_shared > vs->vd->connections_limit) {
2445 vnc_disconnect_start(vs);
2446 return 0;
2449 vs->client_width = pixman_image_get_width(vs->vd->server);
2450 vs->client_height = pixman_image_get_height(vs->vd->server);
2451 vnc_write_u16(vs, vs->client_width);
2452 vnc_write_u16(vs, vs->client_height);
2454 pixel_format_message(vs);
2456 if (qemu_name)
2457 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2458 else
2459 size = snprintf(buf, sizeof(buf), "QEMU");
2461 vnc_write_u32(vs, size);
2462 vnc_write(vs, buf, size);
2463 vnc_flush(vs);
2465 vnc_client_cache_auth(vs);
2466 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2468 vnc_read_when(vs, protocol_client_msg, 1);
2470 return 0;
2473 void start_client_init(VncState *vs)
2475 vnc_read_when(vs, protocol_client_init, 1);
2478 static void make_challenge(VncState *vs)
2480 int i;
2482 srand(time(NULL)+getpid()+getpid()*987654+rand());
2484 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2485 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2488 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2490 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2491 size_t i, pwlen;
2492 unsigned char key[8];
2493 time_t now = time(NULL);
2494 QCryptoCipher *cipher = NULL;
2495 Error *err = NULL;
2497 if (!vs->vd->password) {
2498 VNC_DEBUG("No password configured on server");
2499 goto reject;
2501 if (vs->vd->expires < now) {
2502 VNC_DEBUG("Password is expired");
2503 goto reject;
2506 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2508 /* Calculate the expected challenge response */
2509 pwlen = strlen(vs->vd->password);
2510 for (i=0; i<sizeof(key); i++)
2511 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2513 cipher = qcrypto_cipher_new(
2514 QCRYPTO_CIPHER_ALG_DES_RFB,
2515 QCRYPTO_CIPHER_MODE_ECB,
2516 key, G_N_ELEMENTS(key),
2517 &err);
2518 if (!cipher) {
2519 VNC_DEBUG("Cannot initialize cipher %s",
2520 error_get_pretty(err));
2521 error_free(err);
2522 goto reject;
2525 if (qcrypto_cipher_encrypt(cipher,
2526 vs->challenge,
2527 response,
2528 VNC_AUTH_CHALLENGE_SIZE,
2529 &err) < 0) {
2530 VNC_DEBUG("Cannot encrypt challenge %s",
2531 error_get_pretty(err));
2532 error_free(err);
2533 goto reject;
2536 /* Compare expected vs actual challenge response */
2537 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2538 VNC_DEBUG("Client challenge response did not match\n");
2539 goto reject;
2540 } else {
2541 VNC_DEBUG("Accepting VNC challenge response\n");
2542 vnc_write_u32(vs, 0); /* Accept auth */
2543 vnc_flush(vs);
2545 start_client_init(vs);
2548 qcrypto_cipher_free(cipher);
2549 return 0;
2551 reject:
2552 vnc_write_u32(vs, 1); /* Reject auth */
2553 if (vs->minor >= 8) {
2554 static const char err[] = "Authentication failed";
2555 vnc_write_u32(vs, sizeof(err));
2556 vnc_write(vs, err, sizeof(err));
2558 vnc_flush(vs);
2559 vnc_client_error(vs);
2560 qcrypto_cipher_free(cipher);
2561 return 0;
2564 void start_auth_vnc(VncState *vs)
2566 make_challenge(vs);
2567 /* Send client a 'random' challenge */
2568 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2569 vnc_flush(vs);
2571 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2575 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2577 /* We only advertise 1 auth scheme at a time, so client
2578 * must pick the one we sent. Verify this */
2579 if (data[0] != vs->auth) { /* Reject auth */
2580 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2581 vnc_write_u32(vs, 1);
2582 if (vs->minor >= 8) {
2583 static const char err[] = "Authentication failed";
2584 vnc_write_u32(vs, sizeof(err));
2585 vnc_write(vs, err, sizeof(err));
2587 vnc_client_error(vs);
2588 } else { /* Accept requested auth */
2589 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2590 switch (vs->auth) {
2591 case VNC_AUTH_NONE:
2592 VNC_DEBUG("Accept auth none\n");
2593 if (vs->minor >= 8) {
2594 vnc_write_u32(vs, 0); /* Accept auth completion */
2595 vnc_flush(vs);
2597 start_client_init(vs);
2598 break;
2600 case VNC_AUTH_VNC:
2601 VNC_DEBUG("Start VNC auth\n");
2602 start_auth_vnc(vs);
2603 break;
2605 case VNC_AUTH_VENCRYPT:
2606 VNC_DEBUG("Accept VeNCrypt auth\n");
2607 start_auth_vencrypt(vs);
2608 break;
2610 #ifdef CONFIG_VNC_SASL
2611 case VNC_AUTH_SASL:
2612 VNC_DEBUG("Accept SASL auth\n");
2613 start_auth_sasl(vs);
2614 break;
2615 #endif /* CONFIG_VNC_SASL */
2617 default: /* Should not be possible, but just in case */
2618 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2619 vnc_write_u8(vs, 1);
2620 if (vs->minor >= 8) {
2621 static const char err[] = "Authentication failed";
2622 vnc_write_u32(vs, sizeof(err));
2623 vnc_write(vs, err, sizeof(err));
2625 vnc_client_error(vs);
2628 return 0;
2631 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2633 char local[13];
2635 memcpy(local, version, 12);
2636 local[12] = 0;
2638 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2639 VNC_DEBUG("Malformed protocol version %s\n", local);
2640 vnc_client_error(vs);
2641 return 0;
2643 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2644 if (vs->major != 3 ||
2645 (vs->minor != 3 &&
2646 vs->minor != 4 &&
2647 vs->minor != 5 &&
2648 vs->minor != 7 &&
2649 vs->minor != 8)) {
2650 VNC_DEBUG("Unsupported client version\n");
2651 vnc_write_u32(vs, VNC_AUTH_INVALID);
2652 vnc_flush(vs);
2653 vnc_client_error(vs);
2654 return 0;
2656 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2657 * as equivalent to v3.3 by servers
2659 if (vs->minor == 4 || vs->minor == 5)
2660 vs->minor = 3;
2662 if (vs->minor == 3) {
2663 if (vs->auth == VNC_AUTH_NONE) {
2664 VNC_DEBUG("Tell client auth none\n");
2665 vnc_write_u32(vs, vs->auth);
2666 vnc_flush(vs);
2667 start_client_init(vs);
2668 } else if (vs->auth == VNC_AUTH_VNC) {
2669 VNC_DEBUG("Tell client VNC auth\n");
2670 vnc_write_u32(vs, vs->auth);
2671 vnc_flush(vs);
2672 start_auth_vnc(vs);
2673 } else {
2674 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2675 vnc_write_u32(vs, VNC_AUTH_INVALID);
2676 vnc_flush(vs);
2677 vnc_client_error(vs);
2679 } else {
2680 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2681 vnc_write_u8(vs, 1); /* num auth */
2682 vnc_write_u8(vs, vs->auth);
2683 vnc_read_when(vs, protocol_client_auth, 1);
2684 vnc_flush(vs);
2687 return 0;
2690 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2692 struct VncSurface *vs = &vd->guest;
2694 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2697 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2699 int i, j;
2701 w = (x + w) / VNC_STAT_RECT;
2702 h = (y + h) / VNC_STAT_RECT;
2703 x /= VNC_STAT_RECT;
2704 y /= VNC_STAT_RECT;
2706 for (j = y; j <= h; j++) {
2707 for (i = x; i <= w; i++) {
2708 vs->lossy_rect[j][i] = 1;
2713 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2715 VncState *vs;
2716 int sty = y / VNC_STAT_RECT;
2717 int stx = x / VNC_STAT_RECT;
2718 int has_dirty = 0;
2720 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2721 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2723 QTAILQ_FOREACH(vs, &vd->clients, next) {
2724 int j;
2726 /* kernel send buffers are full -> refresh later */
2727 if (vs->output.offset) {
2728 continue;
2731 if (!vs->lossy_rect[sty][stx]) {
2732 continue;
2735 vs->lossy_rect[sty][stx] = 0;
2736 for (j = 0; j < VNC_STAT_RECT; ++j) {
2737 bitmap_set(vs->dirty[y + j],
2738 x / VNC_DIRTY_PIXELS_PER_BIT,
2739 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2741 has_dirty++;
2744 return has_dirty;
2747 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2749 int width = pixman_image_get_width(vd->guest.fb);
2750 int height = pixman_image_get_height(vd->guest.fb);
2751 int x, y;
2752 struct timeval res;
2753 int has_dirty = 0;
2755 for (y = 0; y < height; y += VNC_STAT_RECT) {
2756 for (x = 0; x < width; x += VNC_STAT_RECT) {
2757 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2759 rect->updated = false;
2763 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2765 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2766 return has_dirty;
2768 vd->guest.last_freq_check = *tv;
2770 for (y = 0; y < height; y += VNC_STAT_RECT) {
2771 for (x = 0; x < width; x += VNC_STAT_RECT) {
2772 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2773 int count = ARRAY_SIZE(rect->times);
2774 struct timeval min, max;
2776 if (!timerisset(&rect->times[count - 1])) {
2777 continue ;
2780 max = rect->times[(rect->idx + count - 1) % count];
2781 qemu_timersub(tv, &max, &res);
2783 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2784 rect->freq = 0;
2785 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2786 memset(rect->times, 0, sizeof (rect->times));
2787 continue ;
2790 min = rect->times[rect->idx];
2791 max = rect->times[(rect->idx + count - 1) % count];
2792 qemu_timersub(&max, &min, &res);
2794 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2795 rect->freq /= count;
2796 rect->freq = 1. / rect->freq;
2799 return has_dirty;
2802 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2804 int i, j;
2805 double total = 0;
2806 int num = 0;
2808 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2809 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2811 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2812 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2813 total += vnc_stat_rect(vs->vd, i, j)->freq;
2814 num++;
2818 if (num) {
2819 return total / num;
2820 } else {
2821 return 0;
2825 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2827 VncRectStat *rect;
2829 rect = vnc_stat_rect(vd, x, y);
2830 if (rect->updated) {
2831 return ;
2833 rect->times[rect->idx] = *tv;
2834 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2835 rect->updated = true;
2838 static int vnc_refresh_server_surface(VncDisplay *vd)
2840 int width = MIN(pixman_image_get_width(vd->guest.fb),
2841 pixman_image_get_width(vd->server));
2842 int height = MIN(pixman_image_get_height(vd->guest.fb),
2843 pixman_image_get_height(vd->server));
2844 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2845 uint8_t *guest_row0 = NULL, *server_row0;
2846 VncState *vs;
2847 int has_dirty = 0;
2848 pixman_image_t *tmpbuf = NULL;
2850 struct timeval tv = { 0, 0 };
2852 if (!vd->non_adaptive) {
2853 gettimeofday(&tv, NULL);
2854 has_dirty = vnc_update_stats(vd, &tv);
2858 * Walk through the guest dirty map.
2859 * Check and copy modified bits from guest to server surface.
2860 * Update server dirty map.
2862 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2863 server_stride = guest_stride = guest_ll =
2864 pixman_image_get_stride(vd->server);
2865 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2866 server_stride);
2867 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2868 int width = pixman_image_get_width(vd->server);
2869 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2870 } else {
2871 int guest_bpp =
2872 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2873 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2874 guest_stride = pixman_image_get_stride(vd->guest.fb);
2875 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2877 line_bytes = MIN(server_stride, guest_ll);
2879 for (;;) {
2880 int x;
2881 uint8_t *guest_ptr, *server_ptr;
2882 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2883 height * VNC_DIRTY_BPL(&vd->guest),
2884 y * VNC_DIRTY_BPL(&vd->guest));
2885 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2886 /* no more dirty bits */
2887 break;
2889 y = offset / VNC_DIRTY_BPL(&vd->guest);
2890 x = offset % VNC_DIRTY_BPL(&vd->guest);
2892 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2894 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2895 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2896 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2897 } else {
2898 guest_ptr = guest_row0 + y * guest_stride;
2900 guest_ptr += x * cmp_bytes;
2902 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2903 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2904 int _cmp_bytes = cmp_bytes;
2905 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2906 continue;
2908 if ((x + 1) * cmp_bytes > line_bytes) {
2909 _cmp_bytes = line_bytes - x * cmp_bytes;
2911 assert(_cmp_bytes >= 0);
2912 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2913 continue;
2915 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2916 if (!vd->non_adaptive) {
2917 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2918 y, &tv);
2920 QTAILQ_FOREACH(vs, &vd->clients, next) {
2921 set_bit(x, vs->dirty[y]);
2923 has_dirty++;
2926 y++;
2928 qemu_pixman_image_unref(tmpbuf);
2929 return has_dirty;
2932 static void vnc_refresh(DisplayChangeListener *dcl)
2934 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2935 VncState *vs, *vn;
2936 int has_dirty, rects = 0;
2938 if (QTAILQ_EMPTY(&vd->clients)) {
2939 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2940 return;
2943 graphic_hw_update(vd->dcl.con);
2945 if (vnc_trylock_display(vd)) {
2946 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2947 return;
2950 has_dirty = vnc_refresh_server_surface(vd);
2951 vnc_unlock_display(vd);
2953 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2954 rects += vnc_update_client(vs, has_dirty, false);
2955 /* vs might be free()ed here */
2958 if (has_dirty && rects) {
2959 vd->dcl.update_interval /= 2;
2960 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2961 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2963 } else {
2964 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2965 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2966 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2971 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2972 bool skipauth, bool websocket)
2974 VncState *vs = g_new0(VncState, 1);
2975 int i;
2977 vs->sioc = sioc;
2978 object_ref(OBJECT(vs->sioc));
2979 vs->ioc = QIO_CHANNEL(sioc);
2980 object_ref(OBJECT(vs->ioc));
2981 vs->vd = vd;
2983 buffer_init(&vs->input, "vnc-input/%p", sioc);
2984 buffer_init(&vs->output, "vnc-output/%p", sioc);
2985 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2987 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2988 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2989 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2990 #ifdef CONFIG_VNC_JPEG
2991 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2992 #endif
2993 #ifdef CONFIG_VNC_PNG
2994 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2995 #endif
2996 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2997 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2998 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2999 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
3001 if (skipauth) {
3002 vs->auth = VNC_AUTH_NONE;
3003 vs->subauth = VNC_AUTH_INVALID;
3004 } else {
3005 if (websocket) {
3006 vs->auth = vd->ws_auth;
3007 vs->subauth = VNC_AUTH_INVALID;
3008 } else {
3009 vs->auth = vd->auth;
3010 vs->subauth = vd->subauth;
3013 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3014 sioc, websocket, vs->auth, vs->subauth);
3016 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3017 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3018 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3021 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3022 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3023 qio_channel_set_blocking(vs->ioc, false, NULL);
3024 if (websocket) {
3025 vs->websocket = 1;
3026 if (vd->ws_tls) {
3027 vs->ioc_tag = qio_channel_add_watch(
3028 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3029 } else {
3030 vs->ioc_tag = qio_channel_add_watch(
3031 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
3033 } else {
3034 vs->ioc_tag = qio_channel_add_watch(
3035 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
3038 vnc_client_cache_addr(vs);
3039 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3040 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3042 if (!vs->websocket) {
3043 vnc_init_state(vs);
3046 if (vd->num_connecting > vd->connections_limit) {
3047 QTAILQ_FOREACH(vs, &vd->clients, next) {
3048 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3049 vnc_disconnect_start(vs);
3050 return;
3056 void vnc_init_state(VncState *vs)
3058 vs->initialized = true;
3059 VncDisplay *vd = vs->vd;
3060 bool first_client = QTAILQ_EMPTY(&vd->clients);
3062 vs->last_x = -1;
3063 vs->last_y = -1;
3065 vs->as.freq = 44100;
3066 vs->as.nchannels = 2;
3067 vs->as.fmt = AUD_FMT_S16;
3068 vs->as.endianness = 0;
3070 qemu_mutex_init(&vs->output_mutex);
3071 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3073 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3074 if (first_client) {
3075 vnc_update_server_surface(vd);
3078 graphic_hw_update(vd->dcl.con);
3080 vnc_write(vs, "RFB 003.008\n", 12);
3081 vnc_flush(vs);
3082 vnc_read_when(vs, protocol_version, 12);
3083 reset_keys(vs);
3084 if (vs->vd->lock_key_sync)
3085 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3087 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3088 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3090 /* vs might be free()ed here */
3093 static gboolean vnc_listen_io(QIOChannel *ioc,
3094 GIOCondition condition,
3095 void *opaque)
3097 VncDisplay *vs = opaque;
3098 QIOChannelSocket *sioc = NULL;
3099 Error *err = NULL;
3101 /* Catch-up */
3102 graphic_hw_update(vs->dcl.con);
3103 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3104 if (sioc != NULL) {
3105 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3106 vnc_connect(vs, sioc, false,
3107 ioc != QIO_CHANNEL(vs->lsock));
3108 object_unref(OBJECT(sioc));
3109 } else {
3110 /* client probably closed connection before we got there */
3111 error_free(err);
3114 return TRUE;
3117 static const DisplayChangeListenerOps dcl_ops = {
3118 .dpy_name = "vnc",
3119 .dpy_refresh = vnc_refresh,
3120 .dpy_gfx_copy = vnc_dpy_copy,
3121 .dpy_gfx_update = vnc_dpy_update,
3122 .dpy_gfx_switch = vnc_dpy_switch,
3123 .dpy_gfx_check_format = qemu_pixman_check_format,
3124 .dpy_mouse_set = vnc_mouse_set,
3125 .dpy_cursor_define = vnc_dpy_cursor_define,
3128 void vnc_display_init(const char *id)
3130 VncDisplay *vs;
3132 if (vnc_display_find(id) != NULL) {
3133 return;
3135 vs = g_malloc0(sizeof(*vs));
3137 vs->id = strdup(id);
3138 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3140 QTAILQ_INIT(&vs->clients);
3141 vs->expires = TIME_MAX;
3143 if (keyboard_layout) {
3144 trace_vnc_key_map_init(keyboard_layout);
3145 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3146 } else {
3147 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3150 if (!vs->kbd_layout)
3151 exit(1);
3153 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3154 vs->connections_limit = 32;
3156 qemu_mutex_init(&vs->mutex);
3157 vnc_start_worker_thread();
3159 vs->dcl.ops = &dcl_ops;
3160 register_displaychangelistener(&vs->dcl);
3164 static void vnc_display_close(VncDisplay *vs)
3166 if (!vs)
3167 return;
3168 vs->enabled = false;
3169 vs->is_unix = false;
3170 if (vs->lsock != NULL) {
3171 if (vs->lsock_tag) {
3172 g_source_remove(vs->lsock_tag);
3174 object_unref(OBJECT(vs->lsock));
3175 vs->lsock = NULL;
3177 vs->ws_enabled = false;
3178 if (vs->lwebsock != NULL) {
3179 if (vs->lwebsock_tag) {
3180 g_source_remove(vs->lwebsock_tag);
3182 object_unref(OBJECT(vs->lwebsock));
3183 vs->lwebsock = NULL;
3185 vs->auth = VNC_AUTH_INVALID;
3186 vs->subauth = VNC_AUTH_INVALID;
3187 if (vs->tlscreds) {
3188 object_unparent(OBJECT(vs->tlscreds));
3189 vs->tlscreds = NULL;
3191 g_free(vs->tlsaclname);
3192 vs->tlsaclname = NULL;
3195 int vnc_display_password(const char *id, const char *password)
3197 VncDisplay *vs = vnc_display_find(id);
3199 if (!vs) {
3200 return -EINVAL;
3202 if (vs->auth == VNC_AUTH_NONE) {
3203 error_printf_unless_qmp("If you want use passwords please enable "
3204 "password auth using '-vnc ${dpy},password'.\n");
3205 return -EINVAL;
3208 g_free(vs->password);
3209 vs->password = g_strdup(password);
3211 return 0;
3214 int vnc_display_pw_expire(const char *id, time_t expires)
3216 VncDisplay *vs = vnc_display_find(id);
3218 if (!vs) {
3219 return -EINVAL;
3222 vs->expires = expires;
3223 return 0;
3226 static void vnc_display_print_local_addr(VncDisplay *vs)
3228 SocketAddress *addr;
3229 Error *err = NULL;
3231 addr = qio_channel_socket_get_local_address(vs->lsock, &err);
3232 if (!addr) {
3233 return;
3236 if (addr->type != SOCKET_ADDRESS_KIND_INET) {
3237 qapi_free_SocketAddress(addr);
3238 return;
3240 error_printf_unless_qmp("VNC server running on %s:%s\n",
3241 addr->u.inet.data->host,
3242 addr->u.inet.data->port);
3243 qapi_free_SocketAddress(addr);
3246 static QemuOptsList qemu_vnc_opts = {
3247 .name = "vnc",
3248 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3249 .implied_opt_name = "vnc",
3250 .desc = {
3252 .name = "vnc",
3253 .type = QEMU_OPT_STRING,
3255 .name = "websocket",
3256 .type = QEMU_OPT_STRING,
3258 .name = "tls-creds",
3259 .type = QEMU_OPT_STRING,
3261 /* Deprecated in favour of tls-creds */
3262 .name = "x509",
3263 .type = QEMU_OPT_STRING,
3265 .name = "share",
3266 .type = QEMU_OPT_STRING,
3268 .name = "display",
3269 .type = QEMU_OPT_STRING,
3271 .name = "head",
3272 .type = QEMU_OPT_NUMBER,
3274 .name = "connections",
3275 .type = QEMU_OPT_NUMBER,
3277 .name = "to",
3278 .type = QEMU_OPT_NUMBER,
3280 .name = "ipv4",
3281 .type = QEMU_OPT_BOOL,
3283 .name = "ipv6",
3284 .type = QEMU_OPT_BOOL,
3286 .name = "password",
3287 .type = QEMU_OPT_BOOL,
3289 .name = "reverse",
3290 .type = QEMU_OPT_BOOL,
3292 .name = "lock-key-sync",
3293 .type = QEMU_OPT_BOOL,
3295 .name = "key-delay-ms",
3296 .type = QEMU_OPT_NUMBER,
3298 .name = "sasl",
3299 .type = QEMU_OPT_BOOL,
3301 /* Deprecated in favour of tls-creds */
3302 .name = "tls",
3303 .type = QEMU_OPT_BOOL,
3305 /* Deprecated in favour of tls-creds */
3306 .name = "x509verify",
3307 .type = QEMU_OPT_STRING,
3309 .name = "acl",
3310 .type = QEMU_OPT_BOOL,
3312 .name = "lossy",
3313 .type = QEMU_OPT_BOOL,
3315 .name = "non-adaptive",
3316 .type = QEMU_OPT_BOOL,
3318 { /* end of list */ }
3323 static int
3324 vnc_display_setup_auth(VncDisplay *vs,
3325 bool password,
3326 bool sasl,
3327 bool websocket,
3328 Error **errp)
3331 * We have a choice of 3 authentication options
3333 * 1. none
3334 * 2. vnc
3335 * 3. sasl
3337 * The channel can be run in 2 modes
3339 * 1. clear
3340 * 2. tls
3342 * And TLS can use 2 types of credentials
3344 * 1. anon
3345 * 2. x509
3347 * We thus have 9 possible logical combinations
3349 * 1. clear + none
3350 * 2. clear + vnc
3351 * 3. clear + sasl
3352 * 4. tls + anon + none
3353 * 5. tls + anon + vnc
3354 * 6. tls + anon + sasl
3355 * 7. tls + x509 + none
3356 * 8. tls + x509 + vnc
3357 * 9. tls + x509 + sasl
3359 * These need to be mapped into the VNC auth schemes
3360 * in an appropriate manner. In regular VNC, all the
3361 * TLS options get mapped into VNC_AUTH_VENCRYPT
3362 * sub-auth types.
3364 * In websockets, the https:// protocol already provides
3365 * TLS support, so there is no need to make use of the
3366 * VeNCrypt extension. Furthermore, websockets browser
3367 * clients could not use VeNCrypt even if they wanted to,
3368 * as they cannot control when the TLS handshake takes
3369 * place. Thus there is no option but to rely on https://,
3370 * meaning combinations 4->6 and 7->9 will be mapped to
3371 * VNC auth schemes in the same way as combos 1->3.
3373 * Regardless of fact that we have a different mapping to
3374 * VNC auth mechs for plain VNC vs websockets VNC, the end
3375 * result has the same security characteristics.
3377 if (password) {
3378 if (vs->tlscreds) {
3379 vs->auth = VNC_AUTH_VENCRYPT;
3380 if (websocket) {
3381 vs->ws_tls = true;
3383 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3384 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3385 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3386 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3387 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3388 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3389 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3390 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3391 } else {
3392 error_setg(errp,
3393 "Unsupported TLS cred type %s",
3394 object_get_typename(OBJECT(vs->tlscreds)));
3395 return -1;
3397 } else {
3398 VNC_DEBUG("Initializing VNC server with password auth\n");
3399 vs->auth = VNC_AUTH_VNC;
3400 vs->subauth = VNC_AUTH_INVALID;
3402 if (websocket) {
3403 vs->ws_auth = VNC_AUTH_VNC;
3404 } else {
3405 vs->ws_auth = VNC_AUTH_INVALID;
3407 } else if (sasl) {
3408 if (vs->tlscreds) {
3409 vs->auth = VNC_AUTH_VENCRYPT;
3410 if (websocket) {
3411 vs->ws_tls = true;
3413 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3414 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3415 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3416 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3417 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3418 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3419 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3420 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3421 } else {
3422 error_setg(errp,
3423 "Unsupported TLS cred type %s",
3424 object_get_typename(OBJECT(vs->tlscreds)));
3425 return -1;
3427 } else {
3428 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3429 vs->auth = VNC_AUTH_SASL;
3430 vs->subauth = VNC_AUTH_INVALID;
3432 if (websocket) {
3433 vs->ws_auth = VNC_AUTH_SASL;
3434 } else {
3435 vs->ws_auth = VNC_AUTH_INVALID;
3437 } else {
3438 if (vs->tlscreds) {
3439 vs->auth = VNC_AUTH_VENCRYPT;
3440 if (websocket) {
3441 vs->ws_tls = true;
3443 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3444 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3445 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3446 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3447 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3448 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3449 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3450 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3451 } else {
3452 error_setg(errp,
3453 "Unsupported TLS cred type %s",
3454 object_get_typename(OBJECT(vs->tlscreds)));
3455 return -1;
3457 } else {
3458 VNC_DEBUG("Initializing VNC server with no auth\n");
3459 vs->auth = VNC_AUTH_NONE;
3460 vs->subauth = VNC_AUTH_INVALID;
3462 if (websocket) {
3463 vs->ws_auth = VNC_AUTH_NONE;
3464 } else {
3465 vs->ws_auth = VNC_AUTH_INVALID;
3468 return 0;
3473 * Handle back compat with old CLI syntax by creating some
3474 * suitable QCryptoTLSCreds objects
3476 static QCryptoTLSCreds *
3477 vnc_display_create_creds(bool x509,
3478 bool x509verify,
3479 const char *dir,
3480 const char *id,
3481 Error **errp)
3483 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3484 Object *parent = object_get_objects_root();
3485 Object *creds;
3486 Error *err = NULL;
3488 if (x509) {
3489 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3490 parent,
3491 credsid,
3492 &err,
3493 "endpoint", "server",
3494 "dir", dir,
3495 "verify-peer", x509verify ? "yes" : "no",
3496 NULL);
3497 } else {
3498 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3499 parent,
3500 credsid,
3501 &err,
3502 "endpoint", "server",
3503 NULL);
3506 g_free(credsid);
3508 if (err) {
3509 error_propagate(errp, err);
3510 return NULL;
3513 return QCRYPTO_TLS_CREDS(creds);
3517 void vnc_display_open(const char *id, Error **errp)
3519 VncDisplay *vs = vnc_display_find(id);
3520 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3521 SocketAddress *saddr = NULL, *wsaddr = NULL;
3522 const char *share, *device_id;
3523 QemuConsole *con;
3524 bool password = false;
3525 bool reverse = false;
3526 const char *vnc;
3527 char *h;
3528 const char *credid;
3529 int show_vnc_port = 0;
3530 bool sasl = false;
3531 #ifdef CONFIG_VNC_SASL
3532 int saslErr;
3533 #endif
3534 int acl = 0;
3535 int lock_key_sync = 1;
3536 int key_delay_ms;
3538 if (!vs) {
3539 error_setg(errp, "VNC display not active");
3540 return;
3542 vnc_display_close(vs);
3544 if (!opts) {
3545 return;
3547 vnc = qemu_opt_get(opts, "vnc");
3548 if (!vnc || strcmp(vnc, "none") == 0) {
3549 return;
3552 h = strrchr(vnc, ':');
3553 if (h) {
3554 size_t hlen = h - vnc;
3556 const char *websocket = qemu_opt_get(opts, "websocket");
3557 int to = qemu_opt_get_number(opts, "to", 0);
3558 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3559 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3560 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3561 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3563 saddr = g_new0(SocketAddress, 1);
3564 if (websocket) {
3565 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3566 error_setg(errp,
3567 "SHA1 hash support is required for websockets");
3568 goto fail;
3571 wsaddr = g_new0(SocketAddress, 1);
3572 vs->ws_enabled = true;
3575 if (strncmp(vnc, "unix:", 5) == 0) {
3576 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3577 saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
3578 saddr->u.q_unix.data->path = g_strdup(vnc + 5);
3580 if (vs->ws_enabled) {
3581 error_setg(errp, "UNIX sockets not supported with websock");
3582 goto fail;
3584 } else {
3585 unsigned long long baseport;
3586 InetSocketAddress *inet;
3587 saddr->type = SOCKET_ADDRESS_KIND_INET;
3588 inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
3589 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3590 inet->host = g_strndup(vnc + 1, hlen - 2);
3591 } else {
3592 inet->host = g_strndup(vnc, hlen);
3594 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3595 error_setg(errp, "can't convert to a number: %s", h + 1);
3596 goto fail;
3598 if (baseport > 65535 ||
3599 baseport + 5900 > 65535) {
3600 error_setg(errp, "port %s out of range", h + 1);
3601 goto fail;
3603 inet->port = g_strdup_printf(
3604 "%d", (int)baseport + 5900);
3606 if (to) {
3607 inet->has_to = true;
3608 inet->to = to + 5900;
3609 show_vnc_port = 1;
3611 inet->ipv4 = ipv4;
3612 inet->has_ipv4 = has_ipv4;
3613 inet->ipv6 = ipv6;
3614 inet->has_ipv6 = has_ipv6;
3616 if (vs->ws_enabled) {
3617 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3618 inet = wsaddr->u.inet.data = g_new0(InetSocketAddress, 1);
3619 inet->host = g_strdup(saddr->u.inet.data->host);
3620 inet->port = g_strdup(websocket);
3622 if (to) {
3623 inet->has_to = true;
3624 inet->to = to;
3626 inet->ipv4 = ipv4;
3627 inet->has_ipv4 = has_ipv4;
3628 inet->ipv6 = ipv6;
3629 inet->has_ipv6 = has_ipv6;
3632 } else {
3633 error_setg(errp, "no vnc port specified");
3634 goto fail;
3637 password = qemu_opt_get_bool(opts, "password", false);
3638 if (password) {
3639 if (fips_get_state()) {
3640 error_setg(errp,
3641 "VNC password auth disabled due to FIPS mode, "
3642 "consider using the VeNCrypt or SASL authentication "
3643 "methods as an alternative");
3644 goto fail;
3646 if (!qcrypto_cipher_supports(
3647 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3648 error_setg(errp,
3649 "Cipher backend does not support DES RFB algorithm");
3650 goto fail;
3654 reverse = qemu_opt_get_bool(opts, "reverse", false);
3655 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3656 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
3657 sasl = qemu_opt_get_bool(opts, "sasl", false);
3658 #ifndef CONFIG_VNC_SASL
3659 if (sasl) {
3660 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3661 goto fail;
3663 #endif /* CONFIG_VNC_SASL */
3664 credid = qemu_opt_get(opts, "tls-creds");
3665 if (credid) {
3666 Object *creds;
3667 if (qemu_opt_get(opts, "tls") ||
3668 qemu_opt_get(opts, "x509") ||
3669 qemu_opt_get(opts, "x509verify")) {
3670 error_setg(errp,
3671 "'tls-creds' parameter is mutually exclusive with "
3672 "'tls', 'x509' and 'x509verify' parameters");
3673 goto fail;
3676 creds = object_resolve_path_component(
3677 object_get_objects_root(), credid);
3678 if (!creds) {
3679 error_setg(errp, "No TLS credentials with id '%s'",
3680 credid);
3681 goto fail;
3683 vs->tlscreds = (QCryptoTLSCreds *)
3684 object_dynamic_cast(creds,
3685 TYPE_QCRYPTO_TLS_CREDS);
3686 if (!vs->tlscreds) {
3687 error_setg(errp, "Object with id '%s' is not TLS credentials",
3688 credid);
3689 goto fail;
3691 object_ref(OBJECT(vs->tlscreds));
3693 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3694 error_setg(errp,
3695 "Expecting TLS credentials with a server endpoint");
3696 goto fail;
3698 } else {
3699 const char *path;
3700 bool tls = false, x509 = false, x509verify = false;
3701 tls = qemu_opt_get_bool(opts, "tls", false);
3702 if (tls) {
3703 path = qemu_opt_get(opts, "x509");
3705 if (path) {
3706 x509 = true;
3707 } else {
3708 path = qemu_opt_get(opts, "x509verify");
3709 if (path) {
3710 x509 = true;
3711 x509verify = true;
3714 vs->tlscreds = vnc_display_create_creds(x509,
3715 x509verify,
3716 path,
3717 vs->id,
3718 errp);
3719 if (!vs->tlscreds) {
3720 goto fail;
3724 acl = qemu_opt_get_bool(opts, "acl", false);
3726 share = qemu_opt_get(opts, "share");
3727 if (share) {
3728 if (strcmp(share, "ignore") == 0) {
3729 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3730 } else if (strcmp(share, "allow-exclusive") == 0) {
3731 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3732 } else if (strcmp(share, "force-shared") == 0) {
3733 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3734 } else {
3735 error_setg(errp, "unknown vnc share= option");
3736 goto fail;
3738 } else {
3739 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3741 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3743 #ifdef CONFIG_VNC_JPEG
3744 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3745 #endif
3746 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3747 /* adaptive updates are only used with tight encoding and
3748 * if lossy updates are enabled so we can disable all the
3749 * calculations otherwise */
3750 if (!vs->lossy) {
3751 vs->non_adaptive = true;
3754 if (acl) {
3755 if (strcmp(vs->id, "default") == 0) {
3756 vs->tlsaclname = g_strdup("vnc.x509dname");
3757 } else {
3758 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3760 qemu_acl_init(vs->tlsaclname);
3762 #ifdef CONFIG_VNC_SASL
3763 if (acl && sasl) {
3764 char *aclname;
3766 if (strcmp(vs->id, "default") == 0) {
3767 aclname = g_strdup("vnc.username");
3768 } else {
3769 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3771 vs->sasl.acl = qemu_acl_init(aclname);
3772 g_free(aclname);
3774 #endif
3776 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3777 goto fail;
3780 #ifdef CONFIG_VNC_SASL
3781 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3782 error_setg(errp, "Failed to initialize SASL auth: %s",
3783 sasl_errstring(saslErr, NULL, NULL));
3784 goto fail;
3786 #endif
3787 vs->lock_key_sync = lock_key_sync;
3788 vs->key_delay_ms = key_delay_ms;
3790 device_id = qemu_opt_get(opts, "display");
3791 if (device_id) {
3792 int head = qemu_opt_get_number(opts, "head", 0);
3793 Error *err = NULL;
3795 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3796 if (err) {
3797 error_propagate(errp, err);
3798 goto fail;
3800 } else {
3801 con = NULL;
3804 if (con != vs->dcl.con) {
3805 unregister_displaychangelistener(&vs->dcl);
3806 vs->dcl.con = con;
3807 register_displaychangelistener(&vs->dcl);
3810 if (reverse) {
3811 /* connect to viewer */
3812 QIOChannelSocket *sioc = NULL;
3813 vs->lsock = NULL;
3814 vs->lwebsock = NULL;
3815 if (vs->ws_enabled) {
3816 error_setg(errp, "Cannot use websockets in reverse mode");
3817 goto fail;
3819 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3820 sioc = qio_channel_socket_new();
3821 if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
3822 goto fail;
3824 vnc_connect(vs, sioc, false, false);
3825 object_unref(OBJECT(sioc));
3826 } else {
3827 vs->lsock = qio_channel_socket_new();
3828 if (qio_channel_socket_listen_sync(vs->lsock, saddr, errp) < 0) {
3829 goto fail;
3831 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3832 vs->enabled = true;
3834 if (vs->ws_enabled) {
3835 vs->lwebsock = qio_channel_socket_new();
3836 if (qio_channel_socket_listen_sync(vs->lwebsock,
3837 wsaddr, errp) < 0) {
3838 object_unref(OBJECT(vs->lsock));
3839 vs->lsock = NULL;
3840 goto fail;
3844 vs->lsock_tag = qio_channel_add_watch(
3845 QIO_CHANNEL(vs->lsock),
3846 G_IO_IN, vnc_listen_io, vs, NULL);
3847 if (vs->ws_enabled) {
3848 vs->lwebsock_tag = qio_channel_add_watch(
3849 QIO_CHANNEL(vs->lwebsock),
3850 G_IO_IN, vnc_listen_io, vs, NULL);
3854 if (show_vnc_port) {
3855 vnc_display_print_local_addr(vs);
3858 qapi_free_SocketAddress(saddr);
3859 qapi_free_SocketAddress(wsaddr);
3860 return;
3862 fail:
3863 qapi_free_SocketAddress(saddr);
3864 qapi_free_SocketAddress(wsaddr);
3865 vs->enabled = false;
3866 vs->ws_enabled = false;
3869 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3871 VncDisplay *vs = vnc_display_find(id);
3872 QIOChannelSocket *sioc;
3874 if (!vs) {
3875 return;
3878 sioc = qio_channel_socket_new_fd(csock, NULL);
3879 if (sioc) {
3880 vnc_connect(vs, sioc, skipauth, false);
3881 object_unref(OBJECT(sioc));
3885 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3887 int i = 2;
3888 char *id;
3890 id = g_strdup("default");
3891 while (qemu_opts_find(olist, id)) {
3892 g_free(id);
3893 id = g_strdup_printf("vnc%d", i++);
3895 qemu_opts_set_id(opts, id);
3898 QemuOpts *vnc_parse(const char *str, Error **errp)
3900 QemuOptsList *olist = qemu_find_opts("vnc");
3901 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3902 const char *id;
3904 if (!opts) {
3905 return NULL;
3908 id = qemu_opts_id(opts);
3909 if (!id) {
3910 /* auto-assign id if not present */
3911 vnc_auto_assign_id(olist, opts);
3913 return opts;
3916 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3918 Error *local_err = NULL;
3919 char *id = (char *)qemu_opts_id(opts);
3921 assert(id);
3922 vnc_display_init(id);
3923 vnc_display_open(id, &local_err);
3924 if (local_err != NULL) {
3925 error_reportf_err(local_err, "Failed to start VNC server: ");
3926 exit(1);
3928 return 0;
3931 static void vnc_register_config(void)
3933 qemu_add_opts(&qemu_vnc_opts);
3935 opts_init(vnc_register_config);