ui: remove unreachable code in vnc_update_client
[qemu/ar7.git] / ui / vnc.c
blob29a720847574be34527522f2280035710ce785db
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);
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)
966 if (vs->disconnecting) {
967 vnc_disconnect_finish(vs);
968 return 0;
971 vs->has_dirty += has_dirty;
972 if (vs->need_update) {
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 vs->force_update = 0;
1029 vs->has_dirty = 0;
1030 return n;
1033 return 0;
1036 /* audio */
1037 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1039 VncState *vs = opaque;
1041 switch (cmd) {
1042 case AUD_CNOTIFY_DISABLE:
1043 vnc_lock_output(vs);
1044 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1045 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1046 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1047 vnc_unlock_output(vs);
1048 vnc_flush(vs);
1049 break;
1051 case AUD_CNOTIFY_ENABLE:
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_BEGIN);
1056 vnc_unlock_output(vs);
1057 vnc_flush(vs);
1058 break;
1062 static void audio_capture_destroy(void *opaque)
1066 static void audio_capture(void *opaque, void *buf, int size)
1068 VncState *vs = opaque;
1070 vnc_lock_output(vs);
1071 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1072 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1073 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1074 vnc_write_u32(vs, size);
1075 vnc_write(vs, buf, size);
1076 vnc_unlock_output(vs);
1077 vnc_flush(vs);
1080 static void audio_add(VncState *vs)
1082 struct audio_capture_ops ops;
1084 if (vs->audio_cap) {
1085 error_report("audio already running");
1086 return;
1089 ops.notify = audio_capture_notify;
1090 ops.destroy = audio_capture_destroy;
1091 ops.capture = audio_capture;
1093 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1094 if (!vs->audio_cap) {
1095 error_report("Failed to add audio capture");
1099 static void audio_del(VncState *vs)
1101 if (vs->audio_cap) {
1102 AUD_del_capture(vs->audio_cap, vs);
1103 vs->audio_cap = NULL;
1107 static void vnc_disconnect_start(VncState *vs)
1109 if (vs->disconnecting) {
1110 return;
1112 trace_vnc_client_disconnect_start(vs, vs->ioc);
1113 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1114 if (vs->ioc_tag) {
1115 g_source_remove(vs->ioc_tag);
1116 vs->ioc_tag = 0;
1118 qio_channel_close(vs->ioc, NULL);
1119 vs->disconnecting = TRUE;
1122 void vnc_disconnect_finish(VncState *vs)
1124 int i;
1126 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1128 vnc_jobs_join(vs); /* Wait encoding jobs */
1130 vnc_lock_output(vs);
1131 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1133 buffer_free(&vs->input);
1134 buffer_free(&vs->output);
1136 qapi_free_VncClientInfo(vs->info);
1138 vnc_zlib_clear(vs);
1139 vnc_tight_clear(vs);
1140 vnc_zrle_clear(vs);
1142 #ifdef CONFIG_VNC_SASL
1143 vnc_sasl_client_cleanup(vs);
1144 #endif /* CONFIG_VNC_SASL */
1145 audio_del(vs);
1146 vnc_release_modifiers(vs);
1148 if (vs->mouse_mode_notifier.notify != NULL) {
1149 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1151 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1152 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1153 /* last client gone */
1154 vnc_update_server_surface(vs->vd);
1157 vnc_unlock_output(vs);
1159 qemu_mutex_destroy(&vs->output_mutex);
1160 if (vs->bh != NULL) {
1161 qemu_bh_delete(vs->bh);
1163 buffer_free(&vs->jobs_buffer);
1165 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1166 g_free(vs->lossy_rect[i]);
1168 g_free(vs->lossy_rect);
1170 object_unref(OBJECT(vs->ioc));
1171 vs->ioc = NULL;
1172 object_unref(OBJECT(vs->sioc));
1173 vs->sioc = NULL;
1174 g_free(vs);
1177 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1179 if (ret <= 0) {
1180 if (ret == 0) {
1181 trace_vnc_client_eof(vs, vs->ioc);
1182 vnc_disconnect_start(vs);
1183 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1184 trace_vnc_client_io_error(vs, vs->ioc,
1185 errp ? error_get_pretty(*errp) :
1186 "Unknown");
1187 vnc_disconnect_start(vs);
1190 if (errp) {
1191 error_free(*errp);
1192 *errp = NULL;
1194 return 0;
1196 return ret;
1200 void vnc_client_error(VncState *vs)
1202 VNC_DEBUG("Closing down client sock: protocol error\n");
1203 vnc_disconnect_start(vs);
1208 * Called to write a chunk of data to the client socket. The data may
1209 * be the raw data, or may have already been encoded by SASL.
1210 * The data will be written either straight onto the socket, or
1211 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1213 * NB, it is theoretically possible to have 2 layers of encryption,
1214 * both SASL, and this TLS layer. It is highly unlikely in practice
1215 * though, since SASL encryption will typically be a no-op if TLS
1216 * is active
1218 * Returns the number of bytes written, which may be less than
1219 * the requested 'datalen' if the socket would block. Returns
1220 * -1 on error, and disconnects the client socket.
1222 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1224 Error *err = NULL;
1225 ssize_t ret;
1226 ret = qio_channel_write(
1227 vs->ioc, (const char *)data, datalen, &err);
1228 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1229 return vnc_client_io_error(vs, ret, &err);
1234 * Called to write buffered data to the client socket, when not
1235 * using any SASL SSF encryption layers. Will write as much data
1236 * as possible without blocking. If all buffered data is written,
1237 * will switch the FD poll() handler back to read monitoring.
1239 * Returns the number of bytes written, which may be less than
1240 * the buffered output data if the socket would block. Returns
1241 * -1 on error, and disconnects the client socket.
1243 static ssize_t vnc_client_write_plain(VncState *vs)
1245 ssize_t ret;
1247 #ifdef CONFIG_VNC_SASL
1248 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1249 vs->output.buffer, vs->output.capacity, vs->output.offset,
1250 vs->sasl.waitWriteSSF);
1252 if (vs->sasl.conn &&
1253 vs->sasl.runSSF &&
1254 vs->sasl.waitWriteSSF) {
1255 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1256 if (ret)
1257 vs->sasl.waitWriteSSF -= ret;
1258 } else
1259 #endif /* CONFIG_VNC_SASL */
1260 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1261 if (!ret)
1262 return 0;
1264 buffer_advance(&vs->output, ret);
1266 if (vs->output.offset == 0) {
1267 if (vs->ioc_tag) {
1268 g_source_remove(vs->ioc_tag);
1270 vs->ioc_tag = qio_channel_add_watch(
1271 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1274 return ret;
1279 * First function called whenever there is data to be written to
1280 * the client socket. Will delegate actual work according to whether
1281 * SASL SSF layers are enabled (thus requiring encryption calls)
1283 static void vnc_client_write_locked(VncState *vs)
1285 #ifdef CONFIG_VNC_SASL
1286 if (vs->sasl.conn &&
1287 vs->sasl.runSSF &&
1288 !vs->sasl.waitWriteSSF) {
1289 vnc_client_write_sasl(vs);
1290 } else
1291 #endif /* CONFIG_VNC_SASL */
1293 vnc_client_write_plain(vs);
1297 static void vnc_client_write(VncState *vs)
1300 vnc_lock_output(vs);
1301 if (vs->output.offset) {
1302 vnc_client_write_locked(vs);
1303 } else if (vs->ioc != NULL) {
1304 if (vs->ioc_tag) {
1305 g_source_remove(vs->ioc_tag);
1307 vs->ioc_tag = qio_channel_add_watch(
1308 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1310 vnc_unlock_output(vs);
1313 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1315 vs->read_handler = func;
1316 vs->read_handler_expect = expecting;
1321 * Called to read a chunk of data from the client socket. The data may
1322 * be the raw data, or may need to be further decoded by SASL.
1323 * The data will be read either straight from to the socket, or
1324 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1326 * NB, it is theoretically possible to have 2 layers of encryption,
1327 * both SASL, and this TLS layer. It is highly unlikely in practice
1328 * though, since SASL encryption will typically be a no-op if TLS
1329 * is active
1331 * Returns the number of bytes read, which may be less than
1332 * the requested 'datalen' if the socket would block. Returns
1333 * -1 on error, and disconnects the client socket.
1335 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1337 ssize_t ret;
1338 Error *err = NULL;
1339 ret = qio_channel_read(
1340 vs->ioc, (char *)data, datalen, &err);
1341 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1342 return vnc_client_io_error(vs, ret, &err);
1347 * Called to read data from the client socket to the input buffer,
1348 * when not using any SASL SSF encryption layers. Will read as much
1349 * data as possible without blocking.
1351 * Returns the number of bytes read. Returns -1 on error, and
1352 * disconnects the client socket.
1354 static ssize_t vnc_client_read_plain(VncState *vs)
1356 ssize_t ret;
1357 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1358 vs->input.buffer, vs->input.capacity, vs->input.offset);
1359 buffer_reserve(&vs->input, 4096);
1360 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1361 if (!ret)
1362 return 0;
1363 vs->input.offset += ret;
1364 return ret;
1367 static void vnc_jobs_bh(void *opaque)
1369 VncState *vs = opaque;
1371 vnc_jobs_consume_buffer(vs);
1375 * First function called whenever there is more data to be read from
1376 * the client socket. Will delegate actual work according to whether
1377 * SASL SSF layers are enabled (thus requiring decryption calls)
1378 * Returns 0 on success, -1 if client disconnected
1380 static int vnc_client_read(VncState *vs)
1382 ssize_t ret;
1384 #ifdef CONFIG_VNC_SASL
1385 if (vs->sasl.conn && vs->sasl.runSSF)
1386 ret = vnc_client_read_sasl(vs);
1387 else
1388 #endif /* CONFIG_VNC_SASL */
1389 ret = vnc_client_read_plain(vs);
1390 if (!ret) {
1391 if (vs->disconnecting) {
1392 vnc_disconnect_finish(vs);
1393 return -1;
1395 return 0;
1398 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1399 size_t len = vs->read_handler_expect;
1400 int ret;
1402 ret = vs->read_handler(vs, vs->input.buffer, len);
1403 if (vs->disconnecting) {
1404 vnc_disconnect_finish(vs);
1405 return -1;
1408 if (!ret) {
1409 buffer_advance(&vs->input, len);
1410 } else {
1411 vs->read_handler_expect = ret;
1414 return 0;
1417 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1418 GIOCondition condition, void *opaque)
1420 VncState *vs = opaque;
1421 if (condition & G_IO_IN) {
1422 if (vnc_client_read(vs) < 0) {
1423 return TRUE;
1426 if (condition & G_IO_OUT) {
1427 vnc_client_write(vs);
1429 return TRUE;
1433 void vnc_write(VncState *vs, const void *data, size_t len)
1435 buffer_reserve(&vs->output, len);
1437 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1438 if (vs->ioc_tag) {
1439 g_source_remove(vs->ioc_tag);
1441 vs->ioc_tag = qio_channel_add_watch(
1442 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1445 buffer_append(&vs->output, data, len);
1448 void vnc_write_s32(VncState *vs, int32_t value)
1450 vnc_write_u32(vs, *(uint32_t *)&value);
1453 void vnc_write_u32(VncState *vs, uint32_t value)
1455 uint8_t buf[4];
1457 buf[0] = (value >> 24) & 0xFF;
1458 buf[1] = (value >> 16) & 0xFF;
1459 buf[2] = (value >> 8) & 0xFF;
1460 buf[3] = value & 0xFF;
1462 vnc_write(vs, buf, 4);
1465 void vnc_write_u16(VncState *vs, uint16_t value)
1467 uint8_t buf[2];
1469 buf[0] = (value >> 8) & 0xFF;
1470 buf[1] = value & 0xFF;
1472 vnc_write(vs, buf, 2);
1475 void vnc_write_u8(VncState *vs, uint8_t value)
1477 vnc_write(vs, (char *)&value, 1);
1480 void vnc_flush(VncState *vs)
1482 vnc_lock_output(vs);
1483 if (vs->ioc != NULL && vs->output.offset) {
1484 vnc_client_write_locked(vs);
1486 vnc_unlock_output(vs);
1489 static uint8_t read_u8(uint8_t *data, size_t offset)
1491 return data[offset];
1494 static uint16_t read_u16(uint8_t *data, size_t offset)
1496 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1499 static int32_t read_s32(uint8_t *data, size_t offset)
1501 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1502 (data[offset + 2] << 8) | data[offset + 3]);
1505 uint32_t read_u32(uint8_t *data, size_t offset)
1507 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1508 (data[offset + 2] << 8) | data[offset + 3]);
1511 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1515 static void check_pointer_type_change(Notifier *notifier, void *data)
1517 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1518 int absolute = qemu_input_is_absolute();
1520 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1521 vnc_lock_output(vs);
1522 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1523 vnc_write_u8(vs, 0);
1524 vnc_write_u16(vs, 1);
1525 vnc_framebuffer_update(vs, absolute, 0,
1526 pixman_image_get_width(vs->vd->server),
1527 pixman_image_get_height(vs->vd->server),
1528 VNC_ENCODING_POINTER_TYPE_CHANGE);
1529 vnc_unlock_output(vs);
1530 vnc_flush(vs);
1532 vs->absolute = absolute;
1535 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1537 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1538 [INPUT_BUTTON_LEFT] = 0x01,
1539 [INPUT_BUTTON_MIDDLE] = 0x02,
1540 [INPUT_BUTTON_RIGHT] = 0x04,
1541 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1542 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1544 QemuConsole *con = vs->vd->dcl.con;
1545 int width = pixman_image_get_width(vs->vd->server);
1546 int height = pixman_image_get_height(vs->vd->server);
1548 if (vs->last_bmask != button_mask) {
1549 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1550 vs->last_bmask = button_mask;
1553 if (vs->absolute) {
1554 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1555 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1556 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1557 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1558 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1559 } else {
1560 if (vs->last_x != -1) {
1561 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1562 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1564 vs->last_x = x;
1565 vs->last_y = y;
1567 qemu_input_event_sync();
1570 static void reset_keys(VncState *vs)
1572 int i;
1573 for(i = 0; i < 256; i++) {
1574 if (vs->modifiers_state[i]) {
1575 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1576 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1577 vs->modifiers_state[i] = 0;
1582 static void press_key(VncState *vs, int keysym)
1584 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1585 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1586 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1587 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1588 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1591 static void vnc_led_state_change(VncState *vs)
1593 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1594 return;
1597 vnc_lock_output(vs);
1598 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1599 vnc_write_u8(vs, 0);
1600 vnc_write_u16(vs, 1);
1601 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1602 vnc_write_u8(vs, vs->vd->ledstate);
1603 vnc_unlock_output(vs);
1604 vnc_flush(vs);
1607 static void kbd_leds(void *opaque, int ledstate)
1609 VncDisplay *vd = opaque;
1610 VncState *client;
1612 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1613 (ledstate & QEMU_NUM_LOCK_LED),
1614 (ledstate & QEMU_SCROLL_LOCK_LED));
1616 if (ledstate == vd->ledstate) {
1617 return;
1620 vd->ledstate = ledstate;
1622 QTAILQ_FOREACH(client, &vd->clients, next) {
1623 vnc_led_state_change(client);
1627 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1629 /* QEMU console switch */
1630 switch(keycode) {
1631 case 0x2a: /* Left Shift */
1632 case 0x36: /* Right Shift */
1633 case 0x1d: /* Left CTRL */
1634 case 0x9d: /* Right CTRL */
1635 case 0x38: /* Left ALT */
1636 case 0xb8: /* Right ALT */
1637 if (down)
1638 vs->modifiers_state[keycode] = 1;
1639 else
1640 vs->modifiers_state[keycode] = 0;
1641 break;
1642 case 0x02 ... 0x0a: /* '1' to '9' keys */
1643 if (vs->vd->dcl.con == NULL &&
1644 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1645 /* Reset the modifiers sent to the current console */
1646 reset_keys(vs);
1647 console_select(keycode - 0x02);
1648 return;
1650 break;
1651 case 0x3a: /* CapsLock */
1652 case 0x45: /* NumLock */
1653 if (down)
1654 vs->modifiers_state[keycode] ^= 1;
1655 break;
1658 /* Turn off the lock state sync logic if the client support the led
1659 state extension.
1661 if (down && vs->vd->lock_key_sync &&
1662 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1663 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1664 /* If the numlock state needs to change then simulate an additional
1665 keypress before sending this one. This will happen if the user
1666 toggles numlock away from the VNC window.
1668 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1669 if (!vs->modifiers_state[0x45]) {
1670 trace_vnc_key_sync_numlock(true);
1671 vs->modifiers_state[0x45] = 1;
1672 press_key(vs, 0xff7f);
1674 } else {
1675 if (vs->modifiers_state[0x45]) {
1676 trace_vnc_key_sync_numlock(false);
1677 vs->modifiers_state[0x45] = 0;
1678 press_key(vs, 0xff7f);
1683 if (down && vs->vd->lock_key_sync &&
1684 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1685 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1686 /* If the capslock state needs to change then simulate an additional
1687 keypress before sending this one. This will happen if the user
1688 toggles capslock away from the VNC window.
1690 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1691 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1692 int capslock = !!(vs->modifiers_state[0x3a]);
1693 if (capslock) {
1694 if (uppercase == shift) {
1695 trace_vnc_key_sync_capslock(false);
1696 vs->modifiers_state[0x3a] = 0;
1697 press_key(vs, 0xffe5);
1699 } else {
1700 if (uppercase != shift) {
1701 trace_vnc_key_sync_capslock(true);
1702 vs->modifiers_state[0x3a] = 1;
1703 press_key(vs, 0xffe5);
1708 if (qemu_console_is_graphic(NULL)) {
1709 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1710 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1711 } else {
1712 bool numlock = vs->modifiers_state[0x45];
1713 bool control = (vs->modifiers_state[0x1d] ||
1714 vs->modifiers_state[0x9d]);
1715 /* QEMU console emulation */
1716 if (down) {
1717 switch (keycode) {
1718 case 0x2a: /* Left Shift */
1719 case 0x36: /* Right Shift */
1720 case 0x1d: /* Left CTRL */
1721 case 0x9d: /* Right CTRL */
1722 case 0x38: /* Left ALT */
1723 case 0xb8: /* Right ALT */
1724 break;
1725 case 0xc8:
1726 kbd_put_keysym(QEMU_KEY_UP);
1727 break;
1728 case 0xd0:
1729 kbd_put_keysym(QEMU_KEY_DOWN);
1730 break;
1731 case 0xcb:
1732 kbd_put_keysym(QEMU_KEY_LEFT);
1733 break;
1734 case 0xcd:
1735 kbd_put_keysym(QEMU_KEY_RIGHT);
1736 break;
1737 case 0xd3:
1738 kbd_put_keysym(QEMU_KEY_DELETE);
1739 break;
1740 case 0xc7:
1741 kbd_put_keysym(QEMU_KEY_HOME);
1742 break;
1743 case 0xcf:
1744 kbd_put_keysym(QEMU_KEY_END);
1745 break;
1746 case 0xc9:
1747 kbd_put_keysym(QEMU_KEY_PAGEUP);
1748 break;
1749 case 0xd1:
1750 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1751 break;
1753 case 0x47:
1754 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1755 break;
1756 case 0x48:
1757 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1758 break;
1759 case 0x49:
1760 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1761 break;
1762 case 0x4b:
1763 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1764 break;
1765 case 0x4c:
1766 kbd_put_keysym('5');
1767 break;
1768 case 0x4d:
1769 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1770 break;
1771 case 0x4f:
1772 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1773 break;
1774 case 0x50:
1775 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1776 break;
1777 case 0x51:
1778 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1779 break;
1780 case 0x52:
1781 kbd_put_keysym('0');
1782 break;
1783 case 0x53:
1784 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1785 break;
1787 case 0xb5:
1788 kbd_put_keysym('/');
1789 break;
1790 case 0x37:
1791 kbd_put_keysym('*');
1792 break;
1793 case 0x4a:
1794 kbd_put_keysym('-');
1795 break;
1796 case 0x4e:
1797 kbd_put_keysym('+');
1798 break;
1799 case 0x9c:
1800 kbd_put_keysym('\n');
1801 break;
1803 default:
1804 if (control) {
1805 kbd_put_keysym(sym & 0x1f);
1806 } else {
1807 kbd_put_keysym(sym);
1809 break;
1815 static void vnc_release_modifiers(VncState *vs)
1817 static const int keycodes[] = {
1818 /* shift, control, alt keys, both left & right */
1819 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1821 int i, keycode;
1823 if (!qemu_console_is_graphic(NULL)) {
1824 return;
1826 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1827 keycode = keycodes[i];
1828 if (!vs->modifiers_state[keycode]) {
1829 continue;
1831 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1832 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1836 static const char *code2name(int keycode)
1838 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
1841 static void key_event(VncState *vs, int down, uint32_t sym)
1843 int keycode;
1844 int lsym = sym;
1846 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1847 lsym = lsym - 'A' + 'a';
1850 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1851 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1852 do_key_event(vs, down, keycode, sym);
1855 static void ext_key_event(VncState *vs, int down,
1856 uint32_t sym, uint16_t keycode)
1858 /* if the user specifies a keyboard layout, always use it */
1859 if (keyboard_layout) {
1860 key_event(vs, down, sym);
1861 } else {
1862 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1863 do_key_event(vs, down, keycode, sym);
1867 static void framebuffer_update_request(VncState *vs, int incremental,
1868 int x, int y, int w, int h)
1870 vs->need_update = 1;
1872 if (incremental) {
1873 return;
1876 vs->force_update = 1;
1877 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1880 static void send_ext_key_event_ack(VncState *vs)
1882 vnc_lock_output(vs);
1883 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1884 vnc_write_u8(vs, 0);
1885 vnc_write_u16(vs, 1);
1886 vnc_framebuffer_update(vs, 0, 0,
1887 pixman_image_get_width(vs->vd->server),
1888 pixman_image_get_height(vs->vd->server),
1889 VNC_ENCODING_EXT_KEY_EVENT);
1890 vnc_unlock_output(vs);
1891 vnc_flush(vs);
1894 static void send_ext_audio_ack(VncState *vs)
1896 vnc_lock_output(vs);
1897 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1898 vnc_write_u8(vs, 0);
1899 vnc_write_u16(vs, 1);
1900 vnc_framebuffer_update(vs, 0, 0,
1901 pixman_image_get_width(vs->vd->server),
1902 pixman_image_get_height(vs->vd->server),
1903 VNC_ENCODING_AUDIO);
1904 vnc_unlock_output(vs);
1905 vnc_flush(vs);
1908 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1910 int i;
1911 unsigned int enc = 0;
1913 vs->features = 0;
1914 vs->vnc_encoding = 0;
1915 vs->tight.compression = 9;
1916 vs->tight.quality = -1; /* Lossless by default */
1917 vs->absolute = -1;
1920 * Start from the end because the encodings are sent in order of preference.
1921 * This way the preferred encoding (first encoding defined in the array)
1922 * will be set at the end of the loop.
1924 for (i = n_encodings - 1; i >= 0; i--) {
1925 enc = encodings[i];
1926 switch (enc) {
1927 case VNC_ENCODING_RAW:
1928 vs->vnc_encoding = enc;
1929 break;
1930 case VNC_ENCODING_COPYRECT:
1931 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1932 break;
1933 case VNC_ENCODING_HEXTILE:
1934 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1935 vs->vnc_encoding = enc;
1936 break;
1937 case VNC_ENCODING_TIGHT:
1938 vs->features |= VNC_FEATURE_TIGHT_MASK;
1939 vs->vnc_encoding = enc;
1940 break;
1941 #ifdef CONFIG_VNC_PNG
1942 case VNC_ENCODING_TIGHT_PNG:
1943 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
1944 vs->vnc_encoding = enc;
1945 break;
1946 #endif
1947 case VNC_ENCODING_ZLIB:
1948 vs->features |= VNC_FEATURE_ZLIB_MASK;
1949 vs->vnc_encoding = enc;
1950 break;
1951 case VNC_ENCODING_ZRLE:
1952 vs->features |= VNC_FEATURE_ZRLE_MASK;
1953 vs->vnc_encoding = enc;
1954 break;
1955 case VNC_ENCODING_ZYWRLE:
1956 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
1957 vs->vnc_encoding = enc;
1958 break;
1959 case VNC_ENCODING_DESKTOPRESIZE:
1960 vs->features |= VNC_FEATURE_RESIZE_MASK;
1961 break;
1962 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1963 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1964 break;
1965 case VNC_ENCODING_RICH_CURSOR:
1966 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
1967 if (vs->vd->cursor) {
1968 vnc_cursor_define(vs);
1970 break;
1971 case VNC_ENCODING_EXT_KEY_EVENT:
1972 send_ext_key_event_ack(vs);
1973 break;
1974 case VNC_ENCODING_AUDIO:
1975 send_ext_audio_ack(vs);
1976 break;
1977 case VNC_ENCODING_WMVi:
1978 vs->features |= VNC_FEATURE_WMVI_MASK;
1979 break;
1980 case VNC_ENCODING_LED_STATE:
1981 vs->features |= VNC_FEATURE_LED_STATE_MASK;
1982 break;
1983 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1984 vs->tight.compression = (enc & 0x0F);
1985 break;
1986 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1987 if (vs->vd->lossy) {
1988 vs->tight.quality = (enc & 0x0F);
1990 break;
1991 default:
1992 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1993 break;
1996 vnc_desktop_resize(vs);
1997 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
1998 vnc_led_state_change(vs);
2001 static void set_pixel_conversion(VncState *vs)
2003 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2005 if (fmt == VNC_SERVER_FB_FORMAT) {
2006 vs->write_pixels = vnc_write_pixels_copy;
2007 vnc_hextile_set_pixel_conversion(vs, 0);
2008 } else {
2009 vs->write_pixels = vnc_write_pixels_generic;
2010 vnc_hextile_set_pixel_conversion(vs, 1);
2014 static void send_color_map(VncState *vs)
2016 int i;
2018 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2019 vnc_write_u8(vs, 0); /* padding */
2020 vnc_write_u16(vs, 0); /* first color */
2021 vnc_write_u16(vs, 256); /* # of colors */
2023 for (i = 0; i < 256; i++) {
2024 PixelFormat *pf = &vs->client_pf;
2026 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2027 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2028 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2032 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2033 int big_endian_flag, int true_color_flag,
2034 int red_max, int green_max, int blue_max,
2035 int red_shift, int green_shift, int blue_shift)
2037 if (!true_color_flag) {
2038 /* Expose a reasonable default 256 color map */
2039 bits_per_pixel = 8;
2040 red_max = 7;
2041 green_max = 7;
2042 blue_max = 3;
2043 red_shift = 0;
2044 green_shift = 3;
2045 blue_shift = 6;
2048 switch (bits_per_pixel) {
2049 case 8:
2050 case 16:
2051 case 32:
2052 break;
2053 default:
2054 vnc_client_error(vs);
2055 return;
2058 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2059 vs->client_pf.rbits = ctpopl(red_max);
2060 vs->client_pf.rshift = red_shift;
2061 vs->client_pf.rmask = red_max << red_shift;
2062 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2063 vs->client_pf.gbits = ctpopl(green_max);
2064 vs->client_pf.gshift = green_shift;
2065 vs->client_pf.gmask = green_max << green_shift;
2066 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2067 vs->client_pf.bbits = ctpopl(blue_max);
2068 vs->client_pf.bshift = blue_shift;
2069 vs->client_pf.bmask = blue_max << blue_shift;
2070 vs->client_pf.bits_per_pixel = bits_per_pixel;
2071 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2072 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2073 vs->client_be = big_endian_flag;
2075 if (!true_color_flag) {
2076 send_color_map(vs);
2079 set_pixel_conversion(vs);
2081 graphic_hw_invalidate(vs->vd->dcl.con);
2082 graphic_hw_update(vs->vd->dcl.con);
2085 static void pixel_format_message (VncState *vs) {
2086 char pad[3] = { 0, 0, 0 };
2088 vs->client_pf = qemu_default_pixelformat(32);
2090 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2091 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2093 #ifdef HOST_WORDS_BIGENDIAN
2094 vnc_write_u8(vs, 1); /* big-endian-flag */
2095 #else
2096 vnc_write_u8(vs, 0); /* big-endian-flag */
2097 #endif
2098 vnc_write_u8(vs, 1); /* true-color-flag */
2099 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2100 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2101 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2102 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2103 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2104 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2105 vnc_write(vs, pad, 3); /* padding */
2107 vnc_hextile_set_pixel_conversion(vs, 0);
2108 vs->write_pixels = vnc_write_pixels_copy;
2111 static void vnc_colordepth(VncState *vs)
2113 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2114 /* Sending a WMVi message to notify the client*/
2115 vnc_lock_output(vs);
2116 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2117 vnc_write_u8(vs, 0);
2118 vnc_write_u16(vs, 1); /* number of rects */
2119 vnc_framebuffer_update(vs, 0, 0,
2120 pixman_image_get_width(vs->vd->server),
2121 pixman_image_get_height(vs->vd->server),
2122 VNC_ENCODING_WMVi);
2123 pixel_format_message(vs);
2124 vnc_unlock_output(vs);
2125 vnc_flush(vs);
2126 } else {
2127 set_pixel_conversion(vs);
2131 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2133 int i;
2134 uint16_t limit;
2135 VncDisplay *vd = vs->vd;
2137 if (data[0] > 3) {
2138 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2141 switch (data[0]) {
2142 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2143 if (len == 1)
2144 return 20;
2146 set_pixel_format(vs, read_u8(data, 4),
2147 read_u8(data, 6), read_u8(data, 7),
2148 read_u16(data, 8), read_u16(data, 10),
2149 read_u16(data, 12), read_u8(data, 14),
2150 read_u8(data, 15), read_u8(data, 16));
2151 break;
2152 case VNC_MSG_CLIENT_SET_ENCODINGS:
2153 if (len == 1)
2154 return 4;
2156 if (len == 4) {
2157 limit = read_u16(data, 2);
2158 if (limit > 0)
2159 return 4 + (limit * 4);
2160 } else
2161 limit = read_u16(data, 2);
2163 for (i = 0; i < limit; i++) {
2164 int32_t val = read_s32(data, 4 + (i * 4));
2165 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2168 set_encodings(vs, (int32_t *)(data + 4), limit);
2169 break;
2170 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2171 if (len == 1)
2172 return 10;
2174 framebuffer_update_request(vs,
2175 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2176 read_u16(data, 6), read_u16(data, 8));
2177 break;
2178 case VNC_MSG_CLIENT_KEY_EVENT:
2179 if (len == 1)
2180 return 8;
2182 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2183 break;
2184 case VNC_MSG_CLIENT_POINTER_EVENT:
2185 if (len == 1)
2186 return 6;
2188 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2189 break;
2190 case VNC_MSG_CLIENT_CUT_TEXT:
2191 if (len == 1) {
2192 return 8;
2194 if (len == 8) {
2195 uint32_t dlen = read_u32(data, 4);
2196 if (dlen > (1 << 20)) {
2197 error_report("vnc: client_cut_text msg payload has %u bytes"
2198 " which exceeds our limit of 1MB.", dlen);
2199 vnc_client_error(vs);
2200 break;
2202 if (dlen > 0) {
2203 return 8 + dlen;
2207 client_cut_text(vs, read_u32(data, 4), data + 8);
2208 break;
2209 case VNC_MSG_CLIENT_QEMU:
2210 if (len == 1)
2211 return 2;
2213 switch (read_u8(data, 1)) {
2214 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2215 if (len == 2)
2216 return 12;
2218 ext_key_event(vs, read_u16(data, 2),
2219 read_u32(data, 4), read_u32(data, 8));
2220 break;
2221 case VNC_MSG_CLIENT_QEMU_AUDIO:
2222 if (len == 2)
2223 return 4;
2225 switch (read_u16 (data, 2)) {
2226 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2227 audio_add(vs);
2228 break;
2229 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2230 audio_del(vs);
2231 break;
2232 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2233 if (len == 4)
2234 return 10;
2235 switch (read_u8(data, 4)) {
2236 case 0: vs->as.fmt = AUD_FMT_U8; break;
2237 case 1: vs->as.fmt = AUD_FMT_S8; break;
2238 case 2: vs->as.fmt = AUD_FMT_U16; break;
2239 case 3: vs->as.fmt = AUD_FMT_S16; break;
2240 case 4: vs->as.fmt = AUD_FMT_U32; break;
2241 case 5: vs->as.fmt = AUD_FMT_S32; break;
2242 default:
2243 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2244 vnc_client_error(vs);
2245 break;
2247 vs->as.nchannels = read_u8(data, 5);
2248 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2249 VNC_DEBUG("Invalid audio channel count %d\n",
2250 read_u8(data, 5));
2251 vnc_client_error(vs);
2252 break;
2254 vs->as.freq = read_u32(data, 6);
2255 break;
2256 default:
2257 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2258 vnc_client_error(vs);
2259 break;
2261 break;
2263 default:
2264 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2265 vnc_client_error(vs);
2266 break;
2268 break;
2269 default:
2270 VNC_DEBUG("Msg: %d\n", data[0]);
2271 vnc_client_error(vs);
2272 break;
2275 vnc_read_when(vs, protocol_client_msg, 1);
2276 return 0;
2279 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2281 char buf[1024];
2282 VncShareMode mode;
2283 int size;
2285 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2286 switch (vs->vd->share_policy) {
2287 case VNC_SHARE_POLICY_IGNORE:
2289 * Ignore the shared flag. Nothing to do here.
2291 * Doesn't conform to the rfb spec but is traditional qemu
2292 * behavior, thus left here as option for compatibility
2293 * reasons.
2295 break;
2296 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2298 * Policy: Allow clients ask for exclusive access.
2300 * Implementation: When a client asks for exclusive access,
2301 * disconnect all others. Shared connects are allowed as long
2302 * as no exclusive connection exists.
2304 * This is how the rfb spec suggests to handle the shared flag.
2306 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2307 VncState *client;
2308 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2309 if (vs == client) {
2310 continue;
2312 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2313 client->share_mode != VNC_SHARE_MODE_SHARED) {
2314 continue;
2316 vnc_disconnect_start(client);
2319 if (mode == VNC_SHARE_MODE_SHARED) {
2320 if (vs->vd->num_exclusive > 0) {
2321 vnc_disconnect_start(vs);
2322 return 0;
2325 break;
2326 case VNC_SHARE_POLICY_FORCE_SHARED:
2328 * Policy: Shared connects only.
2329 * Implementation: Disallow clients asking for exclusive access.
2331 * Useful for shared desktop sessions where you don't want
2332 * someone forgetting to say -shared when running the vnc
2333 * client disconnect everybody else.
2335 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2336 vnc_disconnect_start(vs);
2337 return 0;
2339 break;
2341 vnc_set_share_mode(vs, mode);
2343 if (vs->vd->num_shared > vs->vd->connections_limit) {
2344 vnc_disconnect_start(vs);
2345 return 0;
2348 vs->client_width = pixman_image_get_width(vs->vd->server);
2349 vs->client_height = pixman_image_get_height(vs->vd->server);
2350 vnc_write_u16(vs, vs->client_width);
2351 vnc_write_u16(vs, vs->client_height);
2353 pixel_format_message(vs);
2355 if (qemu_name) {
2356 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2357 if (size > sizeof(buf)) {
2358 size = sizeof(buf);
2360 } else {
2361 size = snprintf(buf, sizeof(buf), "QEMU");
2364 vnc_write_u32(vs, size);
2365 vnc_write(vs, buf, size);
2366 vnc_flush(vs);
2368 vnc_client_cache_auth(vs);
2369 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2371 vnc_read_when(vs, protocol_client_msg, 1);
2373 return 0;
2376 void start_client_init(VncState *vs)
2378 vnc_read_when(vs, protocol_client_init, 1);
2381 static void make_challenge(VncState *vs)
2383 int i;
2385 srand(time(NULL)+getpid()+getpid()*987654+rand());
2387 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2388 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2391 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2393 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2394 size_t i, pwlen;
2395 unsigned char key[8];
2396 time_t now = time(NULL);
2397 QCryptoCipher *cipher = NULL;
2398 Error *err = NULL;
2400 if (!vs->vd->password) {
2401 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2402 goto reject;
2404 if (vs->vd->expires < now) {
2405 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2406 goto reject;
2409 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2411 /* Calculate the expected challenge response */
2412 pwlen = strlen(vs->vd->password);
2413 for (i=0; i<sizeof(key); i++)
2414 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2416 cipher = qcrypto_cipher_new(
2417 QCRYPTO_CIPHER_ALG_DES_RFB,
2418 QCRYPTO_CIPHER_MODE_ECB,
2419 key, G_N_ELEMENTS(key),
2420 &err);
2421 if (!cipher) {
2422 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2423 error_get_pretty(err));
2424 error_free(err);
2425 goto reject;
2428 if (qcrypto_cipher_encrypt(cipher,
2429 vs->challenge,
2430 response,
2431 VNC_AUTH_CHALLENGE_SIZE,
2432 &err) < 0) {
2433 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2434 error_get_pretty(err));
2435 error_free(err);
2436 goto reject;
2439 /* Compare expected vs actual challenge response */
2440 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2441 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2442 goto reject;
2443 } else {
2444 trace_vnc_auth_pass(vs, vs->auth);
2445 vnc_write_u32(vs, 0); /* Accept auth */
2446 vnc_flush(vs);
2448 start_client_init(vs);
2451 qcrypto_cipher_free(cipher);
2452 return 0;
2454 reject:
2455 vnc_write_u32(vs, 1); /* Reject auth */
2456 if (vs->minor >= 8) {
2457 static const char err[] = "Authentication failed";
2458 vnc_write_u32(vs, sizeof(err));
2459 vnc_write(vs, err, sizeof(err));
2461 vnc_flush(vs);
2462 vnc_client_error(vs);
2463 qcrypto_cipher_free(cipher);
2464 return 0;
2467 void start_auth_vnc(VncState *vs)
2469 make_challenge(vs);
2470 /* Send client a 'random' challenge */
2471 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2472 vnc_flush(vs);
2474 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2478 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2480 /* We only advertise 1 auth scheme at a time, so client
2481 * must pick the one we sent. Verify this */
2482 if (data[0] != vs->auth) { /* Reject auth */
2483 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2484 vnc_write_u32(vs, 1);
2485 if (vs->minor >= 8) {
2486 static const char err[] = "Authentication failed";
2487 vnc_write_u32(vs, sizeof(err));
2488 vnc_write(vs, err, sizeof(err));
2490 vnc_client_error(vs);
2491 } else { /* Accept requested auth */
2492 trace_vnc_auth_start(vs, vs->auth);
2493 switch (vs->auth) {
2494 case VNC_AUTH_NONE:
2495 if (vs->minor >= 8) {
2496 vnc_write_u32(vs, 0); /* Accept auth completion */
2497 vnc_flush(vs);
2499 trace_vnc_auth_pass(vs, vs->auth);
2500 start_client_init(vs);
2501 break;
2503 case VNC_AUTH_VNC:
2504 start_auth_vnc(vs);
2505 break;
2507 case VNC_AUTH_VENCRYPT:
2508 start_auth_vencrypt(vs);
2509 break;
2511 #ifdef CONFIG_VNC_SASL
2512 case VNC_AUTH_SASL:
2513 start_auth_sasl(vs);
2514 break;
2515 #endif /* CONFIG_VNC_SASL */
2517 default: /* Should not be possible, but just in case */
2518 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2519 vnc_write_u8(vs, 1);
2520 if (vs->minor >= 8) {
2521 static const char err[] = "Authentication failed";
2522 vnc_write_u32(vs, sizeof(err));
2523 vnc_write(vs, err, sizeof(err));
2525 vnc_client_error(vs);
2528 return 0;
2531 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2533 char local[13];
2535 memcpy(local, version, 12);
2536 local[12] = 0;
2538 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2539 VNC_DEBUG("Malformed protocol version %s\n", local);
2540 vnc_client_error(vs);
2541 return 0;
2543 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2544 if (vs->major != 3 ||
2545 (vs->minor != 3 &&
2546 vs->minor != 4 &&
2547 vs->minor != 5 &&
2548 vs->minor != 7 &&
2549 vs->minor != 8)) {
2550 VNC_DEBUG("Unsupported client version\n");
2551 vnc_write_u32(vs, VNC_AUTH_INVALID);
2552 vnc_flush(vs);
2553 vnc_client_error(vs);
2554 return 0;
2556 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2557 * as equivalent to v3.3 by servers
2559 if (vs->minor == 4 || vs->minor == 5)
2560 vs->minor = 3;
2562 if (vs->minor == 3) {
2563 trace_vnc_auth_start(vs, vs->auth);
2564 if (vs->auth == VNC_AUTH_NONE) {
2565 vnc_write_u32(vs, vs->auth);
2566 vnc_flush(vs);
2567 trace_vnc_auth_pass(vs, vs->auth);
2568 start_client_init(vs);
2569 } else if (vs->auth == VNC_AUTH_VNC) {
2570 VNC_DEBUG("Tell client VNC auth\n");
2571 vnc_write_u32(vs, vs->auth);
2572 vnc_flush(vs);
2573 start_auth_vnc(vs);
2574 } else {
2575 trace_vnc_auth_fail(vs, vs->auth,
2576 "Unsupported auth method for v3.3", "");
2577 vnc_write_u32(vs, VNC_AUTH_INVALID);
2578 vnc_flush(vs);
2579 vnc_client_error(vs);
2581 } else {
2582 vnc_write_u8(vs, 1); /* num auth */
2583 vnc_write_u8(vs, vs->auth);
2584 vnc_read_when(vs, protocol_client_auth, 1);
2585 vnc_flush(vs);
2588 return 0;
2591 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2593 struct VncSurface *vs = &vd->guest;
2595 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2598 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2600 int i, j;
2602 w = (x + w) / VNC_STAT_RECT;
2603 h = (y + h) / VNC_STAT_RECT;
2604 x /= VNC_STAT_RECT;
2605 y /= VNC_STAT_RECT;
2607 for (j = y; j <= h; j++) {
2608 for (i = x; i <= w; i++) {
2609 vs->lossy_rect[j][i] = 1;
2614 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2616 VncState *vs;
2617 int sty = y / VNC_STAT_RECT;
2618 int stx = x / VNC_STAT_RECT;
2619 int has_dirty = 0;
2621 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2622 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2624 QTAILQ_FOREACH(vs, &vd->clients, next) {
2625 int j;
2627 /* kernel send buffers are full -> refresh later */
2628 if (vs->output.offset) {
2629 continue;
2632 if (!vs->lossy_rect[sty][stx]) {
2633 continue;
2636 vs->lossy_rect[sty][stx] = 0;
2637 for (j = 0; j < VNC_STAT_RECT; ++j) {
2638 bitmap_set(vs->dirty[y + j],
2639 x / VNC_DIRTY_PIXELS_PER_BIT,
2640 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2642 has_dirty++;
2645 return has_dirty;
2648 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2650 int width = MIN(pixman_image_get_width(vd->guest.fb),
2651 pixman_image_get_width(vd->server));
2652 int height = MIN(pixman_image_get_height(vd->guest.fb),
2653 pixman_image_get_height(vd->server));
2654 int x, y;
2655 struct timeval res;
2656 int has_dirty = 0;
2658 for (y = 0; y < height; y += VNC_STAT_RECT) {
2659 for (x = 0; x < width; x += VNC_STAT_RECT) {
2660 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2662 rect->updated = false;
2666 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2668 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2669 return has_dirty;
2671 vd->guest.last_freq_check = *tv;
2673 for (y = 0; y < height; y += VNC_STAT_RECT) {
2674 for (x = 0; x < width; x += VNC_STAT_RECT) {
2675 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2676 int count = ARRAY_SIZE(rect->times);
2677 struct timeval min, max;
2679 if (!timerisset(&rect->times[count - 1])) {
2680 continue ;
2683 max = rect->times[(rect->idx + count - 1) % count];
2684 qemu_timersub(tv, &max, &res);
2686 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2687 rect->freq = 0;
2688 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2689 memset(rect->times, 0, sizeof (rect->times));
2690 continue ;
2693 min = rect->times[rect->idx];
2694 max = rect->times[(rect->idx + count - 1) % count];
2695 qemu_timersub(&max, &min, &res);
2697 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2698 rect->freq /= count;
2699 rect->freq = 1. / rect->freq;
2702 return has_dirty;
2705 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2707 int i, j;
2708 double total = 0;
2709 int num = 0;
2711 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2712 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2714 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2715 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2716 total += vnc_stat_rect(vs->vd, i, j)->freq;
2717 num++;
2721 if (num) {
2722 return total / num;
2723 } else {
2724 return 0;
2728 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2730 VncRectStat *rect;
2732 rect = vnc_stat_rect(vd, x, y);
2733 if (rect->updated) {
2734 return ;
2736 rect->times[rect->idx] = *tv;
2737 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2738 rect->updated = true;
2741 static int vnc_refresh_server_surface(VncDisplay *vd)
2743 int width = MIN(pixman_image_get_width(vd->guest.fb),
2744 pixman_image_get_width(vd->server));
2745 int height = MIN(pixman_image_get_height(vd->guest.fb),
2746 pixman_image_get_height(vd->server));
2747 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2748 uint8_t *guest_row0 = NULL, *server_row0;
2749 VncState *vs;
2750 int has_dirty = 0;
2751 pixman_image_t *tmpbuf = NULL;
2753 struct timeval tv = { 0, 0 };
2755 if (!vd->non_adaptive) {
2756 gettimeofday(&tv, NULL);
2757 has_dirty = vnc_update_stats(vd, &tv);
2761 * Walk through the guest dirty map.
2762 * Check and copy modified bits from guest to server surface.
2763 * Update server dirty map.
2765 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2766 server_stride = guest_stride = guest_ll =
2767 pixman_image_get_stride(vd->server);
2768 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2769 server_stride);
2770 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2771 int width = pixman_image_get_width(vd->server);
2772 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2773 } else {
2774 int guest_bpp =
2775 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2776 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2777 guest_stride = pixman_image_get_stride(vd->guest.fb);
2778 guest_ll = pixman_image_get_width(vd->guest.fb) * (DIV_ROUND_UP(guest_bpp, 8));
2780 line_bytes = MIN(server_stride, guest_ll);
2782 for (;;) {
2783 int x;
2784 uint8_t *guest_ptr, *server_ptr;
2785 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2786 height * VNC_DIRTY_BPL(&vd->guest),
2787 y * VNC_DIRTY_BPL(&vd->guest));
2788 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2789 /* no more dirty bits */
2790 break;
2792 y = offset / VNC_DIRTY_BPL(&vd->guest);
2793 x = offset % VNC_DIRTY_BPL(&vd->guest);
2795 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2797 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2798 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2799 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2800 } else {
2801 guest_ptr = guest_row0 + y * guest_stride;
2803 guest_ptr += x * cmp_bytes;
2805 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2806 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2807 int _cmp_bytes = cmp_bytes;
2808 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2809 continue;
2811 if ((x + 1) * cmp_bytes > line_bytes) {
2812 _cmp_bytes = line_bytes - x * cmp_bytes;
2814 assert(_cmp_bytes >= 0);
2815 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2816 continue;
2818 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2819 if (!vd->non_adaptive) {
2820 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2821 y, &tv);
2823 QTAILQ_FOREACH(vs, &vd->clients, next) {
2824 set_bit(x, vs->dirty[y]);
2826 has_dirty++;
2829 y++;
2831 qemu_pixman_image_unref(tmpbuf);
2832 return has_dirty;
2835 static void vnc_refresh(DisplayChangeListener *dcl)
2837 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2838 VncState *vs, *vn;
2839 int has_dirty, rects = 0;
2841 if (QTAILQ_EMPTY(&vd->clients)) {
2842 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2843 return;
2846 graphic_hw_update(vd->dcl.con);
2848 if (vnc_trylock_display(vd)) {
2849 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2850 return;
2853 has_dirty = vnc_refresh_server_surface(vd);
2854 vnc_unlock_display(vd);
2856 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2857 rects += vnc_update_client(vs, has_dirty);
2858 /* vs might be free()ed here */
2861 if (has_dirty && rects) {
2862 vd->dcl.update_interval /= 2;
2863 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2864 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2866 } else {
2867 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2868 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2869 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2874 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2875 bool skipauth, bool websocket)
2877 VncState *vs = g_new0(VncState, 1);
2878 bool first_client = QTAILQ_EMPTY(&vd->clients);
2879 int i;
2881 trace_vnc_client_connect(vs, sioc);
2882 vs->sioc = sioc;
2883 object_ref(OBJECT(vs->sioc));
2884 vs->ioc = QIO_CHANNEL(sioc);
2885 object_ref(OBJECT(vs->ioc));
2886 vs->vd = vd;
2888 buffer_init(&vs->input, "vnc-input/%p", sioc);
2889 buffer_init(&vs->output, "vnc-output/%p", sioc);
2890 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2892 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2893 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2894 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2895 #ifdef CONFIG_VNC_JPEG
2896 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2897 #endif
2898 #ifdef CONFIG_VNC_PNG
2899 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2900 #endif
2901 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2902 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2903 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2904 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2906 if (skipauth) {
2907 vs->auth = VNC_AUTH_NONE;
2908 vs->subauth = VNC_AUTH_INVALID;
2909 } else {
2910 if (websocket) {
2911 vs->auth = vd->ws_auth;
2912 vs->subauth = VNC_AUTH_INVALID;
2913 } else {
2914 vs->auth = vd->auth;
2915 vs->subauth = vd->subauth;
2918 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2919 sioc, websocket, vs->auth, vs->subauth);
2921 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
2922 for (i = 0; i < VNC_STAT_ROWS; ++i) {
2923 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
2926 VNC_DEBUG("New client on socket %p\n", vs->sioc);
2927 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2928 qio_channel_set_blocking(vs->ioc, false, NULL);
2929 if (vs->ioc_tag) {
2930 g_source_remove(vs->ioc_tag);
2932 if (websocket) {
2933 vs->websocket = 1;
2934 if (vd->tlscreds) {
2935 vs->ioc_tag = qio_channel_add_watch(
2936 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
2937 } else {
2938 vs->ioc_tag = qio_channel_add_watch(
2939 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
2941 } else {
2942 vs->ioc_tag = qio_channel_add_watch(
2943 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
2946 vnc_client_cache_addr(vs);
2947 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
2948 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
2950 vs->last_x = -1;
2951 vs->last_y = -1;
2953 vs->as.freq = 44100;
2954 vs->as.nchannels = 2;
2955 vs->as.fmt = AUD_FMT_S16;
2956 vs->as.endianness = 0;
2958 qemu_mutex_init(&vs->output_mutex);
2959 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
2961 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
2962 if (first_client) {
2963 vnc_update_server_surface(vd);
2966 graphic_hw_update(vd->dcl.con);
2968 if (!vs->websocket) {
2969 vnc_start_protocol(vs);
2972 if (vd->num_connecting > vd->connections_limit) {
2973 QTAILQ_FOREACH(vs, &vd->clients, next) {
2974 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
2975 vnc_disconnect_start(vs);
2976 return;
2982 void vnc_start_protocol(VncState *vs)
2984 vnc_write(vs, "RFB 003.008\n", 12);
2985 vnc_flush(vs);
2986 vnc_read_when(vs, protocol_version, 12);
2988 vs->mouse_mode_notifier.notify = check_pointer_type_change;
2989 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
2992 static gboolean vnc_listen_io(QIOChannel *ioc,
2993 GIOCondition condition,
2994 void *opaque)
2996 VncDisplay *vd = opaque;
2997 QIOChannelSocket *sioc = NULL;
2998 Error *err = NULL;
2999 bool isWebsock = false;
3000 size_t i;
3002 for (i = 0; i < vd->nlwebsock; i++) {
3003 if (ioc == QIO_CHANNEL(vd->lwebsock[i])) {
3004 isWebsock = true;
3005 break;
3009 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3010 if (sioc != NULL) {
3011 qio_channel_set_name(QIO_CHANNEL(sioc),
3012 isWebsock ? "vnc-ws-server" : "vnc-server");
3013 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3014 vnc_connect(vd, sioc, false, isWebsock);
3015 object_unref(OBJECT(sioc));
3016 } else {
3017 /* client probably closed connection before we got there */
3018 error_free(err);
3021 return TRUE;
3024 static const DisplayChangeListenerOps dcl_ops = {
3025 .dpy_name = "vnc",
3026 .dpy_refresh = vnc_refresh,
3027 .dpy_gfx_update = vnc_dpy_update,
3028 .dpy_gfx_switch = vnc_dpy_switch,
3029 .dpy_gfx_check_format = qemu_pixman_check_format,
3030 .dpy_mouse_set = vnc_mouse_set,
3031 .dpy_cursor_define = vnc_dpy_cursor_define,
3034 void vnc_display_init(const char *id)
3036 VncDisplay *vd;
3038 if (vnc_display_find(id) != NULL) {
3039 return;
3041 vd = g_malloc0(sizeof(*vd));
3043 vd->id = strdup(id);
3044 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3046 QTAILQ_INIT(&vd->clients);
3047 vd->expires = TIME_MAX;
3049 if (keyboard_layout) {
3050 trace_vnc_key_map_init(keyboard_layout);
3051 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3052 } else {
3053 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3056 if (!vd->kbd_layout) {
3057 exit(1);
3060 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3061 vd->connections_limit = 32;
3063 qemu_mutex_init(&vd->mutex);
3064 vnc_start_worker_thread();
3066 vd->dcl.ops = &dcl_ops;
3067 register_displaychangelistener(&vd->dcl);
3071 static void vnc_display_close(VncDisplay *vd)
3073 size_t i;
3074 if (!vd) {
3075 return;
3077 vd->is_unix = false;
3078 for (i = 0; i < vd->nlsock; i++) {
3079 if (vd->lsock_tag[i]) {
3080 g_source_remove(vd->lsock_tag[i]);
3082 object_unref(OBJECT(vd->lsock[i]));
3084 g_free(vd->lsock);
3085 g_free(vd->lsock_tag);
3086 vd->lsock = NULL;
3087 vd->lsock_tag = NULL;
3088 vd->nlsock = 0;
3090 for (i = 0; i < vd->nlwebsock; i++) {
3091 if (vd->lwebsock_tag[i]) {
3092 g_source_remove(vd->lwebsock_tag[i]);
3094 object_unref(OBJECT(vd->lwebsock[i]));
3096 g_free(vd->lwebsock);
3097 g_free(vd->lwebsock_tag);
3098 vd->lwebsock = NULL;
3099 vd->lwebsock_tag = NULL;
3100 vd->nlwebsock = 0;
3102 vd->auth = VNC_AUTH_INVALID;
3103 vd->subauth = VNC_AUTH_INVALID;
3104 if (vd->tlscreds) {
3105 object_unparent(OBJECT(vd->tlscreds));
3106 vd->tlscreds = NULL;
3108 g_free(vd->tlsaclname);
3109 vd->tlsaclname = NULL;
3110 if (vd->lock_key_sync) {
3111 qemu_remove_led_event_handler(vd->led);
3112 vd->led = NULL;
3116 int vnc_display_password(const char *id, const char *password)
3118 VncDisplay *vd = vnc_display_find(id);
3120 if (!vd) {
3121 return -EINVAL;
3123 if (vd->auth == VNC_AUTH_NONE) {
3124 error_printf_unless_qmp("If you want use passwords please enable "
3125 "password auth using '-vnc ${dpy},password'.\n");
3126 return -EINVAL;
3129 g_free(vd->password);
3130 vd->password = g_strdup(password);
3132 return 0;
3135 int vnc_display_pw_expire(const char *id, time_t expires)
3137 VncDisplay *vd = vnc_display_find(id);
3139 if (!vd) {
3140 return -EINVAL;
3143 vd->expires = expires;
3144 return 0;
3147 static void vnc_display_print_local_addr(VncDisplay *vd)
3149 SocketAddress *addr;
3150 Error *err = NULL;
3152 if (!vd->nlsock) {
3153 return;
3156 addr = qio_channel_socket_get_local_address(vd->lsock[0], &err);
3157 if (!addr) {
3158 return;
3161 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3162 qapi_free_SocketAddress(addr);
3163 return;
3165 error_printf_unless_qmp("VNC server running on %s:%s\n",
3166 addr->u.inet.host,
3167 addr->u.inet.port);
3168 qapi_free_SocketAddress(addr);
3171 static QemuOptsList qemu_vnc_opts = {
3172 .name = "vnc",
3173 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3174 .implied_opt_name = "vnc",
3175 .desc = {
3177 .name = "vnc",
3178 .type = QEMU_OPT_STRING,
3180 .name = "websocket",
3181 .type = QEMU_OPT_STRING,
3183 .name = "tls-creds",
3184 .type = QEMU_OPT_STRING,
3186 /* Deprecated in favour of tls-creds */
3187 .name = "x509",
3188 .type = QEMU_OPT_STRING,
3190 .name = "share",
3191 .type = QEMU_OPT_STRING,
3193 .name = "display",
3194 .type = QEMU_OPT_STRING,
3196 .name = "head",
3197 .type = QEMU_OPT_NUMBER,
3199 .name = "connections",
3200 .type = QEMU_OPT_NUMBER,
3202 .name = "to",
3203 .type = QEMU_OPT_NUMBER,
3205 .name = "ipv4",
3206 .type = QEMU_OPT_BOOL,
3208 .name = "ipv6",
3209 .type = QEMU_OPT_BOOL,
3211 .name = "password",
3212 .type = QEMU_OPT_BOOL,
3214 .name = "reverse",
3215 .type = QEMU_OPT_BOOL,
3217 .name = "lock-key-sync",
3218 .type = QEMU_OPT_BOOL,
3220 .name = "key-delay-ms",
3221 .type = QEMU_OPT_NUMBER,
3223 .name = "sasl",
3224 .type = QEMU_OPT_BOOL,
3226 /* Deprecated in favour of tls-creds */
3227 .name = "tls",
3228 .type = QEMU_OPT_BOOL,
3230 /* Deprecated in favour of tls-creds */
3231 .name = "x509verify",
3232 .type = QEMU_OPT_STRING,
3234 .name = "acl",
3235 .type = QEMU_OPT_BOOL,
3237 .name = "lossy",
3238 .type = QEMU_OPT_BOOL,
3240 .name = "non-adaptive",
3241 .type = QEMU_OPT_BOOL,
3243 { /* end of list */ }
3248 static int
3249 vnc_display_setup_auth(int *auth,
3250 int *subauth,
3251 QCryptoTLSCreds *tlscreds,
3252 bool password,
3253 bool sasl,
3254 bool websocket,
3255 Error **errp)
3258 * We have a choice of 3 authentication options
3260 * 1. none
3261 * 2. vnc
3262 * 3. sasl
3264 * The channel can be run in 2 modes
3266 * 1. clear
3267 * 2. tls
3269 * And TLS can use 2 types of credentials
3271 * 1. anon
3272 * 2. x509
3274 * We thus have 9 possible logical combinations
3276 * 1. clear + none
3277 * 2. clear + vnc
3278 * 3. clear + sasl
3279 * 4. tls + anon + none
3280 * 5. tls + anon + vnc
3281 * 6. tls + anon + sasl
3282 * 7. tls + x509 + none
3283 * 8. tls + x509 + vnc
3284 * 9. tls + x509 + sasl
3286 * These need to be mapped into the VNC auth schemes
3287 * in an appropriate manner. In regular VNC, all the
3288 * TLS options get mapped into VNC_AUTH_VENCRYPT
3289 * sub-auth types.
3291 * In websockets, the https:// protocol already provides
3292 * TLS support, so there is no need to make use of the
3293 * VeNCrypt extension. Furthermore, websockets browser
3294 * clients could not use VeNCrypt even if they wanted to,
3295 * as they cannot control when the TLS handshake takes
3296 * place. Thus there is no option but to rely on https://,
3297 * meaning combinations 4->6 and 7->9 will be mapped to
3298 * VNC auth schemes in the same way as combos 1->3.
3300 * Regardless of fact that we have a different mapping to
3301 * VNC auth mechs for plain VNC vs websockets VNC, the end
3302 * result has the same security characteristics.
3304 if (websocket || !tlscreds) {
3305 if (password) {
3306 VNC_DEBUG("Initializing VNC server with password auth\n");
3307 *auth = VNC_AUTH_VNC;
3308 } else if (sasl) {
3309 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3310 *auth = VNC_AUTH_SASL;
3311 } else {
3312 VNC_DEBUG("Initializing VNC server with no auth\n");
3313 *auth = VNC_AUTH_NONE;
3315 *subauth = VNC_AUTH_INVALID;
3316 } else {
3317 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3318 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3319 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3320 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3322 if (!is_x509 && !is_anon) {
3323 error_setg(errp,
3324 "Unsupported TLS cred type %s",
3325 object_get_typename(OBJECT(tlscreds)));
3326 return -1;
3328 *auth = VNC_AUTH_VENCRYPT;
3329 if (password) {
3330 if (is_x509) {
3331 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3332 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3333 } else {
3334 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3335 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3338 } else if (sasl) {
3339 if (is_x509) {
3340 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3341 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3342 } else {
3343 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3344 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3346 } else {
3347 if (is_x509) {
3348 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3349 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3350 } else {
3351 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3352 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3356 return 0;
3361 * Handle back compat with old CLI syntax by creating some
3362 * suitable QCryptoTLSCreds objects
3364 static QCryptoTLSCreds *
3365 vnc_display_create_creds(bool x509,
3366 bool x509verify,
3367 const char *dir,
3368 const char *id,
3369 Error **errp)
3371 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3372 Object *parent = object_get_objects_root();
3373 Object *creds;
3374 Error *err = NULL;
3376 if (x509) {
3377 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3378 parent,
3379 credsid,
3380 &err,
3381 "endpoint", "server",
3382 "dir", dir,
3383 "verify-peer", x509verify ? "yes" : "no",
3384 NULL);
3385 } else {
3386 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3387 parent,
3388 credsid,
3389 &err,
3390 "endpoint", "server",
3391 NULL);
3394 g_free(credsid);
3396 if (err) {
3397 error_propagate(errp, err);
3398 return NULL;
3401 return QCRYPTO_TLS_CREDS(creds);
3405 static int vnc_display_get_address(const char *addrstr,
3406 bool websocket,
3407 bool reverse,
3408 int displaynum,
3409 int to,
3410 bool has_ipv4,
3411 bool has_ipv6,
3412 bool ipv4,
3413 bool ipv6,
3414 SocketAddress **retaddr,
3415 Error **errp)
3417 int ret = -1;
3418 SocketAddress *addr = NULL;
3420 addr = g_new0(SocketAddress, 1);
3422 if (strncmp(addrstr, "unix:", 5) == 0) {
3423 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3424 addr->u.q_unix.path = g_strdup(addrstr + 5);
3426 if (websocket) {
3427 error_setg(errp, "UNIX sockets not supported with websock");
3428 goto cleanup;
3431 if (to) {
3432 error_setg(errp, "Port range not support with UNIX socket");
3433 goto cleanup;
3435 ret = 0;
3436 } else {
3437 const char *port;
3438 size_t hostlen;
3439 unsigned long long baseport = 0;
3440 InetSocketAddress *inet;
3442 port = strrchr(addrstr, ':');
3443 if (!port) {
3444 if (websocket) {
3445 hostlen = 0;
3446 port = addrstr;
3447 } else {
3448 error_setg(errp, "no vnc port specified");
3449 goto cleanup;
3451 } else {
3452 hostlen = port - addrstr;
3453 port++;
3454 if (*port == '\0') {
3455 error_setg(errp, "vnc port cannot be empty");
3456 goto cleanup;
3460 addr->type = SOCKET_ADDRESS_TYPE_INET;
3461 inet = &addr->u.inet;
3462 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3463 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3464 } else {
3465 inet->host = g_strndup(addrstr, hostlen);
3467 /* plain VNC port is just an offset, for websocket
3468 * port is absolute */
3469 if (websocket) {
3470 if (g_str_equal(addrstr, "") ||
3471 g_str_equal(addrstr, "on")) {
3472 if (displaynum == -1) {
3473 error_setg(errp, "explicit websocket port is required");
3474 goto cleanup;
3476 inet->port = g_strdup_printf(
3477 "%d", displaynum + 5700);
3478 if (to) {
3479 inet->has_to = true;
3480 inet->to = to + 5700;
3482 } else {
3483 inet->port = g_strdup(port);
3485 } else {
3486 int offset = reverse ? 0 : 5900;
3487 if (parse_uint_full(port, &baseport, 10) < 0) {
3488 error_setg(errp, "can't convert to a number: %s", port);
3489 goto cleanup;
3491 if (baseport > 65535 ||
3492 baseport + offset > 65535) {
3493 error_setg(errp, "port %s out of range", port);
3494 goto cleanup;
3496 inet->port = g_strdup_printf(
3497 "%d", (int)baseport + offset);
3499 if (to) {
3500 inet->has_to = true;
3501 inet->to = to + offset;
3505 inet->ipv4 = ipv4;
3506 inet->has_ipv4 = has_ipv4;
3507 inet->ipv6 = ipv6;
3508 inet->has_ipv6 = has_ipv6;
3510 ret = baseport;
3513 *retaddr = addr;
3515 cleanup:
3516 if (ret < 0) {
3517 qapi_free_SocketAddress(addr);
3519 return ret;
3522 static void vnc_free_addresses(SocketAddress ***retsaddr,
3523 size_t *retnsaddr)
3525 size_t i;
3527 for (i = 0; i < *retnsaddr; i++) {
3528 qapi_free_SocketAddress((*retsaddr)[i]);
3530 g_free(*retsaddr);
3532 *retsaddr = NULL;
3533 *retnsaddr = 0;
3536 static int vnc_display_get_addresses(QemuOpts *opts,
3537 bool reverse,
3538 SocketAddress ***retsaddr,
3539 size_t *retnsaddr,
3540 SocketAddress ***retwsaddr,
3541 size_t *retnwsaddr,
3542 Error **errp)
3544 SocketAddress *saddr = NULL;
3545 SocketAddress *wsaddr = NULL;
3546 QemuOptsIter addriter;
3547 const char *addr;
3548 int to = qemu_opt_get_number(opts, "to", 0);
3549 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3550 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3551 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3552 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3553 int displaynum = -1;
3554 int ret = -1;
3556 *retsaddr = NULL;
3557 *retnsaddr = 0;
3558 *retwsaddr = NULL;
3559 *retnwsaddr = 0;
3561 addr = qemu_opt_get(opts, "vnc");
3562 if (addr == NULL || g_str_equal(addr, "none")) {
3563 ret = 0;
3564 goto cleanup;
3566 if (qemu_opt_get(opts, "websocket") &&
3567 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3568 error_setg(errp,
3569 "SHA1 hash support is required for websockets");
3570 goto cleanup;
3573 qemu_opt_iter_init(&addriter, opts, "vnc");
3574 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3575 int rv;
3576 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3577 has_ipv4, has_ipv6,
3578 ipv4, ipv6,
3579 &saddr, errp);
3580 if (rv < 0) {
3581 goto cleanup;
3583 /* Historical compat - first listen address can be used
3584 * to set the default websocket port
3586 if (displaynum == -1) {
3587 displaynum = rv;
3589 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3590 (*retsaddr)[(*retnsaddr)++] = saddr;
3593 /* If we had multiple primary displays, we don't do defaults
3594 * for websocket, and require explicit config instead. */
3595 if (*retnsaddr > 1) {
3596 displaynum = -1;
3599 qemu_opt_iter_init(&addriter, opts, "websocket");
3600 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3601 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3602 has_ipv4, has_ipv6,
3603 ipv4, ipv6,
3604 &wsaddr, errp) < 0) {
3605 goto cleanup;
3608 /* Historical compat - if only a single listen address was
3609 * provided, then this is used to set the default listen
3610 * address for websocket too
3612 if (*retnsaddr == 1 &&
3613 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3614 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3615 g_str_equal(wsaddr->u.inet.host, "") &&
3616 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3617 g_free(wsaddr->u.inet.host);
3618 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3621 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3622 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3625 ret = 0;
3626 cleanup:
3627 if (ret < 0) {
3628 vnc_free_addresses(retsaddr, retnsaddr);
3629 vnc_free_addresses(retwsaddr, retnwsaddr);
3631 return ret;
3634 static int vnc_display_connect(VncDisplay *vd,
3635 SocketAddress **saddr,
3636 size_t nsaddr,
3637 SocketAddress **wsaddr,
3638 size_t nwsaddr,
3639 Error **errp)
3641 /* connect to viewer */
3642 QIOChannelSocket *sioc = NULL;
3643 if (nwsaddr != 0) {
3644 error_setg(errp, "Cannot use websockets in reverse mode");
3645 return -1;
3647 if (nsaddr != 1) {
3648 error_setg(errp, "Expected a single address in reverse mode");
3649 return -1;
3651 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3652 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3653 sioc = qio_channel_socket_new();
3654 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3655 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3656 return -1;
3658 vnc_connect(vd, sioc, false, false);
3659 object_unref(OBJECT(sioc));
3660 return 0;
3664 static int vnc_display_listen_addr(VncDisplay *vd,
3665 SocketAddress *addr,
3666 const char *name,
3667 QIOChannelSocket ***lsock,
3668 guint **lsock_tag,
3669 size_t *nlsock,
3670 Error **errp)
3672 QIODNSResolver *resolver = qio_dns_resolver_get_instance();
3673 SocketAddress **rawaddrs = NULL;
3674 size_t nrawaddrs = 0;
3675 Error *listenerr = NULL;
3676 bool listening = false;
3677 size_t i;
3679 if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,
3680 &rawaddrs, errp) < 0) {
3681 return -1;
3684 for (i = 0; i < nrawaddrs; i++) {
3685 QIOChannelSocket *sioc = qio_channel_socket_new();
3687 qio_channel_set_name(QIO_CHANNEL(sioc), name);
3688 if (qio_channel_socket_listen_sync(
3689 sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
3690 object_unref(OBJECT(sioc));
3691 continue;
3693 listening = true;
3694 (*nlsock)++;
3695 *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);
3696 *lsock_tag = g_renew(guint, *lsock_tag, *nlsock);
3698 (*lsock)[*nlsock - 1] = sioc;
3699 (*lsock_tag)[*nlsock - 1] = 0;
3702 for (i = 0; i < nrawaddrs; i++) {
3703 qapi_free_SocketAddress(rawaddrs[i]);
3705 g_free(rawaddrs);
3707 if (listenerr) {
3708 if (!listening) {
3709 error_propagate(errp, listenerr);
3710 return -1;
3711 } else {
3712 error_free(listenerr);
3716 for (i = 0; i < *nlsock; i++) {
3717 (*lsock_tag)[i] = qio_channel_add_watch(
3718 QIO_CHANNEL((*lsock)[i]),
3719 G_IO_IN, vnc_listen_io, vd, NULL);
3722 return 0;
3726 static int vnc_display_listen(VncDisplay *vd,
3727 SocketAddress **saddr,
3728 size_t nsaddr,
3729 SocketAddress **wsaddr,
3730 size_t nwsaddr,
3731 Error **errp)
3733 size_t i;
3735 for (i = 0; i < nsaddr; i++) {
3736 if (vnc_display_listen_addr(vd, saddr[i],
3737 "vnc-listen",
3738 &vd->lsock,
3739 &vd->lsock_tag,
3740 &vd->nlsock,
3741 errp) < 0) {
3742 return -1;
3745 for (i = 0; i < nwsaddr; i++) {
3746 if (vnc_display_listen_addr(vd, wsaddr[i],
3747 "vnc-ws-listen",
3748 &vd->lwebsock,
3749 &vd->lwebsock_tag,
3750 &vd->nlwebsock,
3751 errp) < 0) {
3752 return -1;
3756 return 0;
3760 void vnc_display_open(const char *id, Error **errp)
3762 VncDisplay *vd = vnc_display_find(id);
3763 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3764 SocketAddress **saddr = NULL, **wsaddr = NULL;
3765 size_t nsaddr, nwsaddr;
3766 const char *share, *device_id;
3767 QemuConsole *con;
3768 bool password = false;
3769 bool reverse = false;
3770 const char *credid;
3771 bool sasl = false;
3772 #ifdef CONFIG_VNC_SASL
3773 int saslErr;
3774 #endif
3775 int acl = 0;
3776 int lock_key_sync = 1;
3777 int key_delay_ms;
3779 if (!vd) {
3780 error_setg(errp, "VNC display not active");
3781 return;
3783 vnc_display_close(vd);
3785 if (!opts) {
3786 return;
3789 reverse = qemu_opt_get_bool(opts, "reverse", false);
3790 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3791 &wsaddr, &nwsaddr, errp) < 0) {
3792 goto fail;
3795 password = qemu_opt_get_bool(opts, "password", false);
3796 if (password) {
3797 if (fips_get_state()) {
3798 error_setg(errp,
3799 "VNC password auth disabled due to FIPS mode, "
3800 "consider using the VeNCrypt or SASL authentication "
3801 "methods as an alternative");
3802 goto fail;
3804 if (!qcrypto_cipher_supports(
3805 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3806 error_setg(errp,
3807 "Cipher backend does not support DES RFB algorithm");
3808 goto fail;
3812 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3813 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
3814 sasl = qemu_opt_get_bool(opts, "sasl", false);
3815 #ifndef CONFIG_VNC_SASL
3816 if (sasl) {
3817 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3818 goto fail;
3820 #endif /* CONFIG_VNC_SASL */
3821 credid = qemu_opt_get(opts, "tls-creds");
3822 if (credid) {
3823 Object *creds;
3824 if (qemu_opt_get(opts, "tls") ||
3825 qemu_opt_get(opts, "x509") ||
3826 qemu_opt_get(opts, "x509verify")) {
3827 error_setg(errp,
3828 "'tls-creds' parameter is mutually exclusive with "
3829 "'tls', 'x509' and 'x509verify' parameters");
3830 goto fail;
3833 creds = object_resolve_path_component(
3834 object_get_objects_root(), credid);
3835 if (!creds) {
3836 error_setg(errp, "No TLS credentials with id '%s'",
3837 credid);
3838 goto fail;
3840 vd->tlscreds = (QCryptoTLSCreds *)
3841 object_dynamic_cast(creds,
3842 TYPE_QCRYPTO_TLS_CREDS);
3843 if (!vd->tlscreds) {
3844 error_setg(errp, "Object with id '%s' is not TLS credentials",
3845 credid);
3846 goto fail;
3848 object_ref(OBJECT(vd->tlscreds));
3850 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3851 error_setg(errp,
3852 "Expecting TLS credentials with a server endpoint");
3853 goto fail;
3855 } else {
3856 const char *path;
3857 bool tls = false, x509 = false, x509verify = false;
3858 tls = qemu_opt_get_bool(opts, "tls", false);
3859 if (tls) {
3860 path = qemu_opt_get(opts, "x509");
3862 if (path) {
3863 x509 = true;
3864 } else {
3865 path = qemu_opt_get(opts, "x509verify");
3866 if (path) {
3867 x509 = true;
3868 x509verify = true;
3871 vd->tlscreds = vnc_display_create_creds(x509,
3872 x509verify,
3873 path,
3874 vd->id,
3875 errp);
3876 if (!vd->tlscreds) {
3877 goto fail;
3881 acl = qemu_opt_get_bool(opts, "acl", false);
3883 share = qemu_opt_get(opts, "share");
3884 if (share) {
3885 if (strcmp(share, "ignore") == 0) {
3886 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
3887 } else if (strcmp(share, "allow-exclusive") == 0) {
3888 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3889 } else if (strcmp(share, "force-shared") == 0) {
3890 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3891 } else {
3892 error_setg(errp, "unknown vnc share= option");
3893 goto fail;
3895 } else {
3896 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3898 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3900 #ifdef CONFIG_VNC_JPEG
3901 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
3902 #endif
3903 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3904 /* adaptive updates are only used with tight encoding and
3905 * if lossy updates are enabled so we can disable all the
3906 * calculations otherwise */
3907 if (!vd->lossy) {
3908 vd->non_adaptive = true;
3911 if (acl) {
3912 if (strcmp(vd->id, "default") == 0) {
3913 vd->tlsaclname = g_strdup("vnc.x509dname");
3914 } else {
3915 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
3917 qemu_acl_init(vd->tlsaclname);
3919 #ifdef CONFIG_VNC_SASL
3920 if (acl && sasl) {
3921 char *aclname;
3923 if (strcmp(vd->id, "default") == 0) {
3924 aclname = g_strdup("vnc.username");
3925 } else {
3926 aclname = g_strdup_printf("vnc.%s.username", vd->id);
3928 vd->sasl.acl = qemu_acl_init(aclname);
3929 g_free(aclname);
3931 #endif
3933 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
3934 vd->tlscreds, password,
3935 sasl, false, errp) < 0) {
3936 goto fail;
3938 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
3940 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
3941 vd->tlscreds, password,
3942 sasl, true, errp) < 0) {
3943 goto fail;
3945 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
3947 #ifdef CONFIG_VNC_SASL
3948 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3949 error_setg(errp, "Failed to initialize SASL auth: %s",
3950 sasl_errstring(saslErr, NULL, NULL));
3951 goto fail;
3953 #endif
3954 vd->lock_key_sync = lock_key_sync;
3955 if (lock_key_sync) {
3956 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
3958 vd->ledstate = 0;
3959 vd->key_delay_ms = key_delay_ms;
3961 device_id = qemu_opt_get(opts, "display");
3962 if (device_id) {
3963 int head = qemu_opt_get_number(opts, "head", 0);
3964 Error *err = NULL;
3966 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3967 if (err) {
3968 error_propagate(errp, err);
3969 goto fail;
3971 } else {
3972 con = NULL;
3975 if (con != vd->dcl.con) {
3976 unregister_displaychangelistener(&vd->dcl);
3977 vd->dcl.con = con;
3978 register_displaychangelistener(&vd->dcl);
3981 if (saddr == NULL) {
3982 goto cleanup;
3985 if (reverse) {
3986 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3987 goto fail;
3989 } else {
3990 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3991 goto fail;
3995 if (qemu_opt_get(opts, "to")) {
3996 vnc_display_print_local_addr(vd);
3999 cleanup:
4000 vnc_free_addresses(&saddr, &nsaddr);
4001 vnc_free_addresses(&wsaddr, &nwsaddr);
4002 return;
4004 fail:
4005 vnc_display_close(vd);
4006 goto cleanup;
4009 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4011 VncDisplay *vd = vnc_display_find(id);
4012 QIOChannelSocket *sioc;
4014 if (!vd) {
4015 return;
4018 sioc = qio_channel_socket_new_fd(csock, NULL);
4019 if (sioc) {
4020 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4021 vnc_connect(vd, sioc, skipauth, false);
4022 object_unref(OBJECT(sioc));
4026 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4028 int i = 2;
4029 char *id;
4031 id = g_strdup("default");
4032 while (qemu_opts_find(olist, id)) {
4033 g_free(id);
4034 id = g_strdup_printf("vnc%d", i++);
4036 qemu_opts_set_id(opts, id);
4039 QemuOpts *vnc_parse(const char *str, Error **errp)
4041 QemuOptsList *olist = qemu_find_opts("vnc");
4042 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
4043 const char *id;
4045 if (!opts) {
4046 return NULL;
4049 id = qemu_opts_id(opts);
4050 if (!id) {
4051 /* auto-assign id if not present */
4052 vnc_auto_assign_id(olist, opts);
4054 return opts;
4057 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4059 Error *local_err = NULL;
4060 char *id = (char *)qemu_opts_id(opts);
4062 assert(id);
4063 vnc_display_init(id);
4064 vnc_display_open(id, &local_err);
4065 if (local_err != NULL) {
4066 error_reportf_err(local_err, "Failed to start VNC server: ");
4067 exit(1);
4069 return 0;
4072 static void vnc_register_config(void)
4074 qemu_add_opts(&qemu_vnc_opts);
4076 opts_init(vnc_register_config);