ui: add tracing of VNC authentication process
[qemu/armbru.git] / ui / vnc.c
blobaf810f0547e905b2b992599cc51377c66f9fc463
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 "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
35 #include "qemu/acl.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.h"
40 #include "ui/input.h"
41 #include "qapi-event.h"
42 #include "crypto/hash.h"
43 #include "crypto/tlscredsanon.h"
44 #include "crypto/tlscredsx509.h"
45 #include "qom/object_interfaces.h"
46 #include "qemu/cutils.h"
47 #include "io/dns-resolver.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_TYPE_INET:
116 info->host = g_strdup(addr->u.inet.host);
117 info->service = g_strdup(addr->u.inet.port);
118 if (addr->u.inet.ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_TYPE_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 case SOCKET_ADDRESS_TYPE_VSOCK:
132 case SOCKET_ADDRESS_TYPE_FD:
133 error_setg(errp, "Unsupported socket address type %s",
134 SocketAddressType_str(addr->type));
135 break;
136 default:
137 abort();
140 return;
143 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
144 VncBasicInfo *info,
145 Error **errp)
147 SocketAddress *addr = NULL;
149 if (!ioc) {
150 error_setg(errp, "No listener socket available");
151 return;
154 addr = qio_channel_socket_get_local_address(ioc, errp);
155 if (!addr) {
156 return;
159 vnc_init_basic_info(addr, info, errp);
160 qapi_free_SocketAddress(addr);
163 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
164 VncBasicInfo *info,
165 Error **errp)
167 SocketAddress *addr = NULL;
169 addr = qio_channel_socket_get_remote_address(ioc, errp);
170 if (!addr) {
171 return;
174 vnc_init_basic_info(addr, info, errp);
175 qapi_free_SocketAddress(addr);
178 static const char *vnc_auth_name(VncDisplay *vd) {
179 switch (vd->auth) {
180 case VNC_AUTH_INVALID:
181 return "invalid";
182 case VNC_AUTH_NONE:
183 return "none";
184 case VNC_AUTH_VNC:
185 return "vnc";
186 case VNC_AUTH_RA2:
187 return "ra2";
188 case VNC_AUTH_RA2NE:
189 return "ra2ne";
190 case VNC_AUTH_TIGHT:
191 return "tight";
192 case VNC_AUTH_ULTRA:
193 return "ultra";
194 case VNC_AUTH_TLS:
195 return "tls";
196 case VNC_AUTH_VENCRYPT:
197 switch (vd->subauth) {
198 case VNC_AUTH_VENCRYPT_PLAIN:
199 return "vencrypt+plain";
200 case VNC_AUTH_VENCRYPT_TLSNONE:
201 return "vencrypt+tls+none";
202 case VNC_AUTH_VENCRYPT_TLSVNC:
203 return "vencrypt+tls+vnc";
204 case VNC_AUTH_VENCRYPT_TLSPLAIN:
205 return "vencrypt+tls+plain";
206 case VNC_AUTH_VENCRYPT_X509NONE:
207 return "vencrypt+x509+none";
208 case VNC_AUTH_VENCRYPT_X509VNC:
209 return "vencrypt+x509+vnc";
210 case VNC_AUTH_VENCRYPT_X509PLAIN:
211 return "vencrypt+x509+plain";
212 case VNC_AUTH_VENCRYPT_TLSSASL:
213 return "vencrypt+tls+sasl";
214 case VNC_AUTH_VENCRYPT_X509SASL:
215 return "vencrypt+x509+sasl";
216 default:
217 return "vencrypt";
219 case VNC_AUTH_SASL:
220 return "sasl";
222 return "unknown";
225 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
227 VncServerInfo *info;
228 Error *err = NULL;
230 if (!vd->nlsock) {
231 return NULL;
234 info = g_malloc0(sizeof(*info));
235 vnc_init_basic_info_from_server_addr(vd->lsock[0],
236 qapi_VncServerInfo_base(info), &err);
237 info->has_auth = true;
238 info->auth = g_strdup(vnc_auth_name(vd));
239 if (err) {
240 qapi_free_VncServerInfo(info);
241 info = NULL;
242 error_free(err);
244 return info;
247 static void vnc_client_cache_auth(VncState *client)
249 if (!client->info) {
250 return;
253 if (client->tls) {
254 client->info->x509_dname =
255 qcrypto_tls_session_get_peer_name(client->tls);
256 client->info->has_x509_dname =
257 client->info->x509_dname != NULL;
259 #ifdef CONFIG_VNC_SASL
260 if (client->sasl.conn &&
261 client->sasl.username) {
262 client->info->has_sasl_username = true;
263 client->info->sasl_username = g_strdup(client->sasl.username);
265 #endif
268 static void vnc_client_cache_addr(VncState *client)
270 Error *err = NULL;
272 client->info = g_malloc0(sizeof(*client->info));
273 vnc_init_basic_info_from_remote_addr(client->sioc,
274 qapi_VncClientInfo_base(client->info),
275 &err);
276 if (err) {
277 qapi_free_VncClientInfo(client->info);
278 client->info = NULL;
279 error_free(err);
283 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
285 VncServerInfo *si;
287 if (!vs->info) {
288 return;
291 si = vnc_server_info_get(vs->vd);
292 if (!si) {
293 return;
296 switch (event) {
297 case QAPI_EVENT_VNC_CONNECTED:
298 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
299 &error_abort);
300 break;
301 case QAPI_EVENT_VNC_INITIALIZED:
302 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
303 break;
304 case QAPI_EVENT_VNC_DISCONNECTED:
305 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
306 break;
307 default:
308 break;
311 qapi_free_VncServerInfo(si);
314 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
316 VncClientInfo *info;
317 Error *err = NULL;
319 info = g_malloc0(sizeof(*info));
321 vnc_init_basic_info_from_remote_addr(client->sioc,
322 qapi_VncClientInfo_base(info),
323 &err);
324 if (err) {
325 error_free(err);
326 qapi_free_VncClientInfo(info);
327 return NULL;
330 info->websocket = client->websocket;
332 if (client->tls) {
333 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
334 info->has_x509_dname = info->x509_dname != NULL;
336 #ifdef CONFIG_VNC_SASL
337 if (client->sasl.conn && client->sasl.username) {
338 info->has_sasl_username = true;
339 info->sasl_username = g_strdup(client->sasl.username);
341 #endif
343 return info;
346 static VncDisplay *vnc_display_find(const char *id)
348 VncDisplay *vd;
350 if (id == NULL) {
351 return QTAILQ_FIRST(&vnc_displays);
353 QTAILQ_FOREACH(vd, &vnc_displays, next) {
354 if (strcmp(id, vd->id) == 0) {
355 return vd;
358 return NULL;
361 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
363 VncClientInfoList *cinfo, *prev = NULL;
364 VncState *client;
366 QTAILQ_FOREACH(client, &vd->clients, next) {
367 cinfo = g_new0(VncClientInfoList, 1);
368 cinfo->value = qmp_query_vnc_client(client);
369 cinfo->next = prev;
370 prev = cinfo;
372 return prev;
375 VncInfo *qmp_query_vnc(Error **errp)
377 VncInfo *info = g_malloc0(sizeof(*info));
378 VncDisplay *vd = vnc_display_find(NULL);
379 SocketAddress *addr = NULL;
381 if (vd == NULL || !vd->nlsock) {
382 info->enabled = false;
383 } else {
384 info->enabled = true;
386 /* for compatibility with the original command */
387 info->has_clients = true;
388 info->clients = qmp_query_client_list(vd);
390 if (vd->lsock == NULL) {
391 return info;
394 addr = qio_channel_socket_get_local_address(vd->lsock[0], errp);
395 if (!addr) {
396 goto out_error;
399 switch (addr->type) {
400 case SOCKET_ADDRESS_TYPE_INET:
401 info->host = g_strdup(addr->u.inet.host);
402 info->service = g_strdup(addr->u.inet.port);
403 if (addr->u.inet.ipv6) {
404 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
405 } else {
406 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
408 break;
410 case SOCKET_ADDRESS_TYPE_UNIX:
411 info->host = g_strdup("");
412 info->service = g_strdup(addr->u.q_unix.path);
413 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
414 break;
416 case SOCKET_ADDRESS_TYPE_VSOCK:
417 case SOCKET_ADDRESS_TYPE_FD:
418 error_setg(errp, "Unsupported socket address type %s",
419 SocketAddressType_str(addr->type));
420 goto out_error;
421 default:
422 abort();
425 info->has_host = true;
426 info->has_service = true;
427 info->has_family = true;
429 info->has_auth = true;
430 info->auth = g_strdup(vnc_auth_name(vd));
433 qapi_free_SocketAddress(addr);
434 return info;
436 out_error:
437 qapi_free_SocketAddress(addr);
438 qapi_free_VncInfo(info);
439 return NULL;
443 static void qmp_query_auth(int auth, int subauth,
444 VncPrimaryAuth *qmp_auth,
445 VncVencryptSubAuth *qmp_vencrypt,
446 bool *qmp_has_vencrypt);
448 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
449 bool websocket,
450 int auth,
451 int subauth,
452 VncServerInfo2List *prev)
454 VncServerInfo2List *list;
455 VncServerInfo2 *info;
456 Error *err = NULL;
457 SocketAddress *addr;
459 addr = qio_channel_socket_get_local_address(ioc, &err);
460 if (!addr) {
461 error_free(err);
462 return prev;
465 info = g_new0(VncServerInfo2, 1);
466 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
467 qapi_free_SocketAddress(addr);
468 if (err) {
469 qapi_free_VncServerInfo2(info);
470 error_free(err);
471 return prev;
473 info->websocket = websocket;
475 qmp_query_auth(auth, subauth, &info->auth,
476 &info->vencrypt, &info->has_vencrypt);
478 list = g_new0(VncServerInfo2List, 1);
479 list->value = info;
480 list->next = prev;
481 return list;
484 static void qmp_query_auth(int auth, int subauth,
485 VncPrimaryAuth *qmp_auth,
486 VncVencryptSubAuth *qmp_vencrypt,
487 bool *qmp_has_vencrypt)
489 switch (auth) {
490 case VNC_AUTH_VNC:
491 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
492 break;
493 case VNC_AUTH_RA2:
494 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
495 break;
496 case VNC_AUTH_RA2NE:
497 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
498 break;
499 case VNC_AUTH_TIGHT:
500 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
501 break;
502 case VNC_AUTH_ULTRA:
503 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
504 break;
505 case VNC_AUTH_TLS:
506 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
507 break;
508 case VNC_AUTH_VENCRYPT:
509 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
510 *qmp_has_vencrypt = true;
511 switch (subauth) {
512 case VNC_AUTH_VENCRYPT_PLAIN:
513 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
514 break;
515 case VNC_AUTH_VENCRYPT_TLSNONE:
516 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
517 break;
518 case VNC_AUTH_VENCRYPT_TLSVNC:
519 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
520 break;
521 case VNC_AUTH_VENCRYPT_TLSPLAIN:
522 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
523 break;
524 case VNC_AUTH_VENCRYPT_X509NONE:
525 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
526 break;
527 case VNC_AUTH_VENCRYPT_X509VNC:
528 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
529 break;
530 case VNC_AUTH_VENCRYPT_X509PLAIN:
531 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
532 break;
533 case VNC_AUTH_VENCRYPT_TLSSASL:
534 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
535 break;
536 case VNC_AUTH_VENCRYPT_X509SASL:
537 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
538 break;
539 default:
540 *qmp_has_vencrypt = false;
541 break;
543 break;
544 case VNC_AUTH_SASL:
545 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
546 break;
547 case VNC_AUTH_NONE:
548 default:
549 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
550 break;
554 VncInfo2List *qmp_query_vnc_servers(Error **errp)
556 VncInfo2List *item, *prev = NULL;
557 VncInfo2 *info;
558 VncDisplay *vd;
559 DeviceState *dev;
560 size_t i;
562 QTAILQ_FOREACH(vd, &vnc_displays, next) {
563 info = g_new0(VncInfo2, 1);
564 info->id = g_strdup(vd->id);
565 info->clients = qmp_query_client_list(vd);
566 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
567 &info->vencrypt, &info->has_vencrypt);
568 if (vd->dcl.con) {
569 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
570 "device", NULL));
571 info->has_display = true;
572 info->display = g_strdup(dev->id);
574 for (i = 0; i < vd->nlsock; i++) {
575 info->server = qmp_query_server_entry(
576 vd->lsock[i], false, vd->auth, vd->subauth, info->server);
578 for (i = 0; i < vd->nlwebsock; i++) {
579 info->server = qmp_query_server_entry(
580 vd->lwebsock[i], true, vd->ws_auth,
581 vd->ws_subauth, info->server);
584 item = g_new0(VncInfo2List, 1);
585 item->value = info;
586 item->next = prev;
587 prev = item;
589 return prev;
592 /* TODO
593 1) Get the queue working for IO.
594 2) there is some weirdness when using the -S option (the screen is grey
595 and not totally invalidated
596 3) resolutions > 1024
599 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
600 static void vnc_disconnect_start(VncState *vs);
602 static void vnc_colordepth(VncState *vs);
603 static void framebuffer_update_request(VncState *vs, int incremental,
604 int x_position, int y_position,
605 int w, int h);
606 static void vnc_refresh(DisplayChangeListener *dcl);
607 static int vnc_refresh_server_surface(VncDisplay *vd);
609 static int vnc_width(VncDisplay *vd)
611 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
612 VNC_DIRTY_PIXELS_PER_BIT));
615 static int vnc_height(VncDisplay *vd)
617 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
620 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
621 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
622 VncDisplay *vd,
623 int x, int y, int w, int h)
625 int width = vnc_width(vd);
626 int height = vnc_height(vd);
628 /* this is needed this to ensure we updated all affected
629 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
630 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
631 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
633 x = MIN(x, width);
634 y = MIN(y, height);
635 w = MIN(x + w, width) - x;
636 h = MIN(y + h, height);
638 for (; y < h; y++) {
639 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
640 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
644 static void vnc_dpy_update(DisplayChangeListener *dcl,
645 int x, int y, int w, int h)
647 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
648 struct VncSurface *s = &vd->guest;
650 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
653 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
654 int32_t encoding)
656 vnc_write_u16(vs, x);
657 vnc_write_u16(vs, y);
658 vnc_write_u16(vs, w);
659 vnc_write_u16(vs, h);
661 vnc_write_s32(vs, encoding);
665 static void vnc_desktop_resize(VncState *vs)
667 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
668 return;
670 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
671 vs->client_height == pixman_image_get_height(vs->vd->server)) {
672 return;
674 vs->client_width = pixman_image_get_width(vs->vd->server);
675 vs->client_height = pixman_image_get_height(vs->vd->server);
676 vnc_lock_output(vs);
677 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
678 vnc_write_u8(vs, 0);
679 vnc_write_u16(vs, 1); /* number of rects */
680 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
681 VNC_ENCODING_DESKTOPRESIZE);
682 vnc_unlock_output(vs);
683 vnc_flush(vs);
686 static void vnc_abort_display_jobs(VncDisplay *vd)
688 VncState *vs;
690 QTAILQ_FOREACH(vs, &vd->clients, next) {
691 vnc_lock_output(vs);
692 vs->abort = true;
693 vnc_unlock_output(vs);
695 QTAILQ_FOREACH(vs, &vd->clients, next) {
696 vnc_jobs_join(vs);
698 QTAILQ_FOREACH(vs, &vd->clients, next) {
699 vnc_lock_output(vs);
700 vs->abort = false;
701 vnc_unlock_output(vs);
705 int vnc_server_fb_stride(VncDisplay *vd)
707 return pixman_image_get_stride(vd->server);
710 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
712 uint8_t *ptr;
714 ptr = (uint8_t *)pixman_image_get_data(vd->server);
715 ptr += y * vnc_server_fb_stride(vd);
716 ptr += x * VNC_SERVER_FB_BYTES;
717 return ptr;
720 static void vnc_update_server_surface(VncDisplay *vd)
722 int width, height;
724 qemu_pixman_image_unref(vd->server);
725 vd->server = NULL;
727 if (QTAILQ_EMPTY(&vd->clients)) {
728 return;
731 width = vnc_width(vd);
732 height = vnc_height(vd);
733 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
734 width, height,
735 NULL, 0);
737 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
738 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
739 width, height);
742 static void vnc_dpy_switch(DisplayChangeListener *dcl,
743 DisplaySurface *surface)
745 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
746 VncState *vs;
748 vnc_abort_display_jobs(vd);
749 vd->ds = surface;
751 /* server surface */
752 vnc_update_server_surface(vd);
754 /* guest surface */
755 qemu_pixman_image_unref(vd->guest.fb);
756 vd->guest.fb = pixman_image_ref(surface->image);
757 vd->guest.format = surface->format;
759 QTAILQ_FOREACH(vs, &vd->clients, next) {
760 vnc_colordepth(vs);
761 vnc_desktop_resize(vs);
762 if (vs->vd->cursor) {
763 vnc_cursor_define(vs);
765 memset(vs->dirty, 0x00, sizeof(vs->dirty));
766 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
767 vnc_width(vd),
768 vnc_height(vd));
772 /* fastest code */
773 static void vnc_write_pixels_copy(VncState *vs,
774 void *pixels, int size)
776 vnc_write(vs, pixels, size);
779 /* slowest but generic code. */
780 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
782 uint8_t r, g, b;
784 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
785 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
786 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
787 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
788 #else
789 # error need some bits here if you change VNC_SERVER_FB_FORMAT
790 #endif
791 v = (r << vs->client_pf.rshift) |
792 (g << vs->client_pf.gshift) |
793 (b << vs->client_pf.bshift);
794 switch (vs->client_pf.bytes_per_pixel) {
795 case 1:
796 buf[0] = v;
797 break;
798 case 2:
799 if (vs->client_be) {
800 buf[0] = v >> 8;
801 buf[1] = v;
802 } else {
803 buf[1] = v >> 8;
804 buf[0] = v;
806 break;
807 default:
808 case 4:
809 if (vs->client_be) {
810 buf[0] = v >> 24;
811 buf[1] = v >> 16;
812 buf[2] = v >> 8;
813 buf[3] = v;
814 } else {
815 buf[3] = v >> 24;
816 buf[2] = v >> 16;
817 buf[1] = v >> 8;
818 buf[0] = v;
820 break;
824 static void vnc_write_pixels_generic(VncState *vs,
825 void *pixels1, int size)
827 uint8_t buf[4];
829 if (VNC_SERVER_FB_BYTES == 4) {
830 uint32_t *pixels = pixels1;
831 int n, i;
832 n = size >> 2;
833 for (i = 0; i < n; i++) {
834 vnc_convert_pixel(vs, buf, pixels[i]);
835 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
840 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
842 int i;
843 uint8_t *row;
844 VncDisplay *vd = vs->vd;
846 row = vnc_server_fb_ptr(vd, x, y);
847 for (i = 0; i < h; i++) {
848 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
849 row += vnc_server_fb_stride(vd);
851 return 1;
854 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
856 int n = 0;
857 bool encode_raw = false;
858 size_t saved_offs = vs->output.offset;
860 switch(vs->vnc_encoding) {
861 case VNC_ENCODING_ZLIB:
862 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
863 break;
864 case VNC_ENCODING_HEXTILE:
865 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
866 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
867 break;
868 case VNC_ENCODING_TIGHT:
869 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
870 break;
871 case VNC_ENCODING_TIGHT_PNG:
872 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
873 break;
874 case VNC_ENCODING_ZRLE:
875 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
876 break;
877 case VNC_ENCODING_ZYWRLE:
878 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
879 break;
880 default:
881 encode_raw = true;
882 break;
885 /* If the client has the same pixel format as our internal buffer and
886 * a RAW encoding would need less space fall back to RAW encoding to
887 * save bandwidth and processing power in the client. */
888 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
889 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
890 vs->output.offset = saved_offs;
891 encode_raw = true;
894 if (encode_raw) {
895 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
896 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
899 return n;
902 static void vnc_mouse_set(DisplayChangeListener *dcl,
903 int x, int y, int visible)
905 /* can we ask the client(s) to move the pointer ??? */
908 static int vnc_cursor_define(VncState *vs)
910 QEMUCursor *c = vs->vd->cursor;
911 int isize;
913 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
914 vnc_lock_output(vs);
915 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
916 vnc_write_u8(vs, 0); /* padding */
917 vnc_write_u16(vs, 1); /* # of rects */
918 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
919 VNC_ENCODING_RICH_CURSOR);
920 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
921 vnc_write_pixels_generic(vs, c->data, isize);
922 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
923 vnc_unlock_output(vs);
924 return 0;
926 return -1;
929 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
930 QEMUCursor *c)
932 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
933 VncState *vs;
935 cursor_put(vd->cursor);
936 g_free(vd->cursor_mask);
938 vd->cursor = c;
939 cursor_get(vd->cursor);
940 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
941 vd->cursor_mask = g_malloc0(vd->cursor_msize);
942 cursor_get_mono_mask(c, 0, vd->cursor_mask);
944 QTAILQ_FOREACH(vs, &vd->clients, next) {
945 vnc_cursor_define(vs);
949 static int find_and_clear_dirty_height(VncState *vs,
950 int y, int last_x, int x, int height)
952 int h;
954 for (h = 1; h < (height - y); h++) {
955 if (!test_bit(last_x, vs->dirty[y + h])) {
956 break;
958 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
961 return h;
964 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
966 if (vs->disconnecting) {
967 vnc_disconnect_finish(vs);
968 return 0;
971 vs->has_dirty += has_dirty;
972 if (vs->need_update && !vs->disconnecting) {
973 VncDisplay *vd = vs->vd;
974 VncJob *job;
975 int y;
976 int height, width;
977 int n = 0;
979 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
980 /* kernel send buffers are full -> drop frames to throttle */
981 return 0;
983 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
984 return 0;
987 * Send screen updates to the vnc client using the server
988 * surface and server dirty map. guest surface updates
989 * happening in parallel don't disturb us, the next pass will
990 * send them to the client.
992 job = vnc_job_new(vs);
994 height = pixman_image_get_height(vd->server);
995 width = pixman_image_get_width(vd->server);
997 y = 0;
998 for (;;) {
999 int x, h;
1000 unsigned long x2;
1001 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1002 height * VNC_DIRTY_BPL(vs),
1003 y * VNC_DIRTY_BPL(vs));
1004 if (offset == height * VNC_DIRTY_BPL(vs)) {
1005 /* no more dirty bits */
1006 break;
1008 y = offset / VNC_DIRTY_BPL(vs);
1009 x = offset % VNC_DIRTY_BPL(vs);
1010 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1011 VNC_DIRTY_BPL(vs), x);
1012 bitmap_clear(vs->dirty[y], x, x2 - x);
1013 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1014 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1015 if (x2 > x) {
1016 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1017 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1019 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1020 y += h;
1021 if (y == height) {
1022 break;
1027 vnc_job_push(job);
1028 if (sync) {
1029 vnc_jobs_join(vs);
1031 vs->force_update = 0;
1032 vs->has_dirty = 0;
1033 return n;
1036 if (vs->disconnecting) {
1037 vnc_disconnect_finish(vs);
1038 } else if (sync) {
1039 vnc_jobs_join(vs);
1042 return 0;
1045 /* audio */
1046 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1048 VncState *vs = opaque;
1050 switch (cmd) {
1051 case AUD_CNOTIFY_DISABLE:
1052 vnc_lock_output(vs);
1053 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1054 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1055 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1056 vnc_unlock_output(vs);
1057 vnc_flush(vs);
1058 break;
1060 case AUD_CNOTIFY_ENABLE:
1061 vnc_lock_output(vs);
1062 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1063 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1064 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1065 vnc_unlock_output(vs);
1066 vnc_flush(vs);
1067 break;
1071 static void audio_capture_destroy(void *opaque)
1075 static void audio_capture(void *opaque, void *buf, int size)
1077 VncState *vs = opaque;
1079 vnc_lock_output(vs);
1080 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1081 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1082 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1083 vnc_write_u32(vs, size);
1084 vnc_write(vs, buf, size);
1085 vnc_unlock_output(vs);
1086 vnc_flush(vs);
1089 static void audio_add(VncState *vs)
1091 struct audio_capture_ops ops;
1093 if (vs->audio_cap) {
1094 error_report("audio already running");
1095 return;
1098 ops.notify = audio_capture_notify;
1099 ops.destroy = audio_capture_destroy;
1100 ops.capture = audio_capture;
1102 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1103 if (!vs->audio_cap) {
1104 error_report("Failed to add audio capture");
1108 static void audio_del(VncState *vs)
1110 if (vs->audio_cap) {
1111 AUD_del_capture(vs->audio_cap, vs);
1112 vs->audio_cap = NULL;
1116 static void vnc_disconnect_start(VncState *vs)
1118 if (vs->disconnecting) {
1119 return;
1121 trace_vnc_client_disconnect_start(vs, vs->ioc);
1122 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1123 if (vs->ioc_tag) {
1124 g_source_remove(vs->ioc_tag);
1126 qio_channel_close(vs->ioc, NULL);
1127 vs->disconnecting = TRUE;
1130 void vnc_disconnect_finish(VncState *vs)
1132 int i;
1134 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1136 vnc_jobs_join(vs); /* Wait encoding jobs */
1138 vnc_lock_output(vs);
1139 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1141 buffer_free(&vs->input);
1142 buffer_free(&vs->output);
1144 qapi_free_VncClientInfo(vs->info);
1146 vnc_zlib_clear(vs);
1147 vnc_tight_clear(vs);
1148 vnc_zrle_clear(vs);
1150 #ifdef CONFIG_VNC_SASL
1151 vnc_sasl_client_cleanup(vs);
1152 #endif /* CONFIG_VNC_SASL */
1153 audio_del(vs);
1154 vnc_release_modifiers(vs);
1156 if (vs->mouse_mode_notifier.notify != NULL) {
1157 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1159 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1160 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1161 /* last client gone */
1162 vnc_update_server_surface(vs->vd);
1165 vnc_unlock_output(vs);
1167 qemu_mutex_destroy(&vs->output_mutex);
1168 if (vs->bh != NULL) {
1169 qemu_bh_delete(vs->bh);
1171 buffer_free(&vs->jobs_buffer);
1173 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1174 g_free(vs->lossy_rect[i]);
1176 g_free(vs->lossy_rect);
1178 object_unref(OBJECT(vs->ioc));
1179 vs->ioc = NULL;
1180 object_unref(OBJECT(vs->sioc));
1181 vs->sioc = NULL;
1182 g_free(vs);
1185 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1187 if (ret <= 0) {
1188 if (ret == 0) {
1189 trace_vnc_client_eof(vs, vs->ioc);
1190 vnc_disconnect_start(vs);
1191 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1192 trace_vnc_client_io_error(vs, vs->ioc,
1193 errp ? error_get_pretty(*errp) :
1194 "Unknown");
1195 vnc_disconnect_start(vs);
1198 if (errp) {
1199 error_free(*errp);
1200 *errp = NULL;
1202 return 0;
1204 return ret;
1208 void vnc_client_error(VncState *vs)
1210 VNC_DEBUG("Closing down client sock: protocol error\n");
1211 vnc_disconnect_start(vs);
1216 * Called to write a chunk of data to the client socket. The data may
1217 * be the raw data, or may have already been encoded by SASL.
1218 * The data will be written either straight onto the socket, or
1219 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1221 * NB, it is theoretically possible to have 2 layers of encryption,
1222 * both SASL, and this TLS layer. It is highly unlikely in practice
1223 * though, since SASL encryption will typically be a no-op if TLS
1224 * is active
1226 * Returns the number of bytes written, which may be less than
1227 * the requested 'datalen' if the socket would block. Returns
1228 * -1 on error, and disconnects the client socket.
1230 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1232 Error *err = NULL;
1233 ssize_t ret;
1234 ret = qio_channel_write(
1235 vs->ioc, (const char *)data, datalen, &err);
1236 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1237 return vnc_client_io_error(vs, ret, &err);
1242 * Called to write buffered data to the client socket, when not
1243 * using any SASL SSF encryption layers. Will write as much data
1244 * as possible without blocking. If all buffered data is written,
1245 * will switch the FD poll() handler back to read monitoring.
1247 * Returns the number of bytes written, which may be less than
1248 * the buffered output data if the socket would block. Returns
1249 * -1 on error, and disconnects the client socket.
1251 static ssize_t vnc_client_write_plain(VncState *vs)
1253 ssize_t ret;
1255 #ifdef CONFIG_VNC_SASL
1256 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1257 vs->output.buffer, vs->output.capacity, vs->output.offset,
1258 vs->sasl.waitWriteSSF);
1260 if (vs->sasl.conn &&
1261 vs->sasl.runSSF &&
1262 vs->sasl.waitWriteSSF) {
1263 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1264 if (ret)
1265 vs->sasl.waitWriteSSF -= ret;
1266 } else
1267 #endif /* CONFIG_VNC_SASL */
1268 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1269 if (!ret)
1270 return 0;
1272 buffer_advance(&vs->output, ret);
1274 if (vs->output.offset == 0) {
1275 if (vs->ioc_tag) {
1276 g_source_remove(vs->ioc_tag);
1278 vs->ioc_tag = qio_channel_add_watch(
1279 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1282 return ret;
1287 * First function called whenever there is data to be written to
1288 * the client socket. Will delegate actual work according to whether
1289 * SASL SSF layers are enabled (thus requiring encryption calls)
1291 static void vnc_client_write_locked(VncState *vs)
1293 #ifdef CONFIG_VNC_SASL
1294 if (vs->sasl.conn &&
1295 vs->sasl.runSSF &&
1296 !vs->sasl.waitWriteSSF) {
1297 vnc_client_write_sasl(vs);
1298 } else
1299 #endif /* CONFIG_VNC_SASL */
1301 vnc_client_write_plain(vs);
1305 static void vnc_client_write(VncState *vs)
1308 vnc_lock_output(vs);
1309 if (vs->output.offset) {
1310 vnc_client_write_locked(vs);
1311 } else if (vs->ioc != NULL) {
1312 if (vs->ioc_tag) {
1313 g_source_remove(vs->ioc_tag);
1315 vs->ioc_tag = qio_channel_add_watch(
1316 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1318 vnc_unlock_output(vs);
1321 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1323 vs->read_handler = func;
1324 vs->read_handler_expect = expecting;
1329 * Called to read a chunk of data from the client socket. The data may
1330 * be the raw data, or may need to be further decoded by SASL.
1331 * The data will be read either straight from to the socket, or
1332 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1334 * NB, it is theoretically possible to have 2 layers of encryption,
1335 * both SASL, and this TLS layer. It is highly unlikely in practice
1336 * though, since SASL encryption will typically be a no-op if TLS
1337 * is active
1339 * Returns the number of bytes read, which may be less than
1340 * the requested 'datalen' if the socket would block. Returns
1341 * -1 on error, and disconnects the client socket.
1343 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1345 ssize_t ret;
1346 Error *err = NULL;
1347 ret = qio_channel_read(
1348 vs->ioc, (char *)data, datalen, &err);
1349 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1350 return vnc_client_io_error(vs, ret, &err);
1355 * Called to read data from the client socket to the input buffer,
1356 * when not using any SASL SSF encryption layers. Will read as much
1357 * data as possible without blocking.
1359 * Returns the number of bytes read. Returns -1 on error, and
1360 * disconnects the client socket.
1362 static ssize_t vnc_client_read_plain(VncState *vs)
1364 ssize_t ret;
1365 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1366 vs->input.buffer, vs->input.capacity, vs->input.offset);
1367 buffer_reserve(&vs->input, 4096);
1368 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1369 if (!ret)
1370 return 0;
1371 vs->input.offset += ret;
1372 return ret;
1375 static void vnc_jobs_bh(void *opaque)
1377 VncState *vs = opaque;
1379 vnc_jobs_consume_buffer(vs);
1383 * First function called whenever there is more data to be read from
1384 * the client socket. Will delegate actual work according to whether
1385 * SASL SSF layers are enabled (thus requiring decryption calls)
1386 * Returns 0 on success, -1 if client disconnected
1388 static int vnc_client_read(VncState *vs)
1390 ssize_t ret;
1392 #ifdef CONFIG_VNC_SASL
1393 if (vs->sasl.conn && vs->sasl.runSSF)
1394 ret = vnc_client_read_sasl(vs);
1395 else
1396 #endif /* CONFIG_VNC_SASL */
1397 ret = vnc_client_read_plain(vs);
1398 if (!ret) {
1399 if (vs->disconnecting) {
1400 vnc_disconnect_finish(vs);
1401 return -1;
1403 return 0;
1406 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1407 size_t len = vs->read_handler_expect;
1408 int ret;
1410 ret = vs->read_handler(vs, vs->input.buffer, len);
1411 if (vs->disconnecting) {
1412 vnc_disconnect_finish(vs);
1413 return -1;
1416 if (!ret) {
1417 buffer_advance(&vs->input, len);
1418 } else {
1419 vs->read_handler_expect = ret;
1422 return 0;
1425 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1426 GIOCondition condition, void *opaque)
1428 VncState *vs = opaque;
1429 if (condition & G_IO_IN) {
1430 if (vnc_client_read(vs) < 0) {
1431 return TRUE;
1434 if (condition & G_IO_OUT) {
1435 vnc_client_write(vs);
1437 return TRUE;
1441 void vnc_write(VncState *vs, const void *data, size_t len)
1443 buffer_reserve(&vs->output, len);
1445 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1446 if (vs->ioc_tag) {
1447 g_source_remove(vs->ioc_tag);
1449 vs->ioc_tag = qio_channel_add_watch(
1450 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1453 buffer_append(&vs->output, data, len);
1456 void vnc_write_s32(VncState *vs, int32_t value)
1458 vnc_write_u32(vs, *(uint32_t *)&value);
1461 void vnc_write_u32(VncState *vs, uint32_t value)
1463 uint8_t buf[4];
1465 buf[0] = (value >> 24) & 0xFF;
1466 buf[1] = (value >> 16) & 0xFF;
1467 buf[2] = (value >> 8) & 0xFF;
1468 buf[3] = value & 0xFF;
1470 vnc_write(vs, buf, 4);
1473 void vnc_write_u16(VncState *vs, uint16_t value)
1475 uint8_t buf[2];
1477 buf[0] = (value >> 8) & 0xFF;
1478 buf[1] = value & 0xFF;
1480 vnc_write(vs, buf, 2);
1483 void vnc_write_u8(VncState *vs, uint8_t value)
1485 vnc_write(vs, (char *)&value, 1);
1488 void vnc_flush(VncState *vs)
1490 vnc_lock_output(vs);
1491 if (vs->ioc != NULL && vs->output.offset) {
1492 vnc_client_write_locked(vs);
1494 vnc_unlock_output(vs);
1497 static uint8_t read_u8(uint8_t *data, size_t offset)
1499 return data[offset];
1502 static uint16_t read_u16(uint8_t *data, size_t offset)
1504 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1507 static int32_t read_s32(uint8_t *data, size_t offset)
1509 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1510 (data[offset + 2] << 8) | data[offset + 3]);
1513 uint32_t read_u32(uint8_t *data, size_t offset)
1515 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1516 (data[offset + 2] << 8) | data[offset + 3]);
1519 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1523 static void check_pointer_type_change(Notifier *notifier, void *data)
1525 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1526 int absolute = qemu_input_is_absolute();
1528 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1529 vnc_lock_output(vs);
1530 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1531 vnc_write_u8(vs, 0);
1532 vnc_write_u16(vs, 1);
1533 vnc_framebuffer_update(vs, absolute, 0,
1534 pixman_image_get_width(vs->vd->server),
1535 pixman_image_get_height(vs->vd->server),
1536 VNC_ENCODING_POINTER_TYPE_CHANGE);
1537 vnc_unlock_output(vs);
1538 vnc_flush(vs);
1540 vs->absolute = absolute;
1543 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1545 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1546 [INPUT_BUTTON_LEFT] = 0x01,
1547 [INPUT_BUTTON_MIDDLE] = 0x02,
1548 [INPUT_BUTTON_RIGHT] = 0x04,
1549 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1550 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1552 QemuConsole *con = vs->vd->dcl.con;
1553 int width = pixman_image_get_width(vs->vd->server);
1554 int height = pixman_image_get_height(vs->vd->server);
1556 if (vs->last_bmask != button_mask) {
1557 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1558 vs->last_bmask = button_mask;
1561 if (vs->absolute) {
1562 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1563 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1564 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1565 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1566 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1567 } else {
1568 if (vs->last_x != -1) {
1569 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1570 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1572 vs->last_x = x;
1573 vs->last_y = y;
1575 qemu_input_event_sync();
1578 static void reset_keys(VncState *vs)
1580 int i;
1581 for(i = 0; i < 256; i++) {
1582 if (vs->modifiers_state[i]) {
1583 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1584 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1585 vs->modifiers_state[i] = 0;
1590 static void press_key(VncState *vs, int keysym)
1592 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1593 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1594 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1595 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1596 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1599 static void vnc_led_state_change(VncState *vs)
1601 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1602 return;
1605 vnc_lock_output(vs);
1606 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1607 vnc_write_u8(vs, 0);
1608 vnc_write_u16(vs, 1);
1609 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1610 vnc_write_u8(vs, vs->vd->ledstate);
1611 vnc_unlock_output(vs);
1612 vnc_flush(vs);
1615 static void kbd_leds(void *opaque, int ledstate)
1617 VncDisplay *vd = opaque;
1618 VncState *client;
1620 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1621 (ledstate & QEMU_NUM_LOCK_LED),
1622 (ledstate & QEMU_SCROLL_LOCK_LED));
1624 if (ledstate == vd->ledstate) {
1625 return;
1628 vd->ledstate = ledstate;
1630 QTAILQ_FOREACH(client, &vd->clients, next) {
1631 vnc_led_state_change(client);
1635 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1637 /* QEMU console switch */
1638 switch(keycode) {
1639 case 0x2a: /* Left Shift */
1640 case 0x36: /* Right Shift */
1641 case 0x1d: /* Left CTRL */
1642 case 0x9d: /* Right CTRL */
1643 case 0x38: /* Left ALT */
1644 case 0xb8: /* Right ALT */
1645 if (down)
1646 vs->modifiers_state[keycode] = 1;
1647 else
1648 vs->modifiers_state[keycode] = 0;
1649 break;
1650 case 0x02 ... 0x0a: /* '1' to '9' keys */
1651 if (vs->vd->dcl.con == NULL &&
1652 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1653 /* Reset the modifiers sent to the current console */
1654 reset_keys(vs);
1655 console_select(keycode - 0x02);
1656 return;
1658 break;
1659 case 0x3a: /* CapsLock */
1660 case 0x45: /* NumLock */
1661 if (down)
1662 vs->modifiers_state[keycode] ^= 1;
1663 break;
1666 /* Turn off the lock state sync logic if the client support the led
1667 state extension.
1669 if (down && vs->vd->lock_key_sync &&
1670 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1671 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1672 /* If the numlock state needs to change then simulate an additional
1673 keypress before sending this one. This will happen if the user
1674 toggles numlock away from the VNC window.
1676 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1677 if (!vs->modifiers_state[0x45]) {
1678 trace_vnc_key_sync_numlock(true);
1679 vs->modifiers_state[0x45] = 1;
1680 press_key(vs, 0xff7f);
1682 } else {
1683 if (vs->modifiers_state[0x45]) {
1684 trace_vnc_key_sync_numlock(false);
1685 vs->modifiers_state[0x45] = 0;
1686 press_key(vs, 0xff7f);
1691 if (down && vs->vd->lock_key_sync &&
1692 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1693 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1694 /* If the capslock state needs to change then simulate an additional
1695 keypress before sending this one. This will happen if the user
1696 toggles capslock away from the VNC window.
1698 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1699 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1700 int capslock = !!(vs->modifiers_state[0x3a]);
1701 if (capslock) {
1702 if (uppercase == shift) {
1703 trace_vnc_key_sync_capslock(false);
1704 vs->modifiers_state[0x3a] = 0;
1705 press_key(vs, 0xffe5);
1707 } else {
1708 if (uppercase != shift) {
1709 trace_vnc_key_sync_capslock(true);
1710 vs->modifiers_state[0x3a] = 1;
1711 press_key(vs, 0xffe5);
1716 if (qemu_console_is_graphic(NULL)) {
1717 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1718 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1719 } else {
1720 bool numlock = vs->modifiers_state[0x45];
1721 bool control = (vs->modifiers_state[0x1d] ||
1722 vs->modifiers_state[0x9d]);
1723 /* QEMU console emulation */
1724 if (down) {
1725 switch (keycode) {
1726 case 0x2a: /* Left Shift */
1727 case 0x36: /* Right Shift */
1728 case 0x1d: /* Left CTRL */
1729 case 0x9d: /* Right CTRL */
1730 case 0x38: /* Left ALT */
1731 case 0xb8: /* Right ALT */
1732 break;
1733 case 0xc8:
1734 kbd_put_keysym(QEMU_KEY_UP);
1735 break;
1736 case 0xd0:
1737 kbd_put_keysym(QEMU_KEY_DOWN);
1738 break;
1739 case 0xcb:
1740 kbd_put_keysym(QEMU_KEY_LEFT);
1741 break;
1742 case 0xcd:
1743 kbd_put_keysym(QEMU_KEY_RIGHT);
1744 break;
1745 case 0xd3:
1746 kbd_put_keysym(QEMU_KEY_DELETE);
1747 break;
1748 case 0xc7:
1749 kbd_put_keysym(QEMU_KEY_HOME);
1750 break;
1751 case 0xcf:
1752 kbd_put_keysym(QEMU_KEY_END);
1753 break;
1754 case 0xc9:
1755 kbd_put_keysym(QEMU_KEY_PAGEUP);
1756 break;
1757 case 0xd1:
1758 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1759 break;
1761 case 0x47:
1762 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1763 break;
1764 case 0x48:
1765 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1766 break;
1767 case 0x49:
1768 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1769 break;
1770 case 0x4b:
1771 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1772 break;
1773 case 0x4c:
1774 kbd_put_keysym('5');
1775 break;
1776 case 0x4d:
1777 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1778 break;
1779 case 0x4f:
1780 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1781 break;
1782 case 0x50:
1783 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1784 break;
1785 case 0x51:
1786 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1787 break;
1788 case 0x52:
1789 kbd_put_keysym('0');
1790 break;
1791 case 0x53:
1792 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1793 break;
1795 case 0xb5:
1796 kbd_put_keysym('/');
1797 break;
1798 case 0x37:
1799 kbd_put_keysym('*');
1800 break;
1801 case 0x4a:
1802 kbd_put_keysym('-');
1803 break;
1804 case 0x4e:
1805 kbd_put_keysym('+');
1806 break;
1807 case 0x9c:
1808 kbd_put_keysym('\n');
1809 break;
1811 default:
1812 if (control) {
1813 kbd_put_keysym(sym & 0x1f);
1814 } else {
1815 kbd_put_keysym(sym);
1817 break;
1823 static void vnc_release_modifiers(VncState *vs)
1825 static const int keycodes[] = {
1826 /* shift, control, alt keys, both left & right */
1827 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1829 int i, keycode;
1831 if (!qemu_console_is_graphic(NULL)) {
1832 return;
1834 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1835 keycode = keycodes[i];
1836 if (!vs->modifiers_state[keycode]) {
1837 continue;
1839 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1840 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1844 static const char *code2name(int keycode)
1846 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
1849 static void key_event(VncState *vs, int down, uint32_t sym)
1851 int keycode;
1852 int lsym = sym;
1854 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1855 lsym = lsym - 'A' + 'a';
1858 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1859 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1860 do_key_event(vs, down, keycode, sym);
1863 static void ext_key_event(VncState *vs, int down,
1864 uint32_t sym, uint16_t keycode)
1866 /* if the user specifies a keyboard layout, always use it */
1867 if (keyboard_layout) {
1868 key_event(vs, down, sym);
1869 } else {
1870 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1871 do_key_event(vs, down, keycode, sym);
1875 static void framebuffer_update_request(VncState *vs, int incremental,
1876 int x, int y, int w, int h)
1878 vs->need_update = 1;
1880 if (incremental) {
1881 return;
1884 vs->force_update = 1;
1885 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1888 static void send_ext_key_event_ack(VncState *vs)
1890 vnc_lock_output(vs);
1891 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1892 vnc_write_u8(vs, 0);
1893 vnc_write_u16(vs, 1);
1894 vnc_framebuffer_update(vs, 0, 0,
1895 pixman_image_get_width(vs->vd->server),
1896 pixman_image_get_height(vs->vd->server),
1897 VNC_ENCODING_EXT_KEY_EVENT);
1898 vnc_unlock_output(vs);
1899 vnc_flush(vs);
1902 static void send_ext_audio_ack(VncState *vs)
1904 vnc_lock_output(vs);
1905 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1906 vnc_write_u8(vs, 0);
1907 vnc_write_u16(vs, 1);
1908 vnc_framebuffer_update(vs, 0, 0,
1909 pixman_image_get_width(vs->vd->server),
1910 pixman_image_get_height(vs->vd->server),
1911 VNC_ENCODING_AUDIO);
1912 vnc_unlock_output(vs);
1913 vnc_flush(vs);
1916 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1918 int i;
1919 unsigned int enc = 0;
1921 vs->features = 0;
1922 vs->vnc_encoding = 0;
1923 vs->tight.compression = 9;
1924 vs->tight.quality = -1; /* Lossless by default */
1925 vs->absolute = -1;
1928 * Start from the end because the encodings are sent in order of preference.
1929 * This way the preferred encoding (first encoding defined in the array)
1930 * will be set at the end of the loop.
1932 for (i = n_encodings - 1; i >= 0; i--) {
1933 enc = encodings[i];
1934 switch (enc) {
1935 case VNC_ENCODING_RAW:
1936 vs->vnc_encoding = enc;
1937 break;
1938 case VNC_ENCODING_COPYRECT:
1939 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1940 break;
1941 case VNC_ENCODING_HEXTILE:
1942 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1943 vs->vnc_encoding = enc;
1944 break;
1945 case VNC_ENCODING_TIGHT:
1946 vs->features |= VNC_FEATURE_TIGHT_MASK;
1947 vs->vnc_encoding = enc;
1948 break;
1949 #ifdef CONFIG_VNC_PNG
1950 case VNC_ENCODING_TIGHT_PNG:
1951 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
1952 vs->vnc_encoding = enc;
1953 break;
1954 #endif
1955 case VNC_ENCODING_ZLIB:
1956 vs->features |= VNC_FEATURE_ZLIB_MASK;
1957 vs->vnc_encoding = enc;
1958 break;
1959 case VNC_ENCODING_ZRLE:
1960 vs->features |= VNC_FEATURE_ZRLE_MASK;
1961 vs->vnc_encoding = enc;
1962 break;
1963 case VNC_ENCODING_ZYWRLE:
1964 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
1965 vs->vnc_encoding = enc;
1966 break;
1967 case VNC_ENCODING_DESKTOPRESIZE:
1968 vs->features |= VNC_FEATURE_RESIZE_MASK;
1969 break;
1970 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1971 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1972 break;
1973 case VNC_ENCODING_RICH_CURSOR:
1974 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
1975 if (vs->vd->cursor) {
1976 vnc_cursor_define(vs);
1978 break;
1979 case VNC_ENCODING_EXT_KEY_EVENT:
1980 send_ext_key_event_ack(vs);
1981 break;
1982 case VNC_ENCODING_AUDIO:
1983 send_ext_audio_ack(vs);
1984 break;
1985 case VNC_ENCODING_WMVi:
1986 vs->features |= VNC_FEATURE_WMVI_MASK;
1987 break;
1988 case VNC_ENCODING_LED_STATE:
1989 vs->features |= VNC_FEATURE_LED_STATE_MASK;
1990 break;
1991 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1992 vs->tight.compression = (enc & 0x0F);
1993 break;
1994 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1995 if (vs->vd->lossy) {
1996 vs->tight.quality = (enc & 0x0F);
1998 break;
1999 default:
2000 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2001 break;
2004 vnc_desktop_resize(vs);
2005 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2006 vnc_led_state_change(vs);
2009 static void set_pixel_conversion(VncState *vs)
2011 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2013 if (fmt == VNC_SERVER_FB_FORMAT) {
2014 vs->write_pixels = vnc_write_pixels_copy;
2015 vnc_hextile_set_pixel_conversion(vs, 0);
2016 } else {
2017 vs->write_pixels = vnc_write_pixels_generic;
2018 vnc_hextile_set_pixel_conversion(vs, 1);
2022 static void send_color_map(VncState *vs)
2024 int i;
2026 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2027 vnc_write_u8(vs, 0); /* padding */
2028 vnc_write_u16(vs, 0); /* first color */
2029 vnc_write_u16(vs, 256); /* # of colors */
2031 for (i = 0; i < 256; i++) {
2032 PixelFormat *pf = &vs->client_pf;
2034 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2035 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2036 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2040 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2041 int big_endian_flag, int true_color_flag,
2042 int red_max, int green_max, int blue_max,
2043 int red_shift, int green_shift, int blue_shift)
2045 if (!true_color_flag) {
2046 /* Expose a reasonable default 256 color map */
2047 bits_per_pixel = 8;
2048 red_max = 7;
2049 green_max = 7;
2050 blue_max = 3;
2051 red_shift = 0;
2052 green_shift = 3;
2053 blue_shift = 6;
2056 switch (bits_per_pixel) {
2057 case 8:
2058 case 16:
2059 case 32:
2060 break;
2061 default:
2062 vnc_client_error(vs);
2063 return;
2066 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2067 vs->client_pf.rbits = ctpopl(red_max);
2068 vs->client_pf.rshift = red_shift;
2069 vs->client_pf.rmask = red_max << red_shift;
2070 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2071 vs->client_pf.gbits = ctpopl(green_max);
2072 vs->client_pf.gshift = green_shift;
2073 vs->client_pf.gmask = green_max << green_shift;
2074 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2075 vs->client_pf.bbits = ctpopl(blue_max);
2076 vs->client_pf.bshift = blue_shift;
2077 vs->client_pf.bmask = blue_max << blue_shift;
2078 vs->client_pf.bits_per_pixel = bits_per_pixel;
2079 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2080 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2081 vs->client_be = big_endian_flag;
2083 if (!true_color_flag) {
2084 send_color_map(vs);
2087 set_pixel_conversion(vs);
2089 graphic_hw_invalidate(vs->vd->dcl.con);
2090 graphic_hw_update(vs->vd->dcl.con);
2093 static void pixel_format_message (VncState *vs) {
2094 char pad[3] = { 0, 0, 0 };
2096 vs->client_pf = qemu_default_pixelformat(32);
2098 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2099 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2101 #ifdef HOST_WORDS_BIGENDIAN
2102 vnc_write_u8(vs, 1); /* big-endian-flag */
2103 #else
2104 vnc_write_u8(vs, 0); /* big-endian-flag */
2105 #endif
2106 vnc_write_u8(vs, 1); /* true-color-flag */
2107 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2108 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2109 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2110 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2111 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2112 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2113 vnc_write(vs, pad, 3); /* padding */
2115 vnc_hextile_set_pixel_conversion(vs, 0);
2116 vs->write_pixels = vnc_write_pixels_copy;
2119 static void vnc_colordepth(VncState *vs)
2121 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2122 /* Sending a WMVi message to notify the client*/
2123 vnc_lock_output(vs);
2124 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2125 vnc_write_u8(vs, 0);
2126 vnc_write_u16(vs, 1); /* number of rects */
2127 vnc_framebuffer_update(vs, 0, 0,
2128 pixman_image_get_width(vs->vd->server),
2129 pixman_image_get_height(vs->vd->server),
2130 VNC_ENCODING_WMVi);
2131 pixel_format_message(vs);
2132 vnc_unlock_output(vs);
2133 vnc_flush(vs);
2134 } else {
2135 set_pixel_conversion(vs);
2139 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2141 int i;
2142 uint16_t limit;
2143 VncDisplay *vd = vs->vd;
2145 if (data[0] > 3) {
2146 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2149 switch (data[0]) {
2150 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2151 if (len == 1)
2152 return 20;
2154 set_pixel_format(vs, read_u8(data, 4),
2155 read_u8(data, 6), read_u8(data, 7),
2156 read_u16(data, 8), read_u16(data, 10),
2157 read_u16(data, 12), read_u8(data, 14),
2158 read_u8(data, 15), read_u8(data, 16));
2159 break;
2160 case VNC_MSG_CLIENT_SET_ENCODINGS:
2161 if (len == 1)
2162 return 4;
2164 if (len == 4) {
2165 limit = read_u16(data, 2);
2166 if (limit > 0)
2167 return 4 + (limit * 4);
2168 } else
2169 limit = read_u16(data, 2);
2171 for (i = 0; i < limit; i++) {
2172 int32_t val = read_s32(data, 4 + (i * 4));
2173 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2176 set_encodings(vs, (int32_t *)(data + 4), limit);
2177 break;
2178 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2179 if (len == 1)
2180 return 10;
2182 framebuffer_update_request(vs,
2183 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2184 read_u16(data, 6), read_u16(data, 8));
2185 break;
2186 case VNC_MSG_CLIENT_KEY_EVENT:
2187 if (len == 1)
2188 return 8;
2190 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2191 break;
2192 case VNC_MSG_CLIENT_POINTER_EVENT:
2193 if (len == 1)
2194 return 6;
2196 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2197 break;
2198 case VNC_MSG_CLIENT_CUT_TEXT:
2199 if (len == 1) {
2200 return 8;
2202 if (len == 8) {
2203 uint32_t dlen = read_u32(data, 4);
2204 if (dlen > (1 << 20)) {
2205 error_report("vnc: client_cut_text msg payload has %u bytes"
2206 " which exceeds our limit of 1MB.", dlen);
2207 vnc_client_error(vs);
2208 break;
2210 if (dlen > 0) {
2211 return 8 + dlen;
2215 client_cut_text(vs, read_u32(data, 4), data + 8);
2216 break;
2217 case VNC_MSG_CLIENT_QEMU:
2218 if (len == 1)
2219 return 2;
2221 switch (read_u8(data, 1)) {
2222 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2223 if (len == 2)
2224 return 12;
2226 ext_key_event(vs, read_u16(data, 2),
2227 read_u32(data, 4), read_u32(data, 8));
2228 break;
2229 case VNC_MSG_CLIENT_QEMU_AUDIO:
2230 if (len == 2)
2231 return 4;
2233 switch (read_u16 (data, 2)) {
2234 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2235 audio_add(vs);
2236 break;
2237 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2238 audio_del(vs);
2239 break;
2240 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2241 if (len == 4)
2242 return 10;
2243 switch (read_u8(data, 4)) {
2244 case 0: vs->as.fmt = AUD_FMT_U8; break;
2245 case 1: vs->as.fmt = AUD_FMT_S8; break;
2246 case 2: vs->as.fmt = AUD_FMT_U16; break;
2247 case 3: vs->as.fmt = AUD_FMT_S16; break;
2248 case 4: vs->as.fmt = AUD_FMT_U32; break;
2249 case 5: vs->as.fmt = AUD_FMT_S32; break;
2250 default:
2251 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2252 vnc_client_error(vs);
2253 break;
2255 vs->as.nchannels = read_u8(data, 5);
2256 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2257 VNC_DEBUG("Invalid audio channel coount %d\n",
2258 read_u8(data, 5));
2259 vnc_client_error(vs);
2260 break;
2262 vs->as.freq = read_u32(data, 6);
2263 break;
2264 default:
2265 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2266 vnc_client_error(vs);
2267 break;
2269 break;
2271 default:
2272 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2273 vnc_client_error(vs);
2274 break;
2276 break;
2277 default:
2278 VNC_DEBUG("Msg: %d\n", data[0]);
2279 vnc_client_error(vs);
2280 break;
2283 vnc_read_when(vs, protocol_client_msg, 1);
2284 return 0;
2287 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2289 char buf[1024];
2290 VncShareMode mode;
2291 int size;
2293 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2294 switch (vs->vd->share_policy) {
2295 case VNC_SHARE_POLICY_IGNORE:
2297 * Ignore the shared flag. Nothing to do here.
2299 * Doesn't conform to the rfb spec but is traditional qemu
2300 * behavior, thus left here as option for compatibility
2301 * reasons.
2303 break;
2304 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2306 * Policy: Allow clients ask for exclusive access.
2308 * Implementation: When a client asks for exclusive access,
2309 * disconnect all others. Shared connects are allowed as long
2310 * as no exclusive connection exists.
2312 * This is how the rfb spec suggests to handle the shared flag.
2314 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2315 VncState *client;
2316 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2317 if (vs == client) {
2318 continue;
2320 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2321 client->share_mode != VNC_SHARE_MODE_SHARED) {
2322 continue;
2324 vnc_disconnect_start(client);
2327 if (mode == VNC_SHARE_MODE_SHARED) {
2328 if (vs->vd->num_exclusive > 0) {
2329 vnc_disconnect_start(vs);
2330 return 0;
2333 break;
2334 case VNC_SHARE_POLICY_FORCE_SHARED:
2336 * Policy: Shared connects only.
2337 * Implementation: Disallow clients asking for exclusive access.
2339 * Useful for shared desktop sessions where you don't want
2340 * someone forgetting to say -shared when running the vnc
2341 * client disconnect everybody else.
2343 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2344 vnc_disconnect_start(vs);
2345 return 0;
2347 break;
2349 vnc_set_share_mode(vs, mode);
2351 if (vs->vd->num_shared > vs->vd->connections_limit) {
2352 vnc_disconnect_start(vs);
2353 return 0;
2356 vs->client_width = pixman_image_get_width(vs->vd->server);
2357 vs->client_height = pixman_image_get_height(vs->vd->server);
2358 vnc_write_u16(vs, vs->client_width);
2359 vnc_write_u16(vs, vs->client_height);
2361 pixel_format_message(vs);
2363 if (qemu_name) {
2364 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2365 if (size > sizeof(buf)) {
2366 size = sizeof(buf);
2368 } else {
2369 size = snprintf(buf, sizeof(buf), "QEMU");
2372 vnc_write_u32(vs, size);
2373 vnc_write(vs, buf, size);
2374 vnc_flush(vs);
2376 vnc_client_cache_auth(vs);
2377 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2379 vnc_read_when(vs, protocol_client_msg, 1);
2381 return 0;
2384 void start_client_init(VncState *vs)
2386 vnc_read_when(vs, protocol_client_init, 1);
2389 static void make_challenge(VncState *vs)
2391 int i;
2393 srand(time(NULL)+getpid()+getpid()*987654+rand());
2395 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2396 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2399 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2401 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2402 size_t i, pwlen;
2403 unsigned char key[8];
2404 time_t now = time(NULL);
2405 QCryptoCipher *cipher = NULL;
2406 Error *err = NULL;
2408 if (!vs->vd->password) {
2409 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2410 goto reject;
2412 if (vs->vd->expires < now) {
2413 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2414 goto reject;
2417 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2419 /* Calculate the expected challenge response */
2420 pwlen = strlen(vs->vd->password);
2421 for (i=0; i<sizeof(key); i++)
2422 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2424 cipher = qcrypto_cipher_new(
2425 QCRYPTO_CIPHER_ALG_DES_RFB,
2426 QCRYPTO_CIPHER_MODE_ECB,
2427 key, G_N_ELEMENTS(key),
2428 &err);
2429 if (!cipher) {
2430 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2431 error_get_pretty(err));
2432 error_free(err);
2433 goto reject;
2436 if (qcrypto_cipher_encrypt(cipher,
2437 vs->challenge,
2438 response,
2439 VNC_AUTH_CHALLENGE_SIZE,
2440 &err) < 0) {
2441 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2442 error_get_pretty(err));
2443 error_free(err);
2444 goto reject;
2447 /* Compare expected vs actual challenge response */
2448 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2449 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2450 goto reject;
2451 } else {
2452 trace_vnc_auth_pass(vs, vs->auth);
2453 vnc_write_u32(vs, 0); /* Accept auth */
2454 vnc_flush(vs);
2456 start_client_init(vs);
2459 qcrypto_cipher_free(cipher);
2460 return 0;
2462 reject:
2463 vnc_write_u32(vs, 1); /* Reject auth */
2464 if (vs->minor >= 8) {
2465 static const char err[] = "Authentication failed";
2466 vnc_write_u32(vs, sizeof(err));
2467 vnc_write(vs, err, sizeof(err));
2469 vnc_flush(vs);
2470 vnc_client_error(vs);
2471 qcrypto_cipher_free(cipher);
2472 return 0;
2475 void start_auth_vnc(VncState *vs)
2477 make_challenge(vs);
2478 /* Send client a 'random' challenge */
2479 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2480 vnc_flush(vs);
2482 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2486 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2488 /* We only advertise 1 auth scheme at a time, so client
2489 * must pick the one we sent. Verify this */
2490 if (data[0] != vs->auth) { /* Reject auth */
2491 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2492 vnc_write_u32(vs, 1);
2493 if (vs->minor >= 8) {
2494 static const char err[] = "Authentication failed";
2495 vnc_write_u32(vs, sizeof(err));
2496 vnc_write(vs, err, sizeof(err));
2498 vnc_client_error(vs);
2499 } else { /* Accept requested auth */
2500 trace_vnc_auth_start(vs, vs->auth);
2501 switch (vs->auth) {
2502 case VNC_AUTH_NONE:
2503 if (vs->minor >= 8) {
2504 vnc_write_u32(vs, 0); /* Accept auth completion */
2505 vnc_flush(vs);
2507 trace_vnc_auth_pass(vs, vs->auth);
2508 start_client_init(vs);
2509 break;
2511 case VNC_AUTH_VNC:
2512 start_auth_vnc(vs);
2513 break;
2515 case VNC_AUTH_VENCRYPT:
2516 start_auth_vencrypt(vs);
2517 break;
2519 #ifdef CONFIG_VNC_SASL
2520 case VNC_AUTH_SASL:
2521 start_auth_sasl(vs);
2522 break;
2523 #endif /* CONFIG_VNC_SASL */
2525 default: /* Should not be possible, but just in case */
2526 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2527 vnc_write_u8(vs, 1);
2528 if (vs->minor >= 8) {
2529 static const char err[] = "Authentication failed";
2530 vnc_write_u32(vs, sizeof(err));
2531 vnc_write(vs, err, sizeof(err));
2533 vnc_client_error(vs);
2536 return 0;
2539 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2541 char local[13];
2543 memcpy(local, version, 12);
2544 local[12] = 0;
2546 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2547 VNC_DEBUG("Malformed protocol version %s\n", local);
2548 vnc_client_error(vs);
2549 return 0;
2551 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2552 if (vs->major != 3 ||
2553 (vs->minor != 3 &&
2554 vs->minor != 4 &&
2555 vs->minor != 5 &&
2556 vs->minor != 7 &&
2557 vs->minor != 8)) {
2558 VNC_DEBUG("Unsupported client version\n");
2559 vnc_write_u32(vs, VNC_AUTH_INVALID);
2560 vnc_flush(vs);
2561 vnc_client_error(vs);
2562 return 0;
2564 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2565 * as equivalent to v3.3 by servers
2567 if (vs->minor == 4 || vs->minor == 5)
2568 vs->minor = 3;
2570 if (vs->minor == 3) {
2571 trace_vnc_auth_start(vs, vs->auth);
2572 if (vs->auth == VNC_AUTH_NONE) {
2573 vnc_write_u32(vs, vs->auth);
2574 vnc_flush(vs);
2575 trace_vnc_auth_pass(vs, vs->auth);
2576 start_client_init(vs);
2577 } else if (vs->auth == VNC_AUTH_VNC) {
2578 VNC_DEBUG("Tell client VNC auth\n");
2579 vnc_write_u32(vs, vs->auth);
2580 vnc_flush(vs);
2581 start_auth_vnc(vs);
2582 } else {
2583 trace_vnc_auth_fail(vs, vs->auth,
2584 "Unsupported auth method for v3.3", "");
2585 vnc_write_u32(vs, VNC_AUTH_INVALID);
2586 vnc_flush(vs);
2587 vnc_client_error(vs);
2589 } else {
2590 vnc_write_u8(vs, 1); /* num auth */
2591 vnc_write_u8(vs, vs->auth);
2592 vnc_read_when(vs, protocol_client_auth, 1);
2593 vnc_flush(vs);
2596 return 0;
2599 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2601 struct VncSurface *vs = &vd->guest;
2603 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2606 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2608 int i, j;
2610 w = (x + w) / VNC_STAT_RECT;
2611 h = (y + h) / VNC_STAT_RECT;
2612 x /= VNC_STAT_RECT;
2613 y /= VNC_STAT_RECT;
2615 for (j = y; j <= h; j++) {
2616 for (i = x; i <= w; i++) {
2617 vs->lossy_rect[j][i] = 1;
2622 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2624 VncState *vs;
2625 int sty = y / VNC_STAT_RECT;
2626 int stx = x / VNC_STAT_RECT;
2627 int has_dirty = 0;
2629 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2630 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2632 QTAILQ_FOREACH(vs, &vd->clients, next) {
2633 int j;
2635 /* kernel send buffers are full -> refresh later */
2636 if (vs->output.offset) {
2637 continue;
2640 if (!vs->lossy_rect[sty][stx]) {
2641 continue;
2644 vs->lossy_rect[sty][stx] = 0;
2645 for (j = 0; j < VNC_STAT_RECT; ++j) {
2646 bitmap_set(vs->dirty[y + j],
2647 x / VNC_DIRTY_PIXELS_PER_BIT,
2648 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2650 has_dirty++;
2653 return has_dirty;
2656 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2658 int width = MIN(pixman_image_get_width(vd->guest.fb),
2659 pixman_image_get_width(vd->server));
2660 int height = MIN(pixman_image_get_height(vd->guest.fb),
2661 pixman_image_get_height(vd->server));
2662 int x, y;
2663 struct timeval res;
2664 int has_dirty = 0;
2666 for (y = 0; y < height; y += VNC_STAT_RECT) {
2667 for (x = 0; x < width; x += VNC_STAT_RECT) {
2668 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2670 rect->updated = false;
2674 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2676 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2677 return has_dirty;
2679 vd->guest.last_freq_check = *tv;
2681 for (y = 0; y < height; y += VNC_STAT_RECT) {
2682 for (x = 0; x < width; x += VNC_STAT_RECT) {
2683 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2684 int count = ARRAY_SIZE(rect->times);
2685 struct timeval min, max;
2687 if (!timerisset(&rect->times[count - 1])) {
2688 continue ;
2691 max = rect->times[(rect->idx + count - 1) % count];
2692 qemu_timersub(tv, &max, &res);
2694 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2695 rect->freq = 0;
2696 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2697 memset(rect->times, 0, sizeof (rect->times));
2698 continue ;
2701 min = rect->times[rect->idx];
2702 max = rect->times[(rect->idx + count - 1) % count];
2703 qemu_timersub(&max, &min, &res);
2705 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2706 rect->freq /= count;
2707 rect->freq = 1. / rect->freq;
2710 return has_dirty;
2713 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2715 int i, j;
2716 double total = 0;
2717 int num = 0;
2719 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2720 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2722 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2723 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2724 total += vnc_stat_rect(vs->vd, i, j)->freq;
2725 num++;
2729 if (num) {
2730 return total / num;
2731 } else {
2732 return 0;
2736 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2738 VncRectStat *rect;
2740 rect = vnc_stat_rect(vd, x, y);
2741 if (rect->updated) {
2742 return ;
2744 rect->times[rect->idx] = *tv;
2745 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2746 rect->updated = true;
2749 static int vnc_refresh_server_surface(VncDisplay *vd)
2751 int width = MIN(pixman_image_get_width(vd->guest.fb),
2752 pixman_image_get_width(vd->server));
2753 int height = MIN(pixman_image_get_height(vd->guest.fb),
2754 pixman_image_get_height(vd->server));
2755 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2756 uint8_t *guest_row0 = NULL, *server_row0;
2757 VncState *vs;
2758 int has_dirty = 0;
2759 pixman_image_t *tmpbuf = NULL;
2761 struct timeval tv = { 0, 0 };
2763 if (!vd->non_adaptive) {
2764 gettimeofday(&tv, NULL);
2765 has_dirty = vnc_update_stats(vd, &tv);
2769 * Walk through the guest dirty map.
2770 * Check and copy modified bits from guest to server surface.
2771 * Update server dirty map.
2773 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2774 server_stride = guest_stride = guest_ll =
2775 pixman_image_get_stride(vd->server);
2776 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2777 server_stride);
2778 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2779 int width = pixman_image_get_width(vd->server);
2780 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2781 } else {
2782 int guest_bpp =
2783 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2784 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2785 guest_stride = pixman_image_get_stride(vd->guest.fb);
2786 guest_ll = pixman_image_get_width(vd->guest.fb) * (DIV_ROUND_UP(guest_bpp, 8));
2788 line_bytes = MIN(server_stride, guest_ll);
2790 for (;;) {
2791 int x;
2792 uint8_t *guest_ptr, *server_ptr;
2793 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2794 height * VNC_DIRTY_BPL(&vd->guest),
2795 y * VNC_DIRTY_BPL(&vd->guest));
2796 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2797 /* no more dirty bits */
2798 break;
2800 y = offset / VNC_DIRTY_BPL(&vd->guest);
2801 x = offset % VNC_DIRTY_BPL(&vd->guest);
2803 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2805 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2806 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2807 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2808 } else {
2809 guest_ptr = guest_row0 + y * guest_stride;
2811 guest_ptr += x * cmp_bytes;
2813 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2814 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2815 int _cmp_bytes = cmp_bytes;
2816 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2817 continue;
2819 if ((x + 1) * cmp_bytes > line_bytes) {
2820 _cmp_bytes = line_bytes - x * cmp_bytes;
2822 assert(_cmp_bytes >= 0);
2823 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2824 continue;
2826 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2827 if (!vd->non_adaptive) {
2828 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2829 y, &tv);
2831 QTAILQ_FOREACH(vs, &vd->clients, next) {
2832 set_bit(x, vs->dirty[y]);
2834 has_dirty++;
2837 y++;
2839 qemu_pixman_image_unref(tmpbuf);
2840 return has_dirty;
2843 static void vnc_refresh(DisplayChangeListener *dcl)
2845 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2846 VncState *vs, *vn;
2847 int has_dirty, rects = 0;
2849 if (QTAILQ_EMPTY(&vd->clients)) {
2850 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2851 return;
2854 graphic_hw_update(vd->dcl.con);
2856 if (vnc_trylock_display(vd)) {
2857 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2858 return;
2861 has_dirty = vnc_refresh_server_surface(vd);
2862 vnc_unlock_display(vd);
2864 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2865 rects += vnc_update_client(vs, has_dirty, false);
2866 /* vs might be free()ed here */
2869 if (has_dirty && rects) {
2870 vd->dcl.update_interval /= 2;
2871 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2872 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2874 } else {
2875 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2876 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2877 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2882 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2883 bool skipauth, bool websocket)
2885 VncState *vs = g_new0(VncState, 1);
2886 bool first_client = QTAILQ_EMPTY(&vd->clients);
2887 int i;
2889 trace_vnc_client_connect(vs, sioc);
2890 vs->sioc = sioc;
2891 object_ref(OBJECT(vs->sioc));
2892 vs->ioc = QIO_CHANNEL(sioc);
2893 object_ref(OBJECT(vs->ioc));
2894 vs->vd = vd;
2896 buffer_init(&vs->input, "vnc-input/%p", sioc);
2897 buffer_init(&vs->output, "vnc-output/%p", sioc);
2898 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2900 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2901 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2902 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2903 #ifdef CONFIG_VNC_JPEG
2904 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2905 #endif
2906 #ifdef CONFIG_VNC_PNG
2907 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2908 #endif
2909 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2910 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2911 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2912 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2914 if (skipauth) {
2915 vs->auth = VNC_AUTH_NONE;
2916 vs->subauth = VNC_AUTH_INVALID;
2917 } else {
2918 if (websocket) {
2919 vs->auth = vd->ws_auth;
2920 vs->subauth = VNC_AUTH_INVALID;
2921 } else {
2922 vs->auth = vd->auth;
2923 vs->subauth = vd->subauth;
2926 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2927 sioc, websocket, vs->auth, vs->subauth);
2929 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
2930 for (i = 0; i < VNC_STAT_ROWS; ++i) {
2931 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
2934 VNC_DEBUG("New client on socket %p\n", vs->sioc);
2935 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2936 qio_channel_set_blocking(vs->ioc, false, NULL);
2937 if (websocket) {
2938 vs->websocket = 1;
2939 if (vd->tlscreds) {
2940 vs->ioc_tag = qio_channel_add_watch(
2941 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
2942 } else {
2943 vs->ioc_tag = qio_channel_add_watch(
2944 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
2946 } else {
2947 vs->ioc_tag = qio_channel_add_watch(
2948 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
2951 vnc_client_cache_addr(vs);
2952 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
2953 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
2955 vs->last_x = -1;
2956 vs->last_y = -1;
2958 vs->as.freq = 44100;
2959 vs->as.nchannels = 2;
2960 vs->as.fmt = AUD_FMT_S16;
2961 vs->as.endianness = 0;
2963 qemu_mutex_init(&vs->output_mutex);
2964 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
2966 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
2967 if (first_client) {
2968 vnc_update_server_surface(vd);
2971 graphic_hw_update(vd->dcl.con);
2973 if (!vs->websocket) {
2974 vnc_start_protocol(vs);
2977 if (vd->num_connecting > vd->connections_limit) {
2978 QTAILQ_FOREACH(vs, &vd->clients, next) {
2979 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
2980 vnc_disconnect_start(vs);
2981 return;
2987 void vnc_start_protocol(VncState *vs)
2989 vnc_write(vs, "RFB 003.008\n", 12);
2990 vnc_flush(vs);
2991 vnc_read_when(vs, protocol_version, 12);
2993 vs->mouse_mode_notifier.notify = check_pointer_type_change;
2994 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
2997 static gboolean vnc_listen_io(QIOChannel *ioc,
2998 GIOCondition condition,
2999 void *opaque)
3001 VncDisplay *vd = opaque;
3002 QIOChannelSocket *sioc = NULL;
3003 Error *err = NULL;
3004 bool isWebsock = false;
3005 size_t i;
3007 for (i = 0; i < vd->nlwebsock; i++) {
3008 if (ioc == QIO_CHANNEL(vd->lwebsock[i])) {
3009 isWebsock = true;
3010 break;
3014 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3015 if (sioc != NULL) {
3016 qio_channel_set_name(QIO_CHANNEL(sioc),
3017 isWebsock ? "vnc-ws-server" : "vnc-server");
3018 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3019 vnc_connect(vd, sioc, false, isWebsock);
3020 object_unref(OBJECT(sioc));
3021 } else {
3022 /* client probably closed connection before we got there */
3023 error_free(err);
3026 return TRUE;
3029 static const DisplayChangeListenerOps dcl_ops = {
3030 .dpy_name = "vnc",
3031 .dpy_refresh = vnc_refresh,
3032 .dpy_gfx_update = vnc_dpy_update,
3033 .dpy_gfx_switch = vnc_dpy_switch,
3034 .dpy_gfx_check_format = qemu_pixman_check_format,
3035 .dpy_mouse_set = vnc_mouse_set,
3036 .dpy_cursor_define = vnc_dpy_cursor_define,
3039 void vnc_display_init(const char *id)
3041 VncDisplay *vd;
3043 if (vnc_display_find(id) != NULL) {
3044 return;
3046 vd = g_malloc0(sizeof(*vd));
3048 vd->id = strdup(id);
3049 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3051 QTAILQ_INIT(&vd->clients);
3052 vd->expires = TIME_MAX;
3054 if (keyboard_layout) {
3055 trace_vnc_key_map_init(keyboard_layout);
3056 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3057 } else {
3058 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3061 if (!vd->kbd_layout) {
3062 exit(1);
3065 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3066 vd->connections_limit = 32;
3068 qemu_mutex_init(&vd->mutex);
3069 vnc_start_worker_thread();
3071 vd->dcl.ops = &dcl_ops;
3072 register_displaychangelistener(&vd->dcl);
3076 static void vnc_display_close(VncDisplay *vd)
3078 size_t i;
3079 if (!vd) {
3080 return;
3082 vd->is_unix = false;
3083 for (i = 0; i < vd->nlsock; i++) {
3084 if (vd->lsock_tag[i]) {
3085 g_source_remove(vd->lsock_tag[i]);
3087 object_unref(OBJECT(vd->lsock[i]));
3089 g_free(vd->lsock);
3090 g_free(vd->lsock_tag);
3091 vd->lsock = NULL;
3092 vd->lsock_tag = NULL;
3093 vd->nlsock = 0;
3095 for (i = 0; i < vd->nlwebsock; i++) {
3096 if (vd->lwebsock_tag[i]) {
3097 g_source_remove(vd->lwebsock_tag[i]);
3099 object_unref(OBJECT(vd->lwebsock[i]));
3101 g_free(vd->lwebsock);
3102 g_free(vd->lwebsock_tag);
3103 vd->lwebsock = NULL;
3104 vd->lwebsock_tag = NULL;
3105 vd->nlwebsock = 0;
3107 vd->auth = VNC_AUTH_INVALID;
3108 vd->subauth = VNC_AUTH_INVALID;
3109 if (vd->tlscreds) {
3110 object_unparent(OBJECT(vd->tlscreds));
3111 vd->tlscreds = NULL;
3113 g_free(vd->tlsaclname);
3114 vd->tlsaclname = NULL;
3115 if (vd->lock_key_sync) {
3116 qemu_remove_led_event_handler(vd->led);
3117 vd->led = NULL;
3121 int vnc_display_password(const char *id, const char *password)
3123 VncDisplay *vd = vnc_display_find(id);
3125 if (!vd) {
3126 return -EINVAL;
3128 if (vd->auth == VNC_AUTH_NONE) {
3129 error_printf_unless_qmp("If you want use passwords please enable "
3130 "password auth using '-vnc ${dpy},password'.\n");
3131 return -EINVAL;
3134 g_free(vd->password);
3135 vd->password = g_strdup(password);
3137 return 0;
3140 int vnc_display_pw_expire(const char *id, time_t expires)
3142 VncDisplay *vd = vnc_display_find(id);
3144 if (!vd) {
3145 return -EINVAL;
3148 vd->expires = expires;
3149 return 0;
3152 static void vnc_display_print_local_addr(VncDisplay *vd)
3154 SocketAddress *addr;
3155 Error *err = NULL;
3157 if (!vd->nlsock) {
3158 return;
3161 addr = qio_channel_socket_get_local_address(vd->lsock[0], &err);
3162 if (!addr) {
3163 return;
3166 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3167 qapi_free_SocketAddress(addr);
3168 return;
3170 error_printf_unless_qmp("VNC server running on %s:%s\n",
3171 addr->u.inet.host,
3172 addr->u.inet.port);
3173 qapi_free_SocketAddress(addr);
3176 static QemuOptsList qemu_vnc_opts = {
3177 .name = "vnc",
3178 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3179 .implied_opt_name = "vnc",
3180 .desc = {
3182 .name = "vnc",
3183 .type = QEMU_OPT_STRING,
3185 .name = "websocket",
3186 .type = QEMU_OPT_STRING,
3188 .name = "tls-creds",
3189 .type = QEMU_OPT_STRING,
3191 /* Deprecated in favour of tls-creds */
3192 .name = "x509",
3193 .type = QEMU_OPT_STRING,
3195 .name = "share",
3196 .type = QEMU_OPT_STRING,
3198 .name = "display",
3199 .type = QEMU_OPT_STRING,
3201 .name = "head",
3202 .type = QEMU_OPT_NUMBER,
3204 .name = "connections",
3205 .type = QEMU_OPT_NUMBER,
3207 .name = "to",
3208 .type = QEMU_OPT_NUMBER,
3210 .name = "ipv4",
3211 .type = QEMU_OPT_BOOL,
3213 .name = "ipv6",
3214 .type = QEMU_OPT_BOOL,
3216 .name = "password",
3217 .type = QEMU_OPT_BOOL,
3219 .name = "reverse",
3220 .type = QEMU_OPT_BOOL,
3222 .name = "lock-key-sync",
3223 .type = QEMU_OPT_BOOL,
3225 .name = "key-delay-ms",
3226 .type = QEMU_OPT_NUMBER,
3228 .name = "sasl",
3229 .type = QEMU_OPT_BOOL,
3231 /* Deprecated in favour of tls-creds */
3232 .name = "tls",
3233 .type = QEMU_OPT_BOOL,
3235 /* Deprecated in favour of tls-creds */
3236 .name = "x509verify",
3237 .type = QEMU_OPT_STRING,
3239 .name = "acl",
3240 .type = QEMU_OPT_BOOL,
3242 .name = "lossy",
3243 .type = QEMU_OPT_BOOL,
3245 .name = "non-adaptive",
3246 .type = QEMU_OPT_BOOL,
3248 { /* end of list */ }
3253 static int
3254 vnc_display_setup_auth(int *auth,
3255 int *subauth,
3256 QCryptoTLSCreds *tlscreds,
3257 bool password,
3258 bool sasl,
3259 bool websocket,
3260 Error **errp)
3263 * We have a choice of 3 authentication options
3265 * 1. none
3266 * 2. vnc
3267 * 3. sasl
3269 * The channel can be run in 2 modes
3271 * 1. clear
3272 * 2. tls
3274 * And TLS can use 2 types of credentials
3276 * 1. anon
3277 * 2. x509
3279 * We thus have 9 possible logical combinations
3281 * 1. clear + none
3282 * 2. clear + vnc
3283 * 3. clear + sasl
3284 * 4. tls + anon + none
3285 * 5. tls + anon + vnc
3286 * 6. tls + anon + sasl
3287 * 7. tls + x509 + none
3288 * 8. tls + x509 + vnc
3289 * 9. tls + x509 + sasl
3291 * These need to be mapped into the VNC auth schemes
3292 * in an appropriate manner. In regular VNC, all the
3293 * TLS options get mapped into VNC_AUTH_VENCRYPT
3294 * sub-auth types.
3296 * In websockets, the https:// protocol already provides
3297 * TLS support, so there is no need to make use of the
3298 * VeNCrypt extension. Furthermore, websockets browser
3299 * clients could not use VeNCrypt even if they wanted to,
3300 * as they cannot control when the TLS handshake takes
3301 * place. Thus there is no option but to rely on https://,
3302 * meaning combinations 4->6 and 7->9 will be mapped to
3303 * VNC auth schemes in the same way as combos 1->3.
3305 * Regardless of fact that we have a different mapping to
3306 * VNC auth mechs for plain VNC vs websockets VNC, the end
3307 * result has the same security characteristics.
3309 if (websocket || !tlscreds) {
3310 if (password) {
3311 VNC_DEBUG("Initializing VNC server with password auth\n");
3312 *auth = VNC_AUTH_VNC;
3313 } else if (sasl) {
3314 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3315 *auth = VNC_AUTH_SASL;
3316 } else {
3317 VNC_DEBUG("Initializing VNC server with no auth\n");
3318 *auth = VNC_AUTH_NONE;
3320 *subauth = VNC_AUTH_INVALID;
3321 } else {
3322 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3323 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3324 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3325 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3327 if (!is_x509 && !is_anon) {
3328 error_setg(errp,
3329 "Unsupported TLS cred type %s",
3330 object_get_typename(OBJECT(tlscreds)));
3331 return -1;
3333 *auth = VNC_AUTH_VENCRYPT;
3334 if (password) {
3335 if (is_x509) {
3336 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3337 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3338 } else {
3339 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3340 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3343 } else if (sasl) {
3344 if (is_x509) {
3345 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3346 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3347 } else {
3348 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3349 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3351 } else {
3352 if (is_x509) {
3353 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3354 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3355 } else {
3356 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3357 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3361 return 0;
3366 * Handle back compat with old CLI syntax by creating some
3367 * suitable QCryptoTLSCreds objects
3369 static QCryptoTLSCreds *
3370 vnc_display_create_creds(bool x509,
3371 bool x509verify,
3372 const char *dir,
3373 const char *id,
3374 Error **errp)
3376 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3377 Object *parent = object_get_objects_root();
3378 Object *creds;
3379 Error *err = NULL;
3381 if (x509) {
3382 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3383 parent,
3384 credsid,
3385 &err,
3386 "endpoint", "server",
3387 "dir", dir,
3388 "verify-peer", x509verify ? "yes" : "no",
3389 NULL);
3390 } else {
3391 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3392 parent,
3393 credsid,
3394 &err,
3395 "endpoint", "server",
3396 NULL);
3399 g_free(credsid);
3401 if (err) {
3402 error_propagate(errp, err);
3403 return NULL;
3406 return QCRYPTO_TLS_CREDS(creds);
3410 static int vnc_display_get_address(const char *addrstr,
3411 bool websocket,
3412 bool reverse,
3413 int displaynum,
3414 int to,
3415 bool has_ipv4,
3416 bool has_ipv6,
3417 bool ipv4,
3418 bool ipv6,
3419 SocketAddress **retaddr,
3420 Error **errp)
3422 int ret = -1;
3423 SocketAddress *addr = NULL;
3425 addr = g_new0(SocketAddress, 1);
3427 if (strncmp(addrstr, "unix:", 5) == 0) {
3428 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3429 addr->u.q_unix.path = g_strdup(addrstr + 5);
3431 if (websocket) {
3432 error_setg(errp, "UNIX sockets not supported with websock");
3433 goto cleanup;
3436 if (to) {
3437 error_setg(errp, "Port range not support with UNIX socket");
3438 goto cleanup;
3440 ret = 0;
3441 } else {
3442 const char *port;
3443 size_t hostlen;
3444 unsigned long long baseport = 0;
3445 InetSocketAddress *inet;
3447 port = strrchr(addrstr, ':');
3448 if (!port) {
3449 if (websocket) {
3450 hostlen = 0;
3451 port = addrstr;
3452 } else {
3453 error_setg(errp, "no vnc port specified");
3454 goto cleanup;
3456 } else {
3457 hostlen = port - addrstr;
3458 port++;
3459 if (*port == '\0') {
3460 error_setg(errp, "vnc port cannot be empty");
3461 goto cleanup;
3465 addr->type = SOCKET_ADDRESS_TYPE_INET;
3466 inet = &addr->u.inet;
3467 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3468 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3469 } else {
3470 inet->host = g_strndup(addrstr, hostlen);
3472 /* plain VNC port is just an offset, for websocket
3473 * port is absolute */
3474 if (websocket) {
3475 if (g_str_equal(addrstr, "") ||
3476 g_str_equal(addrstr, "on")) {
3477 if (displaynum == -1) {
3478 error_setg(errp, "explicit websocket port is required");
3479 goto cleanup;
3481 inet->port = g_strdup_printf(
3482 "%d", displaynum + 5700);
3483 if (to) {
3484 inet->has_to = true;
3485 inet->to = to + 5700;
3487 } else {
3488 inet->port = g_strdup(port);
3490 } else {
3491 int offset = reverse ? 0 : 5900;
3492 if (parse_uint_full(port, &baseport, 10) < 0) {
3493 error_setg(errp, "can't convert to a number: %s", port);
3494 goto cleanup;
3496 if (baseport > 65535 ||
3497 baseport + offset > 65535) {
3498 error_setg(errp, "port %s out of range", port);
3499 goto cleanup;
3501 inet->port = g_strdup_printf(
3502 "%d", (int)baseport + offset);
3504 if (to) {
3505 inet->has_to = true;
3506 inet->to = to + offset;
3510 inet->ipv4 = ipv4;
3511 inet->has_ipv4 = has_ipv4;
3512 inet->ipv6 = ipv6;
3513 inet->has_ipv6 = has_ipv6;
3515 ret = baseport;
3518 *retaddr = addr;
3520 cleanup:
3521 if (ret < 0) {
3522 qapi_free_SocketAddress(addr);
3524 return ret;
3527 static void vnc_free_addresses(SocketAddress ***retsaddr,
3528 size_t *retnsaddr)
3530 size_t i;
3532 for (i = 0; i < *retnsaddr; i++) {
3533 qapi_free_SocketAddress((*retsaddr)[i]);
3535 g_free(*retsaddr);
3537 *retsaddr = NULL;
3538 *retnsaddr = 0;
3541 static int vnc_display_get_addresses(QemuOpts *opts,
3542 bool reverse,
3543 SocketAddress ***retsaddr,
3544 size_t *retnsaddr,
3545 SocketAddress ***retwsaddr,
3546 size_t *retnwsaddr,
3547 Error **errp)
3549 SocketAddress *saddr = NULL;
3550 SocketAddress *wsaddr = NULL;
3551 QemuOptsIter addriter;
3552 const char *addr;
3553 int to = qemu_opt_get_number(opts, "to", 0);
3554 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3555 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3556 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3557 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3558 int displaynum = -1;
3559 int ret = -1;
3561 *retsaddr = NULL;
3562 *retnsaddr = 0;
3563 *retwsaddr = NULL;
3564 *retnwsaddr = 0;
3566 addr = qemu_opt_get(opts, "vnc");
3567 if (addr == NULL || g_str_equal(addr, "none")) {
3568 ret = 0;
3569 goto cleanup;
3571 if (qemu_opt_get(opts, "websocket") &&
3572 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3573 error_setg(errp,
3574 "SHA1 hash support is required for websockets");
3575 goto cleanup;
3578 qemu_opt_iter_init(&addriter, opts, "vnc");
3579 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3580 int rv;
3581 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3582 has_ipv4, has_ipv6,
3583 ipv4, ipv6,
3584 &saddr, errp);
3585 if (rv < 0) {
3586 goto cleanup;
3588 /* Historical compat - first listen address can be used
3589 * to set the default websocket port
3591 if (displaynum == -1) {
3592 displaynum = rv;
3594 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3595 (*retsaddr)[(*retnsaddr)++] = saddr;
3598 /* If we had multiple primary displays, we don't do defaults
3599 * for websocket, and require explicit config instead. */
3600 if (*retnsaddr > 1) {
3601 displaynum = -1;
3604 qemu_opt_iter_init(&addriter, opts, "websocket");
3605 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3606 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3607 has_ipv4, has_ipv6,
3608 ipv4, ipv6,
3609 &wsaddr, errp) < 0) {
3610 goto cleanup;
3613 /* Historical compat - if only a single listen address was
3614 * provided, then this is used to set the default listen
3615 * address for websocket too
3617 if (*retnsaddr == 1 &&
3618 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3619 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3620 g_str_equal(wsaddr->u.inet.host, "") &&
3621 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3622 g_free(wsaddr->u.inet.host);
3623 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3626 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3627 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3630 ret = 0;
3631 cleanup:
3632 if (ret < 0) {
3633 vnc_free_addresses(retsaddr, retnsaddr);
3634 vnc_free_addresses(retwsaddr, retnwsaddr);
3636 return ret;
3639 static int vnc_display_connect(VncDisplay *vd,
3640 SocketAddress **saddr,
3641 size_t nsaddr,
3642 SocketAddress **wsaddr,
3643 size_t nwsaddr,
3644 Error **errp)
3646 /* connect to viewer */
3647 QIOChannelSocket *sioc = NULL;
3648 if (nwsaddr != 0) {
3649 error_setg(errp, "Cannot use websockets in reverse mode");
3650 return -1;
3652 if (nsaddr != 1) {
3653 error_setg(errp, "Expected a single address in reverse mode");
3654 return -1;
3656 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3657 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3658 sioc = qio_channel_socket_new();
3659 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3660 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3661 return -1;
3663 vnc_connect(vd, sioc, false, false);
3664 object_unref(OBJECT(sioc));
3665 return 0;
3669 static int vnc_display_listen_addr(VncDisplay *vd,
3670 SocketAddress *addr,
3671 const char *name,
3672 QIOChannelSocket ***lsock,
3673 guint **lsock_tag,
3674 size_t *nlsock,
3675 Error **errp)
3677 QIODNSResolver *resolver = qio_dns_resolver_get_instance();
3678 SocketAddress **rawaddrs = NULL;
3679 size_t nrawaddrs = 0;
3680 Error *listenerr = NULL;
3681 bool listening = false;
3682 size_t i;
3684 if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,
3685 &rawaddrs, errp) < 0) {
3686 return -1;
3689 for (i = 0; i < nrawaddrs; i++) {
3690 QIOChannelSocket *sioc = qio_channel_socket_new();
3692 qio_channel_set_name(QIO_CHANNEL(sioc), name);
3693 if (qio_channel_socket_listen_sync(
3694 sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
3695 object_unref(OBJECT(sioc));
3696 continue;
3698 listening = true;
3699 (*nlsock)++;
3700 *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);
3701 *lsock_tag = g_renew(guint, *lsock_tag, *nlsock);
3703 (*lsock)[*nlsock - 1] = sioc;
3704 (*lsock_tag)[*nlsock - 1] = 0;
3707 for (i = 0; i < nrawaddrs; i++) {
3708 qapi_free_SocketAddress(rawaddrs[i]);
3710 g_free(rawaddrs);
3712 if (listenerr) {
3713 if (!listening) {
3714 error_propagate(errp, listenerr);
3715 return -1;
3716 } else {
3717 error_free(listenerr);
3721 for (i = 0; i < *nlsock; i++) {
3722 (*lsock_tag)[i] = qio_channel_add_watch(
3723 QIO_CHANNEL((*lsock)[i]),
3724 G_IO_IN, vnc_listen_io, vd, NULL);
3727 return 0;
3731 static int vnc_display_listen(VncDisplay *vd,
3732 SocketAddress **saddr,
3733 size_t nsaddr,
3734 SocketAddress **wsaddr,
3735 size_t nwsaddr,
3736 Error **errp)
3738 size_t i;
3740 for (i = 0; i < nsaddr; i++) {
3741 if (vnc_display_listen_addr(vd, saddr[i],
3742 "vnc-listen",
3743 &vd->lsock,
3744 &vd->lsock_tag,
3745 &vd->nlsock,
3746 errp) < 0) {
3747 return -1;
3750 for (i = 0; i < nwsaddr; i++) {
3751 if (vnc_display_listen_addr(vd, wsaddr[i],
3752 "vnc-ws-listen",
3753 &vd->lwebsock,
3754 &vd->lwebsock_tag,
3755 &vd->nlwebsock,
3756 errp) < 0) {
3757 return -1;
3761 return 0;
3765 void vnc_display_open(const char *id, Error **errp)
3767 VncDisplay *vd = vnc_display_find(id);
3768 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3769 SocketAddress **saddr = NULL, **wsaddr = NULL;
3770 size_t nsaddr, nwsaddr;
3771 const char *share, *device_id;
3772 QemuConsole *con;
3773 bool password = false;
3774 bool reverse = false;
3775 const char *credid;
3776 bool sasl = false;
3777 #ifdef CONFIG_VNC_SASL
3778 int saslErr;
3779 #endif
3780 int acl = 0;
3781 int lock_key_sync = 1;
3782 int key_delay_ms;
3784 if (!vd) {
3785 error_setg(errp, "VNC display not active");
3786 return;
3788 vnc_display_close(vd);
3790 if (!opts) {
3791 return;
3794 reverse = qemu_opt_get_bool(opts, "reverse", false);
3795 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3796 &wsaddr, &nwsaddr, errp) < 0) {
3797 goto fail;
3800 password = qemu_opt_get_bool(opts, "password", false);
3801 if (password) {
3802 if (fips_get_state()) {
3803 error_setg(errp,
3804 "VNC password auth disabled due to FIPS mode, "
3805 "consider using the VeNCrypt or SASL authentication "
3806 "methods as an alternative");
3807 goto fail;
3809 if (!qcrypto_cipher_supports(
3810 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3811 error_setg(errp,
3812 "Cipher backend does not support DES RFB algorithm");
3813 goto fail;
3817 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3818 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
3819 sasl = qemu_opt_get_bool(opts, "sasl", false);
3820 #ifndef CONFIG_VNC_SASL
3821 if (sasl) {
3822 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3823 goto fail;
3825 #endif /* CONFIG_VNC_SASL */
3826 credid = qemu_opt_get(opts, "tls-creds");
3827 if (credid) {
3828 Object *creds;
3829 if (qemu_opt_get(opts, "tls") ||
3830 qemu_opt_get(opts, "x509") ||
3831 qemu_opt_get(opts, "x509verify")) {
3832 error_setg(errp,
3833 "'tls-creds' parameter is mutually exclusive with "
3834 "'tls', 'x509' and 'x509verify' parameters");
3835 goto fail;
3838 creds = object_resolve_path_component(
3839 object_get_objects_root(), credid);
3840 if (!creds) {
3841 error_setg(errp, "No TLS credentials with id '%s'",
3842 credid);
3843 goto fail;
3845 vd->tlscreds = (QCryptoTLSCreds *)
3846 object_dynamic_cast(creds,
3847 TYPE_QCRYPTO_TLS_CREDS);
3848 if (!vd->tlscreds) {
3849 error_setg(errp, "Object with id '%s' is not TLS credentials",
3850 credid);
3851 goto fail;
3853 object_ref(OBJECT(vd->tlscreds));
3855 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3856 error_setg(errp,
3857 "Expecting TLS credentials with a server endpoint");
3858 goto fail;
3860 } else {
3861 const char *path;
3862 bool tls = false, x509 = false, x509verify = false;
3863 tls = qemu_opt_get_bool(opts, "tls", false);
3864 if (tls) {
3865 path = qemu_opt_get(opts, "x509");
3867 if (path) {
3868 x509 = true;
3869 } else {
3870 path = qemu_opt_get(opts, "x509verify");
3871 if (path) {
3872 x509 = true;
3873 x509verify = true;
3876 vd->tlscreds = vnc_display_create_creds(x509,
3877 x509verify,
3878 path,
3879 vd->id,
3880 errp);
3881 if (!vd->tlscreds) {
3882 goto fail;
3886 acl = qemu_opt_get_bool(opts, "acl", false);
3888 share = qemu_opt_get(opts, "share");
3889 if (share) {
3890 if (strcmp(share, "ignore") == 0) {
3891 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
3892 } else if (strcmp(share, "allow-exclusive") == 0) {
3893 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3894 } else if (strcmp(share, "force-shared") == 0) {
3895 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3896 } else {
3897 error_setg(errp, "unknown vnc share= option");
3898 goto fail;
3900 } else {
3901 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3903 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3905 #ifdef CONFIG_VNC_JPEG
3906 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
3907 #endif
3908 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3909 /* adaptive updates are only used with tight encoding and
3910 * if lossy updates are enabled so we can disable all the
3911 * calculations otherwise */
3912 if (!vd->lossy) {
3913 vd->non_adaptive = true;
3916 if (acl) {
3917 if (strcmp(vd->id, "default") == 0) {
3918 vd->tlsaclname = g_strdup("vnc.x509dname");
3919 } else {
3920 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
3922 qemu_acl_init(vd->tlsaclname);
3924 #ifdef CONFIG_VNC_SASL
3925 if (acl && sasl) {
3926 char *aclname;
3928 if (strcmp(vd->id, "default") == 0) {
3929 aclname = g_strdup("vnc.username");
3930 } else {
3931 aclname = g_strdup_printf("vnc.%s.username", vd->id);
3933 vd->sasl.acl = qemu_acl_init(aclname);
3934 g_free(aclname);
3936 #endif
3938 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
3939 vd->tlscreds, password,
3940 sasl, false, errp) < 0) {
3941 goto fail;
3943 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
3945 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
3946 vd->tlscreds, password,
3947 sasl, true, errp) < 0) {
3948 goto fail;
3950 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
3952 #ifdef CONFIG_VNC_SASL
3953 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3954 error_setg(errp, "Failed to initialize SASL auth: %s",
3955 sasl_errstring(saslErr, NULL, NULL));
3956 goto fail;
3958 #endif
3959 vd->lock_key_sync = lock_key_sync;
3960 if (lock_key_sync) {
3961 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
3963 vd->ledstate = 0;
3964 vd->key_delay_ms = key_delay_ms;
3966 device_id = qemu_opt_get(opts, "display");
3967 if (device_id) {
3968 int head = qemu_opt_get_number(opts, "head", 0);
3969 Error *err = NULL;
3971 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3972 if (err) {
3973 error_propagate(errp, err);
3974 goto fail;
3976 } else {
3977 con = NULL;
3980 if (con != vd->dcl.con) {
3981 unregister_displaychangelistener(&vd->dcl);
3982 vd->dcl.con = con;
3983 register_displaychangelistener(&vd->dcl);
3986 if (saddr == NULL) {
3987 goto cleanup;
3990 if (reverse) {
3991 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3992 goto fail;
3994 } else {
3995 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3996 goto fail;
4000 if (qemu_opt_get(opts, "to")) {
4001 vnc_display_print_local_addr(vd);
4004 cleanup:
4005 vnc_free_addresses(&saddr, &nsaddr);
4006 vnc_free_addresses(&wsaddr, &nwsaddr);
4007 return;
4009 fail:
4010 vnc_display_close(vd);
4011 goto cleanup;
4014 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4016 VncDisplay *vd = vnc_display_find(id);
4017 QIOChannelSocket *sioc;
4019 if (!vd) {
4020 return;
4023 sioc = qio_channel_socket_new_fd(csock, NULL);
4024 if (sioc) {
4025 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4026 vnc_connect(vd, sioc, skipauth, false);
4027 object_unref(OBJECT(sioc));
4031 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4033 int i = 2;
4034 char *id;
4036 id = g_strdup("default");
4037 while (qemu_opts_find(olist, id)) {
4038 g_free(id);
4039 id = g_strdup_printf("vnc%d", i++);
4041 qemu_opts_set_id(opts, id);
4044 QemuOpts *vnc_parse(const char *str, Error **errp)
4046 QemuOptsList *olist = qemu_find_opts("vnc");
4047 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
4048 const char *id;
4050 if (!opts) {
4051 return NULL;
4054 id = qemu_opts_id(opts);
4055 if (!id) {
4056 /* auto-assign id if not present */
4057 vnc_auto_assign_id(olist, opts);
4059 return opts;
4062 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4064 Error *local_err = NULL;
4065 char *id = (char *)qemu_opts_id(opts);
4067 assert(id);
4068 vnc_display_init(id);
4069 vnc_display_open(id, &local_err);
4070 if (local_err != NULL) {
4071 error_reportf_err(local_err, "Failed to start VNC server: ");
4072 exit(1);
4074 return 0;
4077 static void vnc_register_config(void)
4079 qemu_add_opts(&qemu_vnc_opts);
4081 opts_init(vnc_register_config);