ui: convert VNC server to use QIOChannelSocket
[qemu/kevin.git] / ui / vnc.c
blob30053cfdbb0b89491c9574f6193a139d39ea45ba
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 "vnc.h"
28 #include "vnc-jobs.h"
29 #include "trace.h"
30 #include "hw/qdev.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 "qemu/osdep.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
48 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
49 #define VNC_REFRESH_INTERVAL_INC 50
50 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
51 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
52 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
54 #include "vnc_keysym.h"
55 #include "crypto/cipher.h"
57 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
58 QTAILQ_HEAD_INITIALIZER(vnc_displays);
60 static int vnc_cursor_define(VncState *vs);
61 static void vnc_release_modifiers(VncState *vs);
63 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
65 #ifdef _VNC_DEBUG
66 static const char *mn[] = {
67 [0] = "undefined",
68 [VNC_SHARE_MODE_CONNECTING] = "connecting",
69 [VNC_SHARE_MODE_SHARED] = "shared",
70 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
71 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
73 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
74 vs->ioc, mn[vs->share_mode], mn[mode]);
75 #endif
77 switch (vs->share_mode) {
78 case VNC_SHARE_MODE_CONNECTING:
79 vs->vd->num_connecting--;
80 break;
81 case VNC_SHARE_MODE_SHARED:
82 vs->vd->num_shared--;
83 break;
84 case VNC_SHARE_MODE_EXCLUSIVE:
85 vs->vd->num_exclusive--;
86 break;
87 default:
88 break;
91 vs->share_mode = mode;
93 switch (vs->share_mode) {
94 case VNC_SHARE_MODE_CONNECTING:
95 vs->vd->num_connecting++;
96 break;
97 case VNC_SHARE_MODE_SHARED:
98 vs->vd->num_shared++;
99 break;
100 case VNC_SHARE_MODE_EXCLUSIVE:
101 vs->vd->num_exclusive++;
102 break;
103 default:
104 break;
109 static void vnc_init_basic_info(SocketAddress *addr,
110 VncBasicInfo *info,
111 Error **errp)
113 switch (addr->type) {
114 case SOCKET_ADDRESS_KIND_INET:
115 info->host = g_strdup(addr->u.inet->host);
116 info->service = g_strdup(addr->u.inet->port);
117 if (addr->u.inet->ipv6) {
118 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
119 } else {
120 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
122 break;
124 case SOCKET_ADDRESS_KIND_UNIX:
125 info->host = g_strdup("");
126 info->service = g_strdup(addr->u.q_unix->path);
127 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
128 break;
130 default:
131 error_setg(errp, "Unsupported socket kind %d",
132 addr->type);
133 break;
136 return;
139 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
140 VncBasicInfo *info,
141 Error **errp)
143 SocketAddress *addr = NULL;
145 addr = qio_channel_socket_get_local_address(ioc, errp);
146 if (!addr) {
147 return;
150 vnc_init_basic_info(addr, info, errp);
151 qapi_free_SocketAddress(addr);
154 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
155 VncBasicInfo *info,
156 Error **errp)
158 SocketAddress *addr = NULL;
160 addr = qio_channel_socket_get_remote_address(ioc, errp);
161 if (!addr) {
162 return;
165 vnc_init_basic_info(addr, info, errp);
166 qapi_free_SocketAddress(addr);
169 static const char *vnc_auth_name(VncDisplay *vd) {
170 switch (vd->auth) {
171 case VNC_AUTH_INVALID:
172 return "invalid";
173 case VNC_AUTH_NONE:
174 return "none";
175 case VNC_AUTH_VNC:
176 return "vnc";
177 case VNC_AUTH_RA2:
178 return "ra2";
179 case VNC_AUTH_RA2NE:
180 return "ra2ne";
181 case VNC_AUTH_TIGHT:
182 return "tight";
183 case VNC_AUTH_ULTRA:
184 return "ultra";
185 case VNC_AUTH_TLS:
186 return "tls";
187 case VNC_AUTH_VENCRYPT:
188 switch (vd->subauth) {
189 case VNC_AUTH_VENCRYPT_PLAIN:
190 return "vencrypt+plain";
191 case VNC_AUTH_VENCRYPT_TLSNONE:
192 return "vencrypt+tls+none";
193 case VNC_AUTH_VENCRYPT_TLSVNC:
194 return "vencrypt+tls+vnc";
195 case VNC_AUTH_VENCRYPT_TLSPLAIN:
196 return "vencrypt+tls+plain";
197 case VNC_AUTH_VENCRYPT_X509NONE:
198 return "vencrypt+x509+none";
199 case VNC_AUTH_VENCRYPT_X509VNC:
200 return "vencrypt+x509+vnc";
201 case VNC_AUTH_VENCRYPT_X509PLAIN:
202 return "vencrypt+x509+plain";
203 case VNC_AUTH_VENCRYPT_TLSSASL:
204 return "vencrypt+tls+sasl";
205 case VNC_AUTH_VENCRYPT_X509SASL:
206 return "vencrypt+x509+sasl";
207 default:
208 return "vencrypt";
210 case VNC_AUTH_SASL:
211 return "sasl";
213 return "unknown";
216 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
218 VncServerInfo *info;
219 Error *err = NULL;
221 info = g_malloc(sizeof(*info));
222 vnc_init_basic_info_from_server_addr(vd->lsock,
223 qapi_VncServerInfo_base(info), &err);
224 info->has_auth = true;
225 info->auth = g_strdup(vnc_auth_name(vd));
226 if (err) {
227 qapi_free_VncServerInfo(info);
228 info = NULL;
229 error_free(err);
231 return info;
234 static void vnc_client_cache_auth(VncState *client)
236 if (!client->info) {
237 return;
240 if (client->tls) {
241 client->info->x509_dname =
242 qcrypto_tls_session_get_peer_name(client->tls);
243 client->info->has_x509_dname =
244 client->info->x509_dname != NULL;
246 #ifdef CONFIG_VNC_SASL
247 if (client->sasl.conn &&
248 client->sasl.username) {
249 client->info->has_sasl_username = true;
250 client->info->sasl_username = g_strdup(client->sasl.username);
252 #endif
255 static void vnc_client_cache_addr(VncState *client)
257 Error *err = NULL;
259 client->info = g_malloc0(sizeof(*client->info));
260 vnc_init_basic_info_from_remote_addr(client->sioc,
261 qapi_VncClientInfo_base(client->info),
262 &err);
263 if (err) {
264 qapi_free_VncClientInfo(client->info);
265 client->info = NULL;
266 error_free(err);
270 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
272 VncServerInfo *si;
274 if (!vs->info) {
275 return;
278 si = vnc_server_info_get(vs->vd);
279 if (!si) {
280 return;
283 switch (event) {
284 case QAPI_EVENT_VNC_CONNECTED:
285 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
286 &error_abort);
287 break;
288 case QAPI_EVENT_VNC_INITIALIZED:
289 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
290 break;
291 case QAPI_EVENT_VNC_DISCONNECTED:
292 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
293 break;
294 default:
295 break;
298 qapi_free_VncServerInfo(si);
301 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
303 VncClientInfo *info;
304 Error *err = NULL;
306 info = g_malloc0(sizeof(*info));
308 vnc_init_basic_info_from_remote_addr(client->sioc,
309 qapi_VncClientInfo_base(info),
310 &err);
311 if (err) {
312 error_free(err);
313 qapi_free_VncClientInfo(info);
314 return NULL;
317 info->websocket = client->websocket;
319 if (client->tls) {
320 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
321 info->has_x509_dname = info->x509_dname != NULL;
323 #ifdef CONFIG_VNC_SASL
324 if (client->sasl.conn && client->sasl.username) {
325 info->has_sasl_username = true;
326 info->sasl_username = g_strdup(client->sasl.username);
328 #endif
330 return info;
333 static VncDisplay *vnc_display_find(const char *id)
335 VncDisplay *vd;
337 if (id == NULL) {
338 return QTAILQ_FIRST(&vnc_displays);
340 QTAILQ_FOREACH(vd, &vnc_displays, next) {
341 if (strcmp(id, vd->id) == 0) {
342 return vd;
345 return NULL;
348 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
350 VncClientInfoList *cinfo, *prev = NULL;
351 VncState *client;
353 QTAILQ_FOREACH(client, &vd->clients, next) {
354 cinfo = g_new0(VncClientInfoList, 1);
355 cinfo->value = qmp_query_vnc_client(client);
356 cinfo->next = prev;
357 prev = cinfo;
359 return prev;
362 VncInfo *qmp_query_vnc(Error **errp)
364 VncInfo *info = g_malloc0(sizeof(*info));
365 VncDisplay *vd = vnc_display_find(NULL);
366 SocketAddress *addr = NULL;
368 if (vd == NULL || !vd->enabled) {
369 info->enabled = false;
370 } else {
371 info->enabled = true;
373 /* for compatibility with the original command */
374 info->has_clients = true;
375 info->clients = qmp_query_client_list(vd);
377 if (vd->lsock == NULL) {
378 return info;
381 addr = qio_channel_socket_get_local_address(vd->lsock, errp);
382 if (!addr) {
383 goto out_error;
386 switch (addr->type) {
387 case SOCKET_ADDRESS_KIND_INET:
388 info->host = g_strdup(addr->u.inet->host);
389 info->service = g_strdup(addr->u.inet->port);
390 if (addr->u.inet->ipv6) {
391 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
392 } else {
393 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
395 break;
397 case SOCKET_ADDRESS_KIND_UNIX:
398 info->host = g_strdup("");
399 info->service = g_strdup(addr->u.q_unix->path);
400 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
401 break;
403 default:
404 error_setg(errp, "Unsupported socket kind %d",
405 addr->type);
406 goto out_error;
409 info->has_host = true;
410 info->has_service = true;
411 info->has_family = true;
413 info->has_auth = true;
414 info->auth = g_strdup(vnc_auth_name(vd));
417 qapi_free_SocketAddress(addr);
418 return info;
420 out_error:
421 qapi_free_SocketAddress(addr);
422 qapi_free_VncInfo(info);
423 return NULL;
426 static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,
427 bool websocket,
428 VncBasicInfoList *prev)
430 VncBasicInfoList *list;
431 VncBasicInfo *info;
432 Error *err = NULL;
433 SocketAddress *addr;
435 addr = qio_channel_socket_get_local_address(ioc, &err);
436 if (!addr) {
437 error_free(err);
438 return prev;
441 info = g_new0(VncBasicInfo, 1);
442 vnc_init_basic_info(addr, info, &err);
443 qapi_free_SocketAddress(addr);
444 if (err) {
445 qapi_free_VncBasicInfo(info);
446 error_free(err);
447 return prev;
449 info->websocket = websocket;
451 list = g_new0(VncBasicInfoList, 1);
452 list->value = info;
453 list->next = prev;
454 return list;
457 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
459 switch (vd->auth) {
460 case VNC_AUTH_VNC:
461 info->auth = VNC_PRIMARY_AUTH_VNC;
462 break;
463 case VNC_AUTH_RA2:
464 info->auth = VNC_PRIMARY_AUTH_RA2;
465 break;
466 case VNC_AUTH_RA2NE:
467 info->auth = VNC_PRIMARY_AUTH_RA2NE;
468 break;
469 case VNC_AUTH_TIGHT:
470 info->auth = VNC_PRIMARY_AUTH_TIGHT;
471 break;
472 case VNC_AUTH_ULTRA:
473 info->auth = VNC_PRIMARY_AUTH_ULTRA;
474 break;
475 case VNC_AUTH_TLS:
476 info->auth = VNC_PRIMARY_AUTH_TLS;
477 break;
478 case VNC_AUTH_VENCRYPT:
479 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
480 info->has_vencrypt = true;
481 switch (vd->subauth) {
482 case VNC_AUTH_VENCRYPT_PLAIN:
483 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
484 break;
485 case VNC_AUTH_VENCRYPT_TLSNONE:
486 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
487 break;
488 case VNC_AUTH_VENCRYPT_TLSVNC:
489 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
490 break;
491 case VNC_AUTH_VENCRYPT_TLSPLAIN:
492 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
493 break;
494 case VNC_AUTH_VENCRYPT_X509NONE:
495 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
496 break;
497 case VNC_AUTH_VENCRYPT_X509VNC:
498 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
499 break;
500 case VNC_AUTH_VENCRYPT_X509PLAIN:
501 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
502 break;
503 case VNC_AUTH_VENCRYPT_TLSSASL:
504 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
505 break;
506 case VNC_AUTH_VENCRYPT_X509SASL:
507 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
508 break;
509 default:
510 info->has_vencrypt = false;
511 break;
513 break;
514 case VNC_AUTH_SASL:
515 info->auth = VNC_PRIMARY_AUTH_SASL;
516 break;
517 case VNC_AUTH_NONE:
518 default:
519 info->auth = VNC_PRIMARY_AUTH_NONE;
520 break;
524 VncInfo2List *qmp_query_vnc_servers(Error **errp)
526 VncInfo2List *item, *prev = NULL;
527 VncInfo2 *info;
528 VncDisplay *vd;
529 DeviceState *dev;
531 QTAILQ_FOREACH(vd, &vnc_displays, next) {
532 info = g_new0(VncInfo2, 1);
533 info->id = g_strdup(vd->id);
534 info->clients = qmp_query_client_list(vd);
535 qmp_query_auth(vd, info);
536 if (vd->dcl.con) {
537 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
538 "device", NULL));
539 info->has_display = true;
540 info->display = g_strdup(dev->id);
542 if (vd->lsock != NULL) {
543 info->server = qmp_query_server_entry(
544 vd->lsock, false, info->server);
546 if (vd->lwebsock != NULL) {
547 info->server = qmp_query_server_entry(
548 vd->lwebsock, true, info->server);
551 item = g_new0(VncInfo2List, 1);
552 item->value = info;
553 item->next = prev;
554 prev = item;
556 return prev;
559 /* TODO
560 1) Get the queue working for IO.
561 2) there is some weirdness when using the -S option (the screen is grey
562 and not totally invalidated
563 3) resolutions > 1024
566 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
567 static void vnc_disconnect_start(VncState *vs);
569 static void vnc_colordepth(VncState *vs);
570 static void framebuffer_update_request(VncState *vs, int incremental,
571 int x_position, int y_position,
572 int w, int h);
573 static void vnc_refresh(DisplayChangeListener *dcl);
574 static int vnc_refresh_server_surface(VncDisplay *vd);
576 static int vnc_width(VncDisplay *vd)
578 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
579 VNC_DIRTY_PIXELS_PER_BIT));
582 static int vnc_height(VncDisplay *vd)
584 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
587 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
588 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
589 VncDisplay *vd,
590 int x, int y, int w, int h)
592 int width = vnc_width(vd);
593 int height = vnc_height(vd);
595 /* this is needed this to ensure we updated all affected
596 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
597 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
598 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
600 x = MIN(x, width);
601 y = MIN(y, height);
602 w = MIN(x + w, width) - x;
603 h = MIN(y + h, height);
605 for (; y < h; y++) {
606 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
607 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
611 static void vnc_dpy_update(DisplayChangeListener *dcl,
612 int x, int y, int w, int h)
614 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
615 struct VncSurface *s = &vd->guest;
617 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
620 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
621 int32_t encoding)
623 vnc_write_u16(vs, x);
624 vnc_write_u16(vs, y);
625 vnc_write_u16(vs, w);
626 vnc_write_u16(vs, h);
628 vnc_write_s32(vs, encoding);
632 static void vnc_desktop_resize(VncState *vs)
634 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
635 return;
637 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
638 vs->client_height == pixman_image_get_height(vs->vd->server)) {
639 return;
641 vs->client_width = pixman_image_get_width(vs->vd->server);
642 vs->client_height = pixman_image_get_height(vs->vd->server);
643 vnc_lock_output(vs);
644 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
645 vnc_write_u8(vs, 0);
646 vnc_write_u16(vs, 1); /* number of rects */
647 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
648 VNC_ENCODING_DESKTOPRESIZE);
649 vnc_unlock_output(vs);
650 vnc_flush(vs);
653 static void vnc_abort_display_jobs(VncDisplay *vd)
655 VncState *vs;
657 QTAILQ_FOREACH(vs, &vd->clients, next) {
658 vnc_lock_output(vs);
659 vs->abort = true;
660 vnc_unlock_output(vs);
662 QTAILQ_FOREACH(vs, &vd->clients, next) {
663 vnc_jobs_join(vs);
665 QTAILQ_FOREACH(vs, &vd->clients, next) {
666 vnc_lock_output(vs);
667 vs->abort = false;
668 vnc_unlock_output(vs);
672 int vnc_server_fb_stride(VncDisplay *vd)
674 return pixman_image_get_stride(vd->server);
677 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
679 uint8_t *ptr;
681 ptr = (uint8_t *)pixman_image_get_data(vd->server);
682 ptr += y * vnc_server_fb_stride(vd);
683 ptr += x * VNC_SERVER_FB_BYTES;
684 return ptr;
687 static void vnc_update_server_surface(VncDisplay *vd)
689 qemu_pixman_image_unref(vd->server);
690 vd->server = NULL;
692 if (QTAILQ_EMPTY(&vd->clients)) {
693 return;
696 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
697 vnc_width(vd),
698 vnc_height(vd),
699 NULL, 0);
702 static void vnc_dpy_switch(DisplayChangeListener *dcl,
703 DisplaySurface *surface)
705 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
706 VncState *vs;
707 int width, height;
709 vnc_abort_display_jobs(vd);
710 vd->ds = surface;
712 /* server surface */
713 vnc_update_server_surface(vd);
715 /* guest surface */
716 qemu_pixman_image_unref(vd->guest.fb);
717 vd->guest.fb = pixman_image_ref(surface->image);
718 vd->guest.format = surface->format;
719 width = vnc_width(vd);
720 height = vnc_height(vd);
721 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
722 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
723 width, height);
725 QTAILQ_FOREACH(vs, &vd->clients, next) {
726 vnc_colordepth(vs);
727 vnc_desktop_resize(vs);
728 if (vs->vd->cursor) {
729 vnc_cursor_define(vs);
731 memset(vs->dirty, 0x00, sizeof(vs->dirty));
732 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
733 width, height);
737 /* fastest code */
738 static void vnc_write_pixels_copy(VncState *vs,
739 void *pixels, int size)
741 vnc_write(vs, pixels, size);
744 /* slowest but generic code. */
745 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
747 uint8_t r, g, b;
749 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
750 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
751 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
752 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
753 #else
754 # error need some bits here if you change VNC_SERVER_FB_FORMAT
755 #endif
756 v = (r << vs->client_pf.rshift) |
757 (g << vs->client_pf.gshift) |
758 (b << vs->client_pf.bshift);
759 switch (vs->client_pf.bytes_per_pixel) {
760 case 1:
761 buf[0] = v;
762 break;
763 case 2:
764 if (vs->client_be) {
765 buf[0] = v >> 8;
766 buf[1] = v;
767 } else {
768 buf[1] = v >> 8;
769 buf[0] = v;
771 break;
772 default:
773 case 4:
774 if (vs->client_be) {
775 buf[0] = v >> 24;
776 buf[1] = v >> 16;
777 buf[2] = v >> 8;
778 buf[3] = v;
779 } else {
780 buf[3] = v >> 24;
781 buf[2] = v >> 16;
782 buf[1] = v >> 8;
783 buf[0] = v;
785 break;
789 static void vnc_write_pixels_generic(VncState *vs,
790 void *pixels1, int size)
792 uint8_t buf[4];
794 if (VNC_SERVER_FB_BYTES == 4) {
795 uint32_t *pixels = pixels1;
796 int n, i;
797 n = size >> 2;
798 for (i = 0; i < n; i++) {
799 vnc_convert_pixel(vs, buf, pixels[i]);
800 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
805 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
807 int i;
808 uint8_t *row;
809 VncDisplay *vd = vs->vd;
811 row = vnc_server_fb_ptr(vd, x, y);
812 for (i = 0; i < h; i++) {
813 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
814 row += vnc_server_fb_stride(vd);
816 return 1;
819 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
821 int n = 0;
822 bool encode_raw = false;
823 size_t saved_offs = vs->output.offset;
825 switch(vs->vnc_encoding) {
826 case VNC_ENCODING_ZLIB:
827 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
828 break;
829 case VNC_ENCODING_HEXTILE:
830 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
831 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
832 break;
833 case VNC_ENCODING_TIGHT:
834 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
835 break;
836 case VNC_ENCODING_TIGHT_PNG:
837 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
838 break;
839 case VNC_ENCODING_ZRLE:
840 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
841 break;
842 case VNC_ENCODING_ZYWRLE:
843 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
844 break;
845 default:
846 encode_raw = true;
847 break;
850 /* If the client has the same pixel format as our internal buffer and
851 * a RAW encoding would need less space fall back to RAW encoding to
852 * save bandwidth and processing power in the client. */
853 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
854 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
855 vs->output.offset = saved_offs;
856 encode_raw = true;
859 if (encode_raw) {
860 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
861 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
864 return n;
867 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
869 /* send bitblit op to the vnc client */
870 vnc_lock_output(vs);
871 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
872 vnc_write_u8(vs, 0);
873 vnc_write_u16(vs, 1); /* number of rects */
874 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
875 vnc_write_u16(vs, src_x);
876 vnc_write_u16(vs, src_y);
877 vnc_unlock_output(vs);
878 vnc_flush(vs);
881 static void vnc_dpy_copy(DisplayChangeListener *dcl,
882 int src_x, int src_y,
883 int dst_x, int dst_y, int w, int h)
885 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
886 VncState *vs, *vn;
887 uint8_t *src_row;
888 uint8_t *dst_row;
889 int i, x, y, pitch, inc, w_lim, s;
890 int cmp_bytes;
892 if (!vd->server) {
893 /* no client connected */
894 return;
897 vnc_refresh_server_surface(vd);
898 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
899 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
900 vs->force_update = 1;
901 vnc_update_client(vs, 1, true);
902 /* vs might be free()ed here */
906 /* do bitblit op on the local surface too */
907 pitch = vnc_server_fb_stride(vd);
908 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
909 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
910 y = dst_y;
911 inc = 1;
912 if (dst_y > src_y) {
913 /* copy backwards */
914 src_row += pitch * (h-1);
915 dst_row += pitch * (h-1);
916 pitch = -pitch;
917 y = dst_y + h - 1;
918 inc = -1;
920 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
921 if (w_lim < 0) {
922 w_lim = w;
923 } else {
924 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
926 for (i = 0; i < h; i++) {
927 for (x = 0; x <= w_lim;
928 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
929 if (x == w_lim) {
930 if ((s = w - w_lim) == 0)
931 break;
932 } else if (!x) {
933 s = (VNC_DIRTY_PIXELS_PER_BIT -
934 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
935 s = MIN(s, w_lim);
936 } else {
937 s = VNC_DIRTY_PIXELS_PER_BIT;
939 cmp_bytes = s * VNC_SERVER_FB_BYTES;
940 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
941 continue;
942 memmove(dst_row, src_row, cmp_bytes);
943 QTAILQ_FOREACH(vs, &vd->clients, next) {
944 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
945 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
946 vs->dirty[y]);
950 src_row += pitch - w * VNC_SERVER_FB_BYTES;
951 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
952 y += inc;
955 QTAILQ_FOREACH(vs, &vd->clients, next) {
956 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
957 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
962 static void vnc_mouse_set(DisplayChangeListener *dcl,
963 int x, int y, int visible)
965 /* can we ask the client(s) to move the pointer ??? */
968 static int vnc_cursor_define(VncState *vs)
970 QEMUCursor *c = vs->vd->cursor;
971 int isize;
973 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
974 vnc_lock_output(vs);
975 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
976 vnc_write_u8(vs, 0); /* padding */
977 vnc_write_u16(vs, 1); /* # of rects */
978 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
979 VNC_ENCODING_RICH_CURSOR);
980 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
981 vnc_write_pixels_generic(vs, c->data, isize);
982 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
983 vnc_unlock_output(vs);
984 return 0;
986 return -1;
989 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
990 QEMUCursor *c)
992 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
993 VncState *vs;
995 cursor_put(vd->cursor);
996 g_free(vd->cursor_mask);
998 vd->cursor = c;
999 cursor_get(vd->cursor);
1000 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1001 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1002 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1004 QTAILQ_FOREACH(vs, &vd->clients, next) {
1005 vnc_cursor_define(vs);
1009 static int find_and_clear_dirty_height(VncState *vs,
1010 int y, int last_x, int x, int height)
1012 int h;
1014 for (h = 1; h < (height - y); h++) {
1015 if (!test_bit(last_x, vs->dirty[y + h])) {
1016 break;
1018 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1021 return h;
1024 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1026 vs->has_dirty += has_dirty;
1027 if (vs->need_update && vs->ioc != NULL) {
1028 VncDisplay *vd = vs->vd;
1029 VncJob *job;
1030 int y;
1031 int height, width;
1032 int n = 0;
1034 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1035 /* kernel send buffers are full -> drop frames to throttle */
1036 return 0;
1038 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1039 return 0;
1042 * Send screen updates to the vnc client using the server
1043 * surface and server dirty map. guest surface updates
1044 * happening in parallel don't disturb us, the next pass will
1045 * send them to the client.
1047 job = vnc_job_new(vs);
1049 height = pixman_image_get_height(vd->server);
1050 width = pixman_image_get_width(vd->server);
1052 y = 0;
1053 for (;;) {
1054 int x, h;
1055 unsigned long x2;
1056 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1057 height * VNC_DIRTY_BPL(vs),
1058 y * VNC_DIRTY_BPL(vs));
1059 if (offset == height * VNC_DIRTY_BPL(vs)) {
1060 /* no more dirty bits */
1061 break;
1063 y = offset / VNC_DIRTY_BPL(vs);
1064 x = offset % VNC_DIRTY_BPL(vs);
1065 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1066 VNC_DIRTY_BPL(vs), x);
1067 bitmap_clear(vs->dirty[y], x, x2 - x);
1068 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1069 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1070 if (x2 > x) {
1071 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1072 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1074 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1075 y += h;
1076 if (y == height) {
1077 break;
1082 vnc_job_push(job);
1083 if (sync) {
1084 vnc_jobs_join(vs);
1086 vs->force_update = 0;
1087 vs->has_dirty = 0;
1088 return n;
1091 if (vs->disconnecting) {
1092 vnc_disconnect_finish(vs);
1093 } else if (sync) {
1094 vnc_jobs_join(vs);
1097 return 0;
1100 /* audio */
1101 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1103 VncState *vs = opaque;
1105 switch (cmd) {
1106 case AUD_CNOTIFY_DISABLE:
1107 vnc_lock_output(vs);
1108 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1109 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1110 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1111 vnc_unlock_output(vs);
1112 vnc_flush(vs);
1113 break;
1115 case AUD_CNOTIFY_ENABLE:
1116 vnc_lock_output(vs);
1117 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1118 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1119 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1120 vnc_unlock_output(vs);
1121 vnc_flush(vs);
1122 break;
1126 static void audio_capture_destroy(void *opaque)
1130 static void audio_capture(void *opaque, void *buf, int size)
1132 VncState *vs = opaque;
1134 vnc_lock_output(vs);
1135 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1136 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1137 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1138 vnc_write_u32(vs, size);
1139 vnc_write(vs, buf, size);
1140 vnc_unlock_output(vs);
1141 vnc_flush(vs);
1144 static void audio_add(VncState *vs)
1146 struct audio_capture_ops ops;
1148 if (vs->audio_cap) {
1149 error_report("audio already running");
1150 return;
1153 ops.notify = audio_capture_notify;
1154 ops.destroy = audio_capture_destroy;
1155 ops.capture = audio_capture;
1157 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1158 if (!vs->audio_cap) {
1159 error_report("Failed to add audio capture");
1163 static void audio_del(VncState *vs)
1165 if (vs->audio_cap) {
1166 AUD_del_capture(vs->audio_cap, vs);
1167 vs->audio_cap = NULL;
1171 static void vnc_disconnect_start(VncState *vs)
1173 if (vs->disconnecting) {
1174 return;
1176 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1177 if (vs->ioc_tag) {
1178 g_source_remove(vs->ioc_tag);
1180 qio_channel_close(vs->ioc, NULL);
1181 vs->disconnecting = TRUE;
1184 void vnc_disconnect_finish(VncState *vs)
1186 int i;
1188 vnc_jobs_join(vs); /* Wait encoding jobs */
1190 vnc_lock_output(vs);
1191 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1193 buffer_free(&vs->input);
1194 buffer_free(&vs->output);
1195 buffer_free(&vs->ws_input);
1196 buffer_free(&vs->ws_output);
1198 qapi_free_VncClientInfo(vs->info);
1200 vnc_zlib_clear(vs);
1201 vnc_tight_clear(vs);
1202 vnc_zrle_clear(vs);
1204 qcrypto_tls_session_free(vs->tls);
1205 #ifdef CONFIG_VNC_SASL
1206 vnc_sasl_client_cleanup(vs);
1207 #endif /* CONFIG_VNC_SASL */
1208 audio_del(vs);
1209 vnc_release_modifiers(vs);
1211 if (vs->initialized) {
1212 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1213 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1214 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1215 /* last client gone */
1216 vnc_update_server_surface(vs->vd);
1220 if (vs->vd->lock_key_sync)
1221 qemu_remove_led_event_handler(vs->led);
1222 vnc_unlock_output(vs);
1224 qemu_mutex_destroy(&vs->output_mutex);
1225 if (vs->bh != NULL) {
1226 qemu_bh_delete(vs->bh);
1228 buffer_free(&vs->jobs_buffer);
1230 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1231 g_free(vs->lossy_rect[i]);
1233 g_free(vs->lossy_rect);
1235 object_unref(OBJECT(vs->ioc));
1236 vs->ioc = NULL;
1237 object_unref(OBJECT(vs->sioc));
1238 vs->sioc = NULL;
1239 g_free(vs);
1242 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1244 if (ret <= 0) {
1245 if (ret == 0) {
1246 VNC_DEBUG("Closing down client sock: EOF\n");
1247 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1248 VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
1249 ret, errp ? error_get_pretty(*errp) : "Unknown");
1252 vnc_disconnect_start(vs);
1253 if (errp) {
1254 error_free(*errp);
1255 *errp = NULL;
1257 return 0;
1259 return ret;
1263 void vnc_client_error(VncState *vs)
1265 VNC_DEBUG("Closing down client sock: protocol error\n");
1266 vnc_disconnect_start(vs);
1270 ssize_t vnc_tls_pull(char *buf, size_t len, void *opaque)
1272 VncState *vs = opaque;
1273 ssize_t ret = qio_channel_read(vs->ioc, buf, len, NULL);
1274 if (ret < 0) {
1275 if (ret == QIO_CHANNEL_ERR_BLOCK) {
1276 errno = EAGAIN;
1277 } else {
1278 errno = EIO;
1280 return -1;
1282 return ret;
1286 ssize_t vnc_tls_push(const char *buf, size_t len, void *opaque)
1288 VncState *vs = opaque;
1289 ssize_t ret = qio_channel_write(vs->ioc, buf, len, NULL);
1290 if (ret < 0) {
1291 if (ret == QIO_CHANNEL_ERR_BLOCK) {
1292 errno = EAGAIN;
1293 } else {
1294 errno = EIO;
1296 return -1;
1298 return ret;
1303 * Called to write a chunk of data to the client socket. The data may
1304 * be the raw data, or may have already been encoded by SASL.
1305 * The data will be written either straight onto the socket, or
1306 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1308 * NB, it is theoretically possible to have 2 layers of encryption,
1309 * both SASL, and this TLS layer. It is highly unlikely in practice
1310 * though, since SASL encryption will typically be a no-op if TLS
1311 * is active
1313 * Returns the number of bytes written, which may be less than
1314 * the requested 'datalen' if the socket would block. Returns
1315 * -1 on error, and disconnects the client socket.
1317 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1319 Error *err = NULL;
1320 ssize_t ret;
1321 if (vs->tls) {
1322 ret = qcrypto_tls_session_write(vs->tls, (const char *)data, datalen);
1323 if (ret < 0) {
1324 if (errno == EAGAIN) {
1325 ret = QIO_CHANNEL_ERR_BLOCK;
1326 } else {
1327 ret = -1;
1328 error_setg_errno(&err, errno, "%s",
1329 "Cannot write to TLS socket");
1332 } else {
1333 ret = qio_channel_write(
1334 vs->ioc, (const char *)data, datalen, &err);
1336 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1337 return vnc_client_io_error(vs, ret, &err);
1342 * Called to write buffered data to the client socket, when not
1343 * using any SASL SSF encryption layers. Will write as much data
1344 * as possible without blocking. If all buffered data is written,
1345 * will switch the FD poll() handler back to read monitoring.
1347 * Returns the number of bytes written, which may be less than
1348 * the buffered output data if the socket would block. Returns
1349 * -1 on error, and disconnects the client socket.
1351 static ssize_t vnc_client_write_plain(VncState *vs)
1353 ssize_t ret;
1355 #ifdef CONFIG_VNC_SASL
1356 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1357 vs->output.buffer, vs->output.capacity, vs->output.offset,
1358 vs->sasl.waitWriteSSF);
1360 if (vs->sasl.conn &&
1361 vs->sasl.runSSF &&
1362 vs->sasl.waitWriteSSF) {
1363 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1364 if (ret)
1365 vs->sasl.waitWriteSSF -= ret;
1366 } else
1367 #endif /* CONFIG_VNC_SASL */
1368 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1369 if (!ret)
1370 return 0;
1372 buffer_advance(&vs->output, ret);
1374 if (vs->output.offset == 0) {
1375 if (vs->ioc_tag) {
1376 g_source_remove(vs->ioc_tag);
1378 vs->ioc_tag = qio_channel_add_watch(
1379 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1382 return ret;
1387 * First function called whenever there is data to be written to
1388 * the client socket. Will delegate actual work according to whether
1389 * SASL SSF layers are enabled (thus requiring encryption calls)
1391 static void vnc_client_write_locked(VncState *vs)
1393 #ifdef CONFIG_VNC_SASL
1394 if (vs->sasl.conn &&
1395 vs->sasl.runSSF &&
1396 !vs->sasl.waitWriteSSF) {
1397 vnc_client_write_sasl(vs);
1398 } else
1399 #endif /* CONFIG_VNC_SASL */
1401 if (vs->encode_ws) {
1402 vnc_client_write_ws(vs);
1403 } else {
1404 vnc_client_write_plain(vs);
1409 static void vnc_client_write(VncState *vs)
1412 vnc_lock_output(vs);
1413 if (vs->output.offset || vs->ws_output.offset) {
1414 vnc_client_write_locked(vs);
1415 } else if (vs->ioc != NULL) {
1416 if (vs->ioc_tag) {
1417 g_source_remove(vs->ioc_tag);
1419 vs->ioc_tag = qio_channel_add_watch(
1420 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1422 vnc_unlock_output(vs);
1425 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1427 vs->read_handler = func;
1428 vs->read_handler_expect = expecting;
1433 * Called to read a chunk of data from the client socket. The data may
1434 * be the raw data, or may need to be further decoded by SASL.
1435 * The data will be read either straight from to the socket, or
1436 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1438 * NB, it is theoretically possible to have 2 layers of encryption,
1439 * both SASL, and this TLS layer. It is highly unlikely in practice
1440 * though, since SASL encryption will typically be a no-op if TLS
1441 * is active
1443 * Returns the number of bytes read, which may be less than
1444 * the requested 'datalen' if the socket would block. Returns
1445 * -1 on error, and disconnects the client socket.
1447 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1449 ssize_t ret;
1450 Error *err = NULL;
1451 if (vs->tls) {
1452 ret = qcrypto_tls_session_read(vs->tls, (char *)data, datalen);
1453 if (ret < 0) {
1454 if (errno == EAGAIN) {
1455 ret = QIO_CHANNEL_ERR_BLOCK;
1456 } else {
1457 ret = -1;
1458 error_setg_errno(&err, errno, "%s",
1459 "Cannot read from TLS socket");
1462 } else {
1463 ret = qio_channel_read(
1464 vs->ioc, (char *)data, datalen, &err);
1466 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1467 return vnc_client_io_error(vs, ret, &err);
1472 * Called to read data from the client socket to the input buffer,
1473 * when not using any SASL SSF encryption layers. Will read as much
1474 * data as possible without blocking.
1476 * Returns the number of bytes read. Returns -1 on error, and
1477 * disconnects the client socket.
1479 static ssize_t vnc_client_read_plain(VncState *vs)
1481 ssize_t ret;
1482 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1483 vs->input.buffer, vs->input.capacity, vs->input.offset);
1484 buffer_reserve(&vs->input, 4096);
1485 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1486 if (!ret)
1487 return 0;
1488 vs->input.offset += ret;
1489 return ret;
1492 static void vnc_jobs_bh(void *opaque)
1494 VncState *vs = opaque;
1496 vnc_jobs_consume_buffer(vs);
1500 * First function called whenever there is more data to be read from
1501 * the client socket. Will delegate actual work according to whether
1502 * SASL SSF layers are enabled (thus requiring decryption calls)
1504 static void vnc_client_read(VncState *vs)
1506 ssize_t ret;
1508 #ifdef CONFIG_VNC_SASL
1509 if (vs->sasl.conn && vs->sasl.runSSF)
1510 ret = vnc_client_read_sasl(vs);
1511 else
1512 #endif /* CONFIG_VNC_SASL */
1513 if (vs->encode_ws) {
1514 ret = vnc_client_read_ws(vs);
1515 if (ret == -1) {
1516 vnc_disconnect_start(vs);
1517 return;
1518 } else if (ret == -2) {
1519 vnc_client_error(vs);
1520 return;
1522 } else {
1523 ret = vnc_client_read_plain(vs);
1525 if (!ret) {
1526 if (vs->disconnecting) {
1527 vnc_disconnect_finish(vs);
1529 return;
1532 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1533 size_t len = vs->read_handler_expect;
1534 int ret;
1536 ret = vs->read_handler(vs, vs->input.buffer, len);
1537 if (vs->disconnecting) {
1538 vnc_disconnect_finish(vs);
1539 return;
1542 if (!ret) {
1543 buffer_advance(&vs->input, len);
1544 } else {
1545 vs->read_handler_expect = ret;
1550 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1551 GIOCondition condition, void *opaque)
1553 VncState *vs = opaque;
1554 if (condition & G_IO_IN) {
1555 vnc_client_read(vs);
1557 if (condition & G_IO_OUT) {
1558 vnc_client_write(vs);
1560 return TRUE;
1564 void vnc_write(VncState *vs, const void *data, size_t len)
1566 buffer_reserve(&vs->output, len);
1568 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1569 if (vs->ioc_tag) {
1570 g_source_remove(vs->ioc_tag);
1572 vs->ioc_tag = qio_channel_add_watch(
1573 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1576 buffer_append(&vs->output, data, len);
1579 void vnc_write_s32(VncState *vs, int32_t value)
1581 vnc_write_u32(vs, *(uint32_t *)&value);
1584 void vnc_write_u32(VncState *vs, uint32_t value)
1586 uint8_t buf[4];
1588 buf[0] = (value >> 24) & 0xFF;
1589 buf[1] = (value >> 16) & 0xFF;
1590 buf[2] = (value >> 8) & 0xFF;
1591 buf[3] = value & 0xFF;
1593 vnc_write(vs, buf, 4);
1596 void vnc_write_u16(VncState *vs, uint16_t value)
1598 uint8_t buf[2];
1600 buf[0] = (value >> 8) & 0xFF;
1601 buf[1] = value & 0xFF;
1603 vnc_write(vs, buf, 2);
1606 void vnc_write_u8(VncState *vs, uint8_t value)
1608 vnc_write(vs, (char *)&value, 1);
1611 void vnc_flush(VncState *vs)
1613 vnc_lock_output(vs);
1614 if (vs->ioc != NULL && (vs->output.offset || vs->ws_output.offset)) {
1615 vnc_client_write_locked(vs);
1617 vnc_unlock_output(vs);
1620 static uint8_t read_u8(uint8_t *data, size_t offset)
1622 return data[offset];
1625 static uint16_t read_u16(uint8_t *data, size_t offset)
1627 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1630 static int32_t read_s32(uint8_t *data, size_t offset)
1632 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1633 (data[offset + 2] << 8) | data[offset + 3]);
1636 uint32_t read_u32(uint8_t *data, size_t offset)
1638 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1639 (data[offset + 2] << 8) | data[offset + 3]);
1642 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1646 static void check_pointer_type_change(Notifier *notifier, void *data)
1648 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1649 int absolute = qemu_input_is_absolute();
1651 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1652 vnc_lock_output(vs);
1653 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1654 vnc_write_u8(vs, 0);
1655 vnc_write_u16(vs, 1);
1656 vnc_framebuffer_update(vs, absolute, 0,
1657 pixman_image_get_width(vs->vd->server),
1658 pixman_image_get_height(vs->vd->server),
1659 VNC_ENCODING_POINTER_TYPE_CHANGE);
1660 vnc_unlock_output(vs);
1661 vnc_flush(vs);
1663 vs->absolute = absolute;
1666 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1668 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1669 [INPUT_BUTTON_LEFT] = 0x01,
1670 [INPUT_BUTTON_MIDDLE] = 0x02,
1671 [INPUT_BUTTON_RIGHT] = 0x04,
1672 [INPUT_BUTTON_WHEELUP] = 0x08,
1673 [INPUT_BUTTON_WHEELDOWN] = 0x10,
1675 QemuConsole *con = vs->vd->dcl.con;
1676 int width = pixman_image_get_width(vs->vd->server);
1677 int height = pixman_image_get_height(vs->vd->server);
1679 if (vs->last_bmask != button_mask) {
1680 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1681 vs->last_bmask = button_mask;
1684 if (vs->absolute) {
1685 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1686 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1687 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1688 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1689 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1690 } else {
1691 if (vs->last_x != -1) {
1692 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1693 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1695 vs->last_x = x;
1696 vs->last_y = y;
1698 qemu_input_event_sync();
1701 static void reset_keys(VncState *vs)
1703 int i;
1704 for(i = 0; i < 256; i++) {
1705 if (vs->modifiers_state[i]) {
1706 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1707 vs->modifiers_state[i] = 0;
1712 static void press_key(VncState *vs, int keysym)
1714 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1715 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1716 qemu_input_event_send_key_delay(0);
1717 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1718 qemu_input_event_send_key_delay(0);
1721 static int current_led_state(VncState *vs)
1723 int ledstate = 0;
1725 if (vs->modifiers_state[0x46]) {
1726 ledstate |= QEMU_SCROLL_LOCK_LED;
1728 if (vs->modifiers_state[0x45]) {
1729 ledstate |= QEMU_NUM_LOCK_LED;
1731 if (vs->modifiers_state[0x3a]) {
1732 ledstate |= QEMU_CAPS_LOCK_LED;
1735 return ledstate;
1738 static void vnc_led_state_change(VncState *vs)
1740 int ledstate = 0;
1742 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1743 return;
1746 ledstate = current_led_state(vs);
1747 vnc_lock_output(vs);
1748 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1749 vnc_write_u8(vs, 0);
1750 vnc_write_u16(vs, 1);
1751 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1752 vnc_write_u8(vs, ledstate);
1753 vnc_unlock_output(vs);
1754 vnc_flush(vs);
1757 static void kbd_leds(void *opaque, int ledstate)
1759 VncState *vs = opaque;
1760 int caps, num, scr;
1761 bool has_changed = (ledstate != current_led_state(vs));
1763 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1764 (ledstate & QEMU_NUM_LOCK_LED),
1765 (ledstate & QEMU_SCROLL_LOCK_LED));
1767 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1768 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1769 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1771 if (vs->modifiers_state[0x3a] != caps) {
1772 vs->modifiers_state[0x3a] = caps;
1774 if (vs->modifiers_state[0x45] != num) {
1775 vs->modifiers_state[0x45] = num;
1777 if (vs->modifiers_state[0x46] != scr) {
1778 vs->modifiers_state[0x46] = scr;
1781 /* Sending the current led state message to the client */
1782 if (has_changed) {
1783 vnc_led_state_change(vs);
1787 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1789 /* QEMU console switch */
1790 switch(keycode) {
1791 case 0x2a: /* Left Shift */
1792 case 0x36: /* Right Shift */
1793 case 0x1d: /* Left CTRL */
1794 case 0x9d: /* Right CTRL */
1795 case 0x38: /* Left ALT */
1796 case 0xb8: /* Right ALT */
1797 if (down)
1798 vs->modifiers_state[keycode] = 1;
1799 else
1800 vs->modifiers_state[keycode] = 0;
1801 break;
1802 case 0x02 ... 0x0a: /* '1' to '9' keys */
1803 if (vs->vd->dcl.con == NULL &&
1804 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1805 /* Reset the modifiers sent to the current console */
1806 reset_keys(vs);
1807 console_select(keycode - 0x02);
1808 return;
1810 break;
1811 case 0x3a: /* CapsLock */
1812 case 0x45: /* NumLock */
1813 if (down)
1814 vs->modifiers_state[keycode] ^= 1;
1815 break;
1818 /* Turn off the lock state sync logic if the client support the led
1819 state extension.
1821 if (down && vs->vd->lock_key_sync &&
1822 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1823 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1824 /* If the numlock state needs to change then simulate an additional
1825 keypress before sending this one. This will happen if the user
1826 toggles numlock away from the VNC window.
1828 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1829 if (!vs->modifiers_state[0x45]) {
1830 trace_vnc_key_sync_numlock(true);
1831 vs->modifiers_state[0x45] = 1;
1832 press_key(vs, 0xff7f);
1834 } else {
1835 if (vs->modifiers_state[0x45]) {
1836 trace_vnc_key_sync_numlock(false);
1837 vs->modifiers_state[0x45] = 0;
1838 press_key(vs, 0xff7f);
1843 if (down && vs->vd->lock_key_sync &&
1844 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1845 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1846 /* If the capslock state needs to change then simulate an additional
1847 keypress before sending this one. This will happen if the user
1848 toggles capslock away from the VNC window.
1850 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1851 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1852 int capslock = !!(vs->modifiers_state[0x3a]);
1853 if (capslock) {
1854 if (uppercase == shift) {
1855 trace_vnc_key_sync_capslock(false);
1856 vs->modifiers_state[0x3a] = 0;
1857 press_key(vs, 0xffe5);
1859 } else {
1860 if (uppercase != shift) {
1861 trace_vnc_key_sync_capslock(true);
1862 vs->modifiers_state[0x3a] = 1;
1863 press_key(vs, 0xffe5);
1868 if (qemu_console_is_graphic(NULL)) {
1869 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1870 } else {
1871 bool numlock = vs->modifiers_state[0x45];
1872 bool control = (vs->modifiers_state[0x1d] ||
1873 vs->modifiers_state[0x9d]);
1874 /* QEMU console emulation */
1875 if (down) {
1876 switch (keycode) {
1877 case 0x2a: /* Left Shift */
1878 case 0x36: /* Right Shift */
1879 case 0x1d: /* Left CTRL */
1880 case 0x9d: /* Right CTRL */
1881 case 0x38: /* Left ALT */
1882 case 0xb8: /* Right ALT */
1883 break;
1884 case 0xc8:
1885 kbd_put_keysym(QEMU_KEY_UP);
1886 break;
1887 case 0xd0:
1888 kbd_put_keysym(QEMU_KEY_DOWN);
1889 break;
1890 case 0xcb:
1891 kbd_put_keysym(QEMU_KEY_LEFT);
1892 break;
1893 case 0xcd:
1894 kbd_put_keysym(QEMU_KEY_RIGHT);
1895 break;
1896 case 0xd3:
1897 kbd_put_keysym(QEMU_KEY_DELETE);
1898 break;
1899 case 0xc7:
1900 kbd_put_keysym(QEMU_KEY_HOME);
1901 break;
1902 case 0xcf:
1903 kbd_put_keysym(QEMU_KEY_END);
1904 break;
1905 case 0xc9:
1906 kbd_put_keysym(QEMU_KEY_PAGEUP);
1907 break;
1908 case 0xd1:
1909 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1910 break;
1912 case 0x47:
1913 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1914 break;
1915 case 0x48:
1916 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1917 break;
1918 case 0x49:
1919 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1920 break;
1921 case 0x4b:
1922 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1923 break;
1924 case 0x4c:
1925 kbd_put_keysym('5');
1926 break;
1927 case 0x4d:
1928 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1929 break;
1930 case 0x4f:
1931 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1932 break;
1933 case 0x50:
1934 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1935 break;
1936 case 0x51:
1937 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1938 break;
1939 case 0x52:
1940 kbd_put_keysym('0');
1941 break;
1942 case 0x53:
1943 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1944 break;
1946 case 0xb5:
1947 kbd_put_keysym('/');
1948 break;
1949 case 0x37:
1950 kbd_put_keysym('*');
1951 break;
1952 case 0x4a:
1953 kbd_put_keysym('-');
1954 break;
1955 case 0x4e:
1956 kbd_put_keysym('+');
1957 break;
1958 case 0x9c:
1959 kbd_put_keysym('\n');
1960 break;
1962 default:
1963 if (control) {
1964 kbd_put_keysym(sym & 0x1f);
1965 } else {
1966 kbd_put_keysym(sym);
1968 break;
1974 static void vnc_release_modifiers(VncState *vs)
1976 static const int keycodes[] = {
1977 /* shift, control, alt keys, both left & right */
1978 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1980 int i, keycode;
1982 if (!qemu_console_is_graphic(NULL)) {
1983 return;
1985 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1986 keycode = keycodes[i];
1987 if (!vs->modifiers_state[keycode]) {
1988 continue;
1990 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1994 static const char *code2name(int keycode)
1996 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1999 static void key_event(VncState *vs, int down, uint32_t sym)
2001 int keycode;
2002 int lsym = sym;
2004 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2005 lsym = lsym - 'A' + 'a';
2008 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
2009 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2010 do_key_event(vs, down, keycode, sym);
2013 static void ext_key_event(VncState *vs, int down,
2014 uint32_t sym, uint16_t keycode)
2016 /* if the user specifies a keyboard layout, always use it */
2017 if (keyboard_layout) {
2018 key_event(vs, down, sym);
2019 } else {
2020 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2021 do_key_event(vs, down, keycode, sym);
2025 static void framebuffer_update_request(VncState *vs, int incremental,
2026 int x, int y, int w, int h)
2028 vs->need_update = 1;
2030 if (incremental) {
2031 return;
2034 vs->force_update = 1;
2035 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2038 static void send_ext_key_event_ack(VncState *vs)
2040 vnc_lock_output(vs);
2041 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2042 vnc_write_u8(vs, 0);
2043 vnc_write_u16(vs, 1);
2044 vnc_framebuffer_update(vs, 0, 0,
2045 pixman_image_get_width(vs->vd->server),
2046 pixman_image_get_height(vs->vd->server),
2047 VNC_ENCODING_EXT_KEY_EVENT);
2048 vnc_unlock_output(vs);
2049 vnc_flush(vs);
2052 static void send_ext_audio_ack(VncState *vs)
2054 vnc_lock_output(vs);
2055 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2056 vnc_write_u8(vs, 0);
2057 vnc_write_u16(vs, 1);
2058 vnc_framebuffer_update(vs, 0, 0,
2059 pixman_image_get_width(vs->vd->server),
2060 pixman_image_get_height(vs->vd->server),
2061 VNC_ENCODING_AUDIO);
2062 vnc_unlock_output(vs);
2063 vnc_flush(vs);
2066 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2068 int i;
2069 unsigned int enc = 0;
2071 vs->features = 0;
2072 vs->vnc_encoding = 0;
2073 vs->tight.compression = 9;
2074 vs->tight.quality = -1; /* Lossless by default */
2075 vs->absolute = -1;
2078 * Start from the end because the encodings are sent in order of preference.
2079 * This way the preferred encoding (first encoding defined in the array)
2080 * will be set at the end of the loop.
2082 for (i = n_encodings - 1; i >= 0; i--) {
2083 enc = encodings[i];
2084 switch (enc) {
2085 case VNC_ENCODING_RAW:
2086 vs->vnc_encoding = enc;
2087 break;
2088 case VNC_ENCODING_COPYRECT:
2089 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2090 break;
2091 case VNC_ENCODING_HEXTILE:
2092 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2093 vs->vnc_encoding = enc;
2094 break;
2095 case VNC_ENCODING_TIGHT:
2096 vs->features |= VNC_FEATURE_TIGHT_MASK;
2097 vs->vnc_encoding = enc;
2098 break;
2099 #ifdef CONFIG_VNC_PNG
2100 case VNC_ENCODING_TIGHT_PNG:
2101 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2102 vs->vnc_encoding = enc;
2103 break;
2104 #endif
2105 case VNC_ENCODING_ZLIB:
2106 vs->features |= VNC_FEATURE_ZLIB_MASK;
2107 vs->vnc_encoding = enc;
2108 break;
2109 case VNC_ENCODING_ZRLE:
2110 vs->features |= VNC_FEATURE_ZRLE_MASK;
2111 vs->vnc_encoding = enc;
2112 break;
2113 case VNC_ENCODING_ZYWRLE:
2114 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2115 vs->vnc_encoding = enc;
2116 break;
2117 case VNC_ENCODING_DESKTOPRESIZE:
2118 vs->features |= VNC_FEATURE_RESIZE_MASK;
2119 break;
2120 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2121 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2122 break;
2123 case VNC_ENCODING_RICH_CURSOR:
2124 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2125 break;
2126 case VNC_ENCODING_EXT_KEY_EVENT:
2127 send_ext_key_event_ack(vs);
2128 break;
2129 case VNC_ENCODING_AUDIO:
2130 send_ext_audio_ack(vs);
2131 break;
2132 case VNC_ENCODING_WMVi:
2133 vs->features |= VNC_FEATURE_WMVI_MASK;
2134 break;
2135 case VNC_ENCODING_LED_STATE:
2136 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2137 break;
2138 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2139 vs->tight.compression = (enc & 0x0F);
2140 break;
2141 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2142 if (vs->vd->lossy) {
2143 vs->tight.quality = (enc & 0x0F);
2145 break;
2146 default:
2147 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2148 break;
2151 vnc_desktop_resize(vs);
2152 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2153 vnc_led_state_change(vs);
2156 static void set_pixel_conversion(VncState *vs)
2158 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2160 if (fmt == VNC_SERVER_FB_FORMAT) {
2161 vs->write_pixels = vnc_write_pixels_copy;
2162 vnc_hextile_set_pixel_conversion(vs, 0);
2163 } else {
2164 vs->write_pixels = vnc_write_pixels_generic;
2165 vnc_hextile_set_pixel_conversion(vs, 1);
2169 static void set_pixel_format(VncState *vs,
2170 int bits_per_pixel, int depth,
2171 int big_endian_flag, int true_color_flag,
2172 int red_max, int green_max, int blue_max,
2173 int red_shift, int green_shift, int blue_shift)
2175 if (!true_color_flag) {
2176 vnc_client_error(vs);
2177 return;
2180 switch (bits_per_pixel) {
2181 case 8:
2182 case 16:
2183 case 32:
2184 break;
2185 default:
2186 vnc_client_error(vs);
2187 return;
2190 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2191 vs->client_pf.rbits = hweight_long(red_max);
2192 vs->client_pf.rshift = red_shift;
2193 vs->client_pf.rmask = red_max << red_shift;
2194 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2195 vs->client_pf.gbits = hweight_long(green_max);
2196 vs->client_pf.gshift = green_shift;
2197 vs->client_pf.gmask = green_max << green_shift;
2198 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2199 vs->client_pf.bbits = hweight_long(blue_max);
2200 vs->client_pf.bshift = blue_shift;
2201 vs->client_pf.bmask = blue_max << blue_shift;
2202 vs->client_pf.bits_per_pixel = bits_per_pixel;
2203 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2204 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2205 vs->client_be = big_endian_flag;
2207 set_pixel_conversion(vs);
2209 graphic_hw_invalidate(vs->vd->dcl.con);
2210 graphic_hw_update(vs->vd->dcl.con);
2213 static void pixel_format_message (VncState *vs) {
2214 char pad[3] = { 0, 0, 0 };
2216 vs->client_pf = qemu_default_pixelformat(32);
2218 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2219 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2221 #ifdef HOST_WORDS_BIGENDIAN
2222 vnc_write_u8(vs, 1); /* big-endian-flag */
2223 #else
2224 vnc_write_u8(vs, 0); /* big-endian-flag */
2225 #endif
2226 vnc_write_u8(vs, 1); /* true-color-flag */
2227 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2228 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2229 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2230 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2231 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2232 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2233 vnc_write(vs, pad, 3); /* padding */
2235 vnc_hextile_set_pixel_conversion(vs, 0);
2236 vs->write_pixels = vnc_write_pixels_copy;
2239 static void vnc_colordepth(VncState *vs)
2241 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2242 /* Sending a WMVi message to notify the client*/
2243 vnc_lock_output(vs);
2244 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2245 vnc_write_u8(vs, 0);
2246 vnc_write_u16(vs, 1); /* number of rects */
2247 vnc_framebuffer_update(vs, 0, 0,
2248 pixman_image_get_width(vs->vd->server),
2249 pixman_image_get_height(vs->vd->server),
2250 VNC_ENCODING_WMVi);
2251 pixel_format_message(vs);
2252 vnc_unlock_output(vs);
2253 vnc_flush(vs);
2254 } else {
2255 set_pixel_conversion(vs);
2259 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2261 int i;
2262 uint16_t limit;
2263 VncDisplay *vd = vs->vd;
2265 if (data[0] > 3) {
2266 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2269 switch (data[0]) {
2270 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2271 if (len == 1)
2272 return 20;
2274 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2275 read_u8(data, 6), read_u8(data, 7),
2276 read_u16(data, 8), read_u16(data, 10),
2277 read_u16(data, 12), read_u8(data, 14),
2278 read_u8(data, 15), read_u8(data, 16));
2279 break;
2280 case VNC_MSG_CLIENT_SET_ENCODINGS:
2281 if (len == 1)
2282 return 4;
2284 if (len == 4) {
2285 limit = read_u16(data, 2);
2286 if (limit > 0)
2287 return 4 + (limit * 4);
2288 } else
2289 limit = read_u16(data, 2);
2291 for (i = 0; i < limit; i++) {
2292 int32_t val = read_s32(data, 4 + (i * 4));
2293 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2296 set_encodings(vs, (int32_t *)(data + 4), limit);
2297 break;
2298 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2299 if (len == 1)
2300 return 10;
2302 framebuffer_update_request(vs,
2303 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2304 read_u16(data, 6), read_u16(data, 8));
2305 break;
2306 case VNC_MSG_CLIENT_KEY_EVENT:
2307 if (len == 1)
2308 return 8;
2310 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2311 break;
2312 case VNC_MSG_CLIENT_POINTER_EVENT:
2313 if (len == 1)
2314 return 6;
2316 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2317 break;
2318 case VNC_MSG_CLIENT_CUT_TEXT:
2319 if (len == 1) {
2320 return 8;
2322 if (len == 8) {
2323 uint32_t dlen = read_u32(data, 4);
2324 if (dlen > (1 << 20)) {
2325 error_report("vnc: client_cut_text msg payload has %u bytes"
2326 " which exceeds our limit of 1MB.", dlen);
2327 vnc_client_error(vs);
2328 break;
2330 if (dlen > 0) {
2331 return 8 + dlen;
2335 client_cut_text(vs, read_u32(data, 4), data + 8);
2336 break;
2337 case VNC_MSG_CLIENT_QEMU:
2338 if (len == 1)
2339 return 2;
2341 switch (read_u8(data, 1)) {
2342 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2343 if (len == 2)
2344 return 12;
2346 ext_key_event(vs, read_u16(data, 2),
2347 read_u32(data, 4), read_u32(data, 8));
2348 break;
2349 case VNC_MSG_CLIENT_QEMU_AUDIO:
2350 if (len == 2)
2351 return 4;
2353 switch (read_u16 (data, 2)) {
2354 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2355 audio_add(vs);
2356 break;
2357 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2358 audio_del(vs);
2359 break;
2360 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2361 if (len == 4)
2362 return 10;
2363 switch (read_u8(data, 4)) {
2364 case 0: vs->as.fmt = AUD_FMT_U8; break;
2365 case 1: vs->as.fmt = AUD_FMT_S8; break;
2366 case 2: vs->as.fmt = AUD_FMT_U16; break;
2367 case 3: vs->as.fmt = AUD_FMT_S16; break;
2368 case 4: vs->as.fmt = AUD_FMT_U32; break;
2369 case 5: vs->as.fmt = AUD_FMT_S32; break;
2370 default:
2371 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2372 vnc_client_error(vs);
2373 break;
2375 vs->as.nchannels = read_u8(data, 5);
2376 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2377 VNC_DEBUG("Invalid audio channel coount %d\n",
2378 read_u8(data, 5));
2379 vnc_client_error(vs);
2380 break;
2382 vs->as.freq = read_u32(data, 6);
2383 break;
2384 default:
2385 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2386 vnc_client_error(vs);
2387 break;
2389 break;
2391 default:
2392 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2393 vnc_client_error(vs);
2394 break;
2396 break;
2397 default:
2398 VNC_DEBUG("Msg: %d\n", data[0]);
2399 vnc_client_error(vs);
2400 break;
2403 vnc_read_when(vs, protocol_client_msg, 1);
2404 return 0;
2407 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2409 char buf[1024];
2410 VncShareMode mode;
2411 int size;
2413 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2414 switch (vs->vd->share_policy) {
2415 case VNC_SHARE_POLICY_IGNORE:
2417 * Ignore the shared flag. Nothing to do here.
2419 * Doesn't conform to the rfb spec but is traditional qemu
2420 * behavior, thus left here as option for compatibility
2421 * reasons.
2423 break;
2424 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2426 * Policy: Allow clients ask for exclusive access.
2428 * Implementation: When a client asks for exclusive access,
2429 * disconnect all others. Shared connects are allowed as long
2430 * as no exclusive connection exists.
2432 * This is how the rfb spec suggests to handle the shared flag.
2434 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2435 VncState *client;
2436 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2437 if (vs == client) {
2438 continue;
2440 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2441 client->share_mode != VNC_SHARE_MODE_SHARED) {
2442 continue;
2444 vnc_disconnect_start(client);
2447 if (mode == VNC_SHARE_MODE_SHARED) {
2448 if (vs->vd->num_exclusive > 0) {
2449 vnc_disconnect_start(vs);
2450 return 0;
2453 break;
2454 case VNC_SHARE_POLICY_FORCE_SHARED:
2456 * Policy: Shared connects only.
2457 * Implementation: Disallow clients asking for exclusive access.
2459 * Useful for shared desktop sessions where you don't want
2460 * someone forgetting to say -shared when running the vnc
2461 * client disconnect everybody else.
2463 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2464 vnc_disconnect_start(vs);
2465 return 0;
2467 break;
2469 vnc_set_share_mode(vs, mode);
2471 if (vs->vd->num_shared > vs->vd->connections_limit) {
2472 vnc_disconnect_start(vs);
2473 return 0;
2476 vs->client_width = pixman_image_get_width(vs->vd->server);
2477 vs->client_height = pixman_image_get_height(vs->vd->server);
2478 vnc_write_u16(vs, vs->client_width);
2479 vnc_write_u16(vs, vs->client_height);
2481 pixel_format_message(vs);
2483 if (qemu_name)
2484 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2485 else
2486 size = snprintf(buf, sizeof(buf), "QEMU");
2488 vnc_write_u32(vs, size);
2489 vnc_write(vs, buf, size);
2490 vnc_flush(vs);
2492 vnc_client_cache_auth(vs);
2493 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2495 vnc_read_when(vs, protocol_client_msg, 1);
2497 return 0;
2500 void start_client_init(VncState *vs)
2502 vnc_read_when(vs, protocol_client_init, 1);
2505 static void make_challenge(VncState *vs)
2507 int i;
2509 srand(time(NULL)+getpid()+getpid()*987654+rand());
2511 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2512 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2515 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2517 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2518 size_t i, pwlen;
2519 unsigned char key[8];
2520 time_t now = time(NULL);
2521 QCryptoCipher *cipher = NULL;
2522 Error *err = NULL;
2524 if (!vs->vd->password) {
2525 VNC_DEBUG("No password configured on server");
2526 goto reject;
2528 if (vs->vd->expires < now) {
2529 VNC_DEBUG("Password is expired");
2530 goto reject;
2533 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2535 /* Calculate the expected challenge response */
2536 pwlen = strlen(vs->vd->password);
2537 for (i=0; i<sizeof(key); i++)
2538 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2540 cipher = qcrypto_cipher_new(
2541 QCRYPTO_CIPHER_ALG_DES_RFB,
2542 QCRYPTO_CIPHER_MODE_ECB,
2543 key, G_N_ELEMENTS(key),
2544 &err);
2545 if (!cipher) {
2546 VNC_DEBUG("Cannot initialize cipher %s",
2547 error_get_pretty(err));
2548 error_free(err);
2549 goto reject;
2552 if (qcrypto_cipher_encrypt(cipher,
2553 vs->challenge,
2554 response,
2555 VNC_AUTH_CHALLENGE_SIZE,
2556 &err) < 0) {
2557 VNC_DEBUG("Cannot encrypt challenge %s",
2558 error_get_pretty(err));
2559 error_free(err);
2560 goto reject;
2563 /* Compare expected vs actual challenge response */
2564 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2565 VNC_DEBUG("Client challenge response did not match\n");
2566 goto reject;
2567 } else {
2568 VNC_DEBUG("Accepting VNC challenge response\n");
2569 vnc_write_u32(vs, 0); /* Accept auth */
2570 vnc_flush(vs);
2572 start_client_init(vs);
2575 qcrypto_cipher_free(cipher);
2576 return 0;
2578 reject:
2579 vnc_write_u32(vs, 1); /* Reject auth */
2580 if (vs->minor >= 8) {
2581 static const char err[] = "Authentication failed";
2582 vnc_write_u32(vs, sizeof(err));
2583 vnc_write(vs, err, sizeof(err));
2585 vnc_flush(vs);
2586 vnc_client_error(vs);
2587 qcrypto_cipher_free(cipher);
2588 return 0;
2591 void start_auth_vnc(VncState *vs)
2593 make_challenge(vs);
2594 /* Send client a 'random' challenge */
2595 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2596 vnc_flush(vs);
2598 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2602 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2604 /* We only advertise 1 auth scheme at a time, so client
2605 * must pick the one we sent. Verify this */
2606 if (data[0] != vs->auth) { /* Reject auth */
2607 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2608 vnc_write_u32(vs, 1);
2609 if (vs->minor >= 8) {
2610 static const char err[] = "Authentication failed";
2611 vnc_write_u32(vs, sizeof(err));
2612 vnc_write(vs, err, sizeof(err));
2614 vnc_client_error(vs);
2615 } else { /* Accept requested auth */
2616 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2617 switch (vs->auth) {
2618 case VNC_AUTH_NONE:
2619 VNC_DEBUG("Accept auth none\n");
2620 if (vs->minor >= 8) {
2621 vnc_write_u32(vs, 0); /* Accept auth completion */
2622 vnc_flush(vs);
2624 start_client_init(vs);
2625 break;
2627 case VNC_AUTH_VNC:
2628 VNC_DEBUG("Start VNC auth\n");
2629 start_auth_vnc(vs);
2630 break;
2632 case VNC_AUTH_VENCRYPT:
2633 VNC_DEBUG("Accept VeNCrypt auth\n");
2634 start_auth_vencrypt(vs);
2635 break;
2637 #ifdef CONFIG_VNC_SASL
2638 case VNC_AUTH_SASL:
2639 VNC_DEBUG("Accept SASL auth\n");
2640 start_auth_sasl(vs);
2641 break;
2642 #endif /* CONFIG_VNC_SASL */
2644 default: /* Should not be possible, but just in case */
2645 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2646 vnc_write_u8(vs, 1);
2647 if (vs->minor >= 8) {
2648 static const char err[] = "Authentication failed";
2649 vnc_write_u32(vs, sizeof(err));
2650 vnc_write(vs, err, sizeof(err));
2652 vnc_client_error(vs);
2655 return 0;
2658 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2660 char local[13];
2662 memcpy(local, version, 12);
2663 local[12] = 0;
2665 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2666 VNC_DEBUG("Malformed protocol version %s\n", local);
2667 vnc_client_error(vs);
2668 return 0;
2670 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2671 if (vs->major != 3 ||
2672 (vs->minor != 3 &&
2673 vs->minor != 4 &&
2674 vs->minor != 5 &&
2675 vs->minor != 7 &&
2676 vs->minor != 8)) {
2677 VNC_DEBUG("Unsupported client version\n");
2678 vnc_write_u32(vs, VNC_AUTH_INVALID);
2679 vnc_flush(vs);
2680 vnc_client_error(vs);
2681 return 0;
2683 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2684 * as equivalent to v3.3 by servers
2686 if (vs->minor == 4 || vs->minor == 5)
2687 vs->minor = 3;
2689 if (vs->minor == 3) {
2690 if (vs->auth == VNC_AUTH_NONE) {
2691 VNC_DEBUG("Tell client auth none\n");
2692 vnc_write_u32(vs, vs->auth);
2693 vnc_flush(vs);
2694 start_client_init(vs);
2695 } else if (vs->auth == VNC_AUTH_VNC) {
2696 VNC_DEBUG("Tell client VNC auth\n");
2697 vnc_write_u32(vs, vs->auth);
2698 vnc_flush(vs);
2699 start_auth_vnc(vs);
2700 } else {
2701 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2702 vnc_write_u32(vs, VNC_AUTH_INVALID);
2703 vnc_flush(vs);
2704 vnc_client_error(vs);
2706 } else {
2707 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2708 vnc_write_u8(vs, 1); /* num auth */
2709 vnc_write_u8(vs, vs->auth);
2710 vnc_read_when(vs, protocol_client_auth, 1);
2711 vnc_flush(vs);
2714 return 0;
2717 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2719 struct VncSurface *vs = &vd->guest;
2721 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2724 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2726 int i, j;
2728 w = (x + w) / VNC_STAT_RECT;
2729 h = (y + h) / VNC_STAT_RECT;
2730 x /= VNC_STAT_RECT;
2731 y /= VNC_STAT_RECT;
2733 for (j = y; j <= h; j++) {
2734 for (i = x; i <= w; i++) {
2735 vs->lossy_rect[j][i] = 1;
2740 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2742 VncState *vs;
2743 int sty = y / VNC_STAT_RECT;
2744 int stx = x / VNC_STAT_RECT;
2745 int has_dirty = 0;
2747 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2748 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2750 QTAILQ_FOREACH(vs, &vd->clients, next) {
2751 int j;
2753 /* kernel send buffers are full -> refresh later */
2754 if (vs->output.offset) {
2755 continue;
2758 if (!vs->lossy_rect[sty][stx]) {
2759 continue;
2762 vs->lossy_rect[sty][stx] = 0;
2763 for (j = 0; j < VNC_STAT_RECT; ++j) {
2764 bitmap_set(vs->dirty[y + j],
2765 x / VNC_DIRTY_PIXELS_PER_BIT,
2766 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2768 has_dirty++;
2771 return has_dirty;
2774 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2776 int width = pixman_image_get_width(vd->guest.fb);
2777 int height = pixman_image_get_height(vd->guest.fb);
2778 int x, y;
2779 struct timeval res;
2780 int has_dirty = 0;
2782 for (y = 0; y < height; y += VNC_STAT_RECT) {
2783 for (x = 0; x < width; x += VNC_STAT_RECT) {
2784 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2786 rect->updated = false;
2790 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2792 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2793 return has_dirty;
2795 vd->guest.last_freq_check = *tv;
2797 for (y = 0; y < height; y += VNC_STAT_RECT) {
2798 for (x = 0; x < width; x += VNC_STAT_RECT) {
2799 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2800 int count = ARRAY_SIZE(rect->times);
2801 struct timeval min, max;
2803 if (!timerisset(&rect->times[count - 1])) {
2804 continue ;
2807 max = rect->times[(rect->idx + count - 1) % count];
2808 qemu_timersub(tv, &max, &res);
2810 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2811 rect->freq = 0;
2812 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2813 memset(rect->times, 0, sizeof (rect->times));
2814 continue ;
2817 min = rect->times[rect->idx];
2818 max = rect->times[(rect->idx + count - 1) % count];
2819 qemu_timersub(&max, &min, &res);
2821 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2822 rect->freq /= count;
2823 rect->freq = 1. / rect->freq;
2826 return has_dirty;
2829 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2831 int i, j;
2832 double total = 0;
2833 int num = 0;
2835 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2836 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2838 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2839 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2840 total += vnc_stat_rect(vs->vd, i, j)->freq;
2841 num++;
2845 if (num) {
2846 return total / num;
2847 } else {
2848 return 0;
2852 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2854 VncRectStat *rect;
2856 rect = vnc_stat_rect(vd, x, y);
2857 if (rect->updated) {
2858 return ;
2860 rect->times[rect->idx] = *tv;
2861 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2862 rect->updated = true;
2865 static int vnc_refresh_server_surface(VncDisplay *vd)
2867 int width = MIN(pixman_image_get_width(vd->guest.fb),
2868 pixman_image_get_width(vd->server));
2869 int height = MIN(pixman_image_get_height(vd->guest.fb),
2870 pixman_image_get_height(vd->server));
2871 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2872 uint8_t *guest_row0 = NULL, *server_row0;
2873 VncState *vs;
2874 int has_dirty = 0;
2875 pixman_image_t *tmpbuf = NULL;
2877 struct timeval tv = { 0, 0 };
2879 if (!vd->non_adaptive) {
2880 gettimeofday(&tv, NULL);
2881 has_dirty = vnc_update_stats(vd, &tv);
2885 * Walk through the guest dirty map.
2886 * Check and copy modified bits from guest to server surface.
2887 * Update server dirty map.
2889 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2890 server_stride = guest_stride = guest_ll =
2891 pixman_image_get_stride(vd->server);
2892 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2893 server_stride);
2894 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2895 int width = pixman_image_get_width(vd->server);
2896 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2897 } else {
2898 int guest_bpp =
2899 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2900 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2901 guest_stride = pixman_image_get_stride(vd->guest.fb);
2902 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2904 line_bytes = MIN(server_stride, guest_ll);
2906 for (;;) {
2907 int x;
2908 uint8_t *guest_ptr, *server_ptr;
2909 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2910 height * VNC_DIRTY_BPL(&vd->guest),
2911 y * VNC_DIRTY_BPL(&vd->guest));
2912 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2913 /* no more dirty bits */
2914 break;
2916 y = offset / VNC_DIRTY_BPL(&vd->guest);
2917 x = offset % VNC_DIRTY_BPL(&vd->guest);
2919 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2921 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2922 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2923 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2924 } else {
2925 guest_ptr = guest_row0 + y * guest_stride;
2927 guest_ptr += x * cmp_bytes;
2929 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2930 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2931 int _cmp_bytes = cmp_bytes;
2932 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2933 continue;
2935 if ((x + 1) * cmp_bytes > line_bytes) {
2936 _cmp_bytes = line_bytes - x * cmp_bytes;
2938 assert(_cmp_bytes >= 0);
2939 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2940 continue;
2942 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2943 if (!vd->non_adaptive) {
2944 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2945 y, &tv);
2947 QTAILQ_FOREACH(vs, &vd->clients, next) {
2948 set_bit(x, vs->dirty[y]);
2950 has_dirty++;
2953 y++;
2955 qemu_pixman_image_unref(tmpbuf);
2956 return has_dirty;
2959 static void vnc_refresh(DisplayChangeListener *dcl)
2961 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2962 VncState *vs, *vn;
2963 int has_dirty, rects = 0;
2965 if (QTAILQ_EMPTY(&vd->clients)) {
2966 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2967 return;
2970 graphic_hw_update(vd->dcl.con);
2972 if (vnc_trylock_display(vd)) {
2973 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2974 return;
2977 has_dirty = vnc_refresh_server_surface(vd);
2978 vnc_unlock_display(vd);
2980 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2981 rects += vnc_update_client(vs, has_dirty, false);
2982 /* vs might be free()ed here */
2985 if (has_dirty && rects) {
2986 vd->dcl.update_interval /= 2;
2987 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2988 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2990 } else {
2991 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2992 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2993 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2998 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2999 bool skipauth, bool websocket)
3001 VncState *vs = g_new0(VncState, 1);
3002 int i;
3004 vs->sioc = sioc;
3005 object_ref(OBJECT(vs->sioc));
3006 vs->ioc = QIO_CHANNEL(sioc);
3007 object_ref(OBJECT(vs->ioc));
3008 vs->vd = vd;
3010 buffer_init(&vs->input, "vnc-input/%p", sioc);
3011 buffer_init(&vs->output, "vnc-output/%p", sioc);
3012 buffer_init(&vs->ws_input, "vnc-ws_input/%p", sioc);
3013 buffer_init(&vs->ws_output, "vnc-ws_output/%p", sioc);
3014 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
3016 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
3017 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
3018 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
3019 #ifdef CONFIG_VNC_JPEG
3020 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
3021 #endif
3022 #ifdef CONFIG_VNC_PNG
3023 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
3024 #endif
3025 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3026 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
3027 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
3028 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
3030 if (skipauth) {
3031 vs->auth = VNC_AUTH_NONE;
3032 vs->subauth = VNC_AUTH_INVALID;
3033 } else {
3034 if (websocket) {
3035 vs->auth = vd->ws_auth;
3036 vs->subauth = VNC_AUTH_INVALID;
3037 } else {
3038 vs->auth = vd->auth;
3039 vs->subauth = vd->subauth;
3042 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3043 sioc, websocket, vs->auth, vs->subauth);
3045 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3046 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3047 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3050 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3051 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3052 qio_channel_set_blocking(vs->ioc, false, NULL);
3053 if (websocket) {
3054 vs->websocket = 1;
3055 if (vd->ws_tls) {
3056 vs->ioc_tag = qio_channel_add_watch(
3057 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3058 } else {
3059 vs->ioc_tag = qio_channel_add_watch(
3060 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
3062 } else {
3063 vs->ioc_tag = qio_channel_add_watch(
3064 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
3067 vnc_client_cache_addr(vs);
3068 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3069 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3071 if (!vs->websocket) {
3072 vnc_init_state(vs);
3075 if (vd->num_connecting > vd->connections_limit) {
3076 QTAILQ_FOREACH(vs, &vd->clients, next) {
3077 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3078 vnc_disconnect_start(vs);
3079 return;
3085 void vnc_init_state(VncState *vs)
3087 vs->initialized = true;
3088 VncDisplay *vd = vs->vd;
3089 bool first_client = QTAILQ_EMPTY(&vd->clients);
3091 vs->last_x = -1;
3092 vs->last_y = -1;
3094 vs->as.freq = 44100;
3095 vs->as.nchannels = 2;
3096 vs->as.fmt = AUD_FMT_S16;
3097 vs->as.endianness = 0;
3099 qemu_mutex_init(&vs->output_mutex);
3100 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3102 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3103 if (first_client) {
3104 vnc_update_server_surface(vd);
3107 graphic_hw_update(vd->dcl.con);
3109 vnc_write(vs, "RFB 003.008\n", 12);
3110 vnc_flush(vs);
3111 vnc_read_when(vs, protocol_version, 12);
3112 reset_keys(vs);
3113 if (vs->vd->lock_key_sync)
3114 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3116 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3117 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3119 /* vs might be free()ed here */
3122 static gboolean vnc_listen_io(QIOChannel *ioc,
3123 GIOCondition condition,
3124 void *opaque)
3126 VncDisplay *vs = opaque;
3127 QIOChannelSocket *sioc = NULL;
3128 Error *err = NULL;
3130 /* Catch-up */
3131 graphic_hw_update(vs->dcl.con);
3132 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3133 if (sioc != NULL) {
3134 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3135 vnc_connect(vs, sioc, false,
3136 ioc != QIO_CHANNEL(vs->lsock));
3137 object_unref(OBJECT(sioc));
3138 } else {
3139 /* client probably closed connection before we got there */
3140 error_free(err);
3143 return TRUE;
3146 static const DisplayChangeListenerOps dcl_ops = {
3147 .dpy_name = "vnc",
3148 .dpy_refresh = vnc_refresh,
3149 .dpy_gfx_copy = vnc_dpy_copy,
3150 .dpy_gfx_update = vnc_dpy_update,
3151 .dpy_gfx_switch = vnc_dpy_switch,
3152 .dpy_gfx_check_format = qemu_pixman_check_format,
3153 .dpy_mouse_set = vnc_mouse_set,
3154 .dpy_cursor_define = vnc_dpy_cursor_define,
3157 void vnc_display_init(const char *id)
3159 VncDisplay *vs;
3161 if (vnc_display_find(id) != NULL) {
3162 return;
3164 vs = g_malloc0(sizeof(*vs));
3166 vs->id = strdup(id);
3167 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3169 QTAILQ_INIT(&vs->clients);
3170 vs->expires = TIME_MAX;
3172 if (keyboard_layout) {
3173 trace_vnc_key_map_init(keyboard_layout);
3174 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3175 } else {
3176 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3179 if (!vs->kbd_layout)
3180 exit(1);
3182 qemu_mutex_init(&vs->mutex);
3183 vnc_start_worker_thread();
3185 vs->dcl.ops = &dcl_ops;
3186 register_displaychangelistener(&vs->dcl);
3190 static void vnc_display_close(VncDisplay *vs)
3192 if (!vs)
3193 return;
3194 vs->enabled = false;
3195 vs->is_unix = false;
3196 if (vs->lsock != NULL) {
3197 if (vs->lsock_tag) {
3198 g_source_remove(vs->lsock_tag);
3200 object_unref(OBJECT(vs->lsock));
3201 vs->lsock = NULL;
3203 vs->ws_enabled = false;
3204 if (vs->lwebsock != NULL) {
3205 if (vs->lwebsock_tag) {
3206 g_source_remove(vs->lwebsock_tag);
3208 object_unref(OBJECT(vs->lwebsock));
3209 vs->lwebsock = NULL;
3211 vs->auth = VNC_AUTH_INVALID;
3212 vs->subauth = VNC_AUTH_INVALID;
3213 if (vs->tlscreds) {
3214 object_unparent(OBJECT(vs->tlscreds));
3216 g_free(vs->tlsaclname);
3217 vs->tlsaclname = NULL;
3220 int vnc_display_password(const char *id, const char *password)
3222 VncDisplay *vs = vnc_display_find(id);
3224 if (!vs) {
3225 return -EINVAL;
3227 if (vs->auth == VNC_AUTH_NONE) {
3228 error_printf_unless_qmp("If you want use passwords please enable "
3229 "password auth using '-vnc ${dpy},password'.");
3230 return -EINVAL;
3233 g_free(vs->password);
3234 vs->password = g_strdup(password);
3236 return 0;
3239 int vnc_display_pw_expire(const char *id, time_t expires)
3241 VncDisplay *vs = vnc_display_find(id);
3243 if (!vs) {
3244 return -EINVAL;
3247 vs->expires = expires;
3248 return 0;
3251 char *vnc_display_local_addr(const char *id)
3253 VncDisplay *vs = vnc_display_find(id);
3254 SocketAddress *addr;
3255 char *ret;
3256 Error *err = NULL;
3258 assert(vs);
3260 addr = qio_channel_socket_get_local_address(vs->lsock, &err);
3261 if (!addr) {
3262 return NULL;
3265 if (addr->type != SOCKET_ADDRESS_KIND_INET) {
3266 qapi_free_SocketAddress(addr);
3267 return NULL;
3269 ret = g_strdup_printf("%s;%s", addr->u.inet->host, addr->u.inet->port);
3270 qapi_free_SocketAddress(addr);
3272 return ret;
3275 static QemuOptsList qemu_vnc_opts = {
3276 .name = "vnc",
3277 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3278 .implied_opt_name = "vnc",
3279 .desc = {
3281 .name = "vnc",
3282 .type = QEMU_OPT_STRING,
3284 .name = "websocket",
3285 .type = QEMU_OPT_STRING,
3287 .name = "tls-creds",
3288 .type = QEMU_OPT_STRING,
3290 /* Deprecated in favour of tls-creds */
3291 .name = "x509",
3292 .type = QEMU_OPT_STRING,
3294 .name = "share",
3295 .type = QEMU_OPT_STRING,
3297 .name = "display",
3298 .type = QEMU_OPT_STRING,
3300 .name = "head",
3301 .type = QEMU_OPT_NUMBER,
3303 .name = "connections",
3304 .type = QEMU_OPT_NUMBER,
3306 .name = "to",
3307 .type = QEMU_OPT_NUMBER,
3309 .name = "ipv4",
3310 .type = QEMU_OPT_BOOL,
3312 .name = "ipv6",
3313 .type = QEMU_OPT_BOOL,
3315 .name = "password",
3316 .type = QEMU_OPT_BOOL,
3318 .name = "reverse",
3319 .type = QEMU_OPT_BOOL,
3321 .name = "lock-key-sync",
3322 .type = QEMU_OPT_BOOL,
3324 .name = "sasl",
3325 .type = QEMU_OPT_BOOL,
3327 /* Deprecated in favour of tls-creds */
3328 .name = "tls",
3329 .type = QEMU_OPT_BOOL,
3331 /* Deprecated in favour of tls-creds */
3332 .name = "x509verify",
3333 .type = QEMU_OPT_STRING,
3335 .name = "acl",
3336 .type = QEMU_OPT_BOOL,
3338 .name = "lossy",
3339 .type = QEMU_OPT_BOOL,
3341 .name = "non-adaptive",
3342 .type = QEMU_OPT_BOOL,
3344 { /* end of list */ }
3349 static int
3350 vnc_display_setup_auth(VncDisplay *vs,
3351 bool password,
3352 bool sasl,
3353 bool websocket,
3354 Error **errp)
3357 * We have a choice of 3 authentication options
3359 * 1. none
3360 * 2. vnc
3361 * 3. sasl
3363 * The channel can be run in 2 modes
3365 * 1. clear
3366 * 2. tls
3368 * And TLS can use 2 types of credentials
3370 * 1. anon
3371 * 2. x509
3373 * We thus have 9 possible logical combinations
3375 * 1. clear + none
3376 * 2. clear + vnc
3377 * 3. clear + sasl
3378 * 4. tls + anon + none
3379 * 5. tls + anon + vnc
3380 * 6. tls + anon + sasl
3381 * 7. tls + x509 + none
3382 * 8. tls + x509 + vnc
3383 * 9. tls + x509 + sasl
3385 * These need to be mapped into the VNC auth schemes
3386 * in an appropriate manner. In regular VNC, all the
3387 * TLS options get mapped into VNC_AUTH_VENCRYPT
3388 * sub-auth types.
3390 * In websockets, the https:// protocol already provides
3391 * TLS support, so there is no need to make use of the
3392 * VeNCrypt extension. Furthermore, websockets browser
3393 * clients could not use VeNCrypt even if they wanted to,
3394 * as they cannot control when the TLS handshake takes
3395 * place. Thus there is no option but to rely on https://,
3396 * meaning combinations 4->6 and 7->9 will be mapped to
3397 * VNC auth schemes in the same way as combos 1->3.
3399 * Regardless of fact that we have a different mapping to
3400 * VNC auth mechs for plain VNC vs websockets VNC, the end
3401 * result has the same security characteristics.
3403 if (password) {
3404 if (vs->tlscreds) {
3405 vs->auth = VNC_AUTH_VENCRYPT;
3406 if (websocket) {
3407 vs->ws_tls = true;
3409 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3410 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3411 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3412 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3413 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3414 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3415 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3416 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3417 } else {
3418 error_setg(errp,
3419 "Unsupported TLS cred type %s",
3420 object_get_typename(OBJECT(vs->tlscreds)));
3421 return -1;
3423 } else {
3424 VNC_DEBUG("Initializing VNC server with password auth\n");
3425 vs->auth = VNC_AUTH_VNC;
3426 vs->subauth = VNC_AUTH_INVALID;
3428 if (websocket) {
3429 vs->ws_auth = VNC_AUTH_VNC;
3430 } else {
3431 vs->ws_auth = VNC_AUTH_INVALID;
3433 } else if (sasl) {
3434 if (vs->tlscreds) {
3435 vs->auth = VNC_AUTH_VENCRYPT;
3436 if (websocket) {
3437 vs->ws_tls = true;
3439 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3440 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3441 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3442 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3443 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3444 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3445 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3446 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3447 } else {
3448 error_setg(errp,
3449 "Unsupported TLS cred type %s",
3450 object_get_typename(OBJECT(vs->tlscreds)));
3451 return -1;
3453 } else {
3454 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3455 vs->auth = VNC_AUTH_SASL;
3456 vs->subauth = VNC_AUTH_INVALID;
3458 if (websocket) {
3459 vs->ws_auth = VNC_AUTH_SASL;
3460 } else {
3461 vs->ws_auth = VNC_AUTH_INVALID;
3463 } else {
3464 if (vs->tlscreds) {
3465 vs->auth = VNC_AUTH_VENCRYPT;
3466 if (websocket) {
3467 vs->ws_tls = true;
3469 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3470 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3471 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3472 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3473 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3474 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3475 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3476 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3477 } else {
3478 error_setg(errp,
3479 "Unsupported TLS cred type %s",
3480 object_get_typename(OBJECT(vs->tlscreds)));
3481 return -1;
3483 } else {
3484 VNC_DEBUG("Initializing VNC server with no auth\n");
3485 vs->auth = VNC_AUTH_NONE;
3486 vs->subauth = VNC_AUTH_INVALID;
3488 if (websocket) {
3489 vs->ws_auth = VNC_AUTH_NONE;
3490 } else {
3491 vs->ws_auth = VNC_AUTH_INVALID;
3494 return 0;
3499 * Handle back compat with old CLI syntax by creating some
3500 * suitable QCryptoTLSCreds objects
3502 static QCryptoTLSCreds *
3503 vnc_display_create_creds(bool x509,
3504 bool x509verify,
3505 const char *dir,
3506 const char *id,
3507 Error **errp)
3509 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3510 Object *parent = object_get_objects_root();
3511 Object *creds;
3512 Error *err = NULL;
3514 if (x509) {
3515 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3516 parent,
3517 credsid,
3518 &err,
3519 "endpoint", "server",
3520 "dir", dir,
3521 "verify-peer", x509verify ? "yes" : "no",
3522 NULL);
3523 } else {
3524 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3525 parent,
3526 credsid,
3527 &err,
3528 "endpoint", "server",
3529 NULL);
3532 g_free(credsid);
3534 if (err) {
3535 error_propagate(errp, err);
3536 return NULL;
3539 return QCRYPTO_TLS_CREDS(creds);
3543 void vnc_display_open(const char *id, Error **errp)
3545 VncDisplay *vs = vnc_display_find(id);
3546 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3547 SocketAddress *saddr = NULL, *wsaddr = NULL;
3548 const char *share, *device_id;
3549 QemuConsole *con;
3550 bool password = false;
3551 bool reverse = false;
3552 const char *vnc;
3553 char *h;
3554 const char *credid;
3555 bool sasl = false;
3556 #ifdef CONFIG_VNC_SASL
3557 int saslErr;
3558 #endif
3559 int acl = 0;
3560 int lock_key_sync = 1;
3562 if (!vs) {
3563 error_setg(errp, "VNC display not active");
3564 return;
3566 vnc_display_close(vs);
3568 if (!opts) {
3569 return;
3571 vnc = qemu_opt_get(opts, "vnc");
3572 if (!vnc || strcmp(vnc, "none") == 0) {
3573 return;
3576 h = strrchr(vnc, ':');
3577 if (h) {
3578 size_t hlen = h - vnc;
3580 const char *websocket = qemu_opt_get(opts, "websocket");
3581 int to = qemu_opt_get_number(opts, "to", 0);
3582 bool has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3583 bool has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3585 saddr = g_new0(SocketAddress, 1);
3586 if (websocket) {
3587 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3588 error_setg(errp,
3589 "SHA1 hash support is required for websockets");
3590 goto fail;
3593 wsaddr = g_new0(SocketAddress, 1);
3594 vs->ws_enabled = true;
3597 if (strncmp(vnc, "unix:", 5) == 0) {
3598 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3599 saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
3600 saddr->u.q_unix->path = g_strdup(vnc + 5);
3602 if (vs->ws_enabled) {
3603 error_setg(errp, "UNIX sockets not supported with websock");
3604 goto fail;
3606 } else {
3607 unsigned long long baseport;
3608 saddr->type = SOCKET_ADDRESS_KIND_INET;
3609 saddr->u.inet = g_new0(InetSocketAddress, 1);
3610 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3611 saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2);
3612 } else {
3613 saddr->u.inet->host = g_strndup(vnc, hlen);
3615 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3616 error_setg(errp, "can't convert to a number: %s", h + 1);
3617 goto fail;
3619 if (baseport > 65535 ||
3620 baseport + 5900 > 65535) {
3621 error_setg(errp, "port %s out of range", h + 1);
3622 goto fail;
3624 saddr->u.inet->port = g_strdup_printf(
3625 "%d", (int)baseport + 5900);
3627 if (to) {
3628 saddr->u.inet->has_to = true;
3629 saddr->u.inet->to = to + 5900;
3631 saddr->u.inet->ipv4 = saddr->u.inet->has_ipv4 = has_ipv4;
3632 saddr->u.inet->ipv6 = saddr->u.inet->has_ipv6 = has_ipv6;
3634 if (vs->ws_enabled) {
3635 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3636 wsaddr->u.inet = g_new0(InetSocketAddress, 1);
3637 wsaddr->u.inet->host = g_strdup(saddr->u.inet->host);
3638 wsaddr->u.inet->port = g_strdup(websocket);
3640 if (to) {
3641 wsaddr->u.inet->has_to = true;
3642 wsaddr->u.inet->to = to;
3644 wsaddr->u.inet->ipv4 = wsaddr->u.inet->has_ipv4 = has_ipv4;
3645 wsaddr->u.inet->ipv6 = wsaddr->u.inet->has_ipv6 = has_ipv6;
3648 } else {
3649 error_setg(errp, "no vnc port specified");
3650 goto fail;
3653 password = qemu_opt_get_bool(opts, "password", false);
3654 if (password) {
3655 if (fips_get_state()) {
3656 error_setg(errp,
3657 "VNC password auth disabled due to FIPS mode, "
3658 "consider using the VeNCrypt or SASL authentication "
3659 "methods as an alternative");
3660 goto fail;
3662 if (!qcrypto_cipher_supports(
3663 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3664 error_setg(errp,
3665 "Cipher backend does not support DES RFB algorithm");
3666 goto fail;
3670 reverse = qemu_opt_get_bool(opts, "reverse", false);
3671 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3672 sasl = qemu_opt_get_bool(opts, "sasl", false);
3673 #ifndef CONFIG_VNC_SASL
3674 if (sasl) {
3675 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3676 goto fail;
3678 #endif /* CONFIG_VNC_SASL */
3679 credid = qemu_opt_get(opts, "tls-creds");
3680 if (credid) {
3681 Object *creds;
3682 if (qemu_opt_get(opts, "tls") ||
3683 qemu_opt_get(opts, "x509") ||
3684 qemu_opt_get(opts, "x509verify")) {
3685 error_setg(errp,
3686 "'credid' parameter is mutually exclusive with "
3687 "'tls', 'x509' and 'x509verify' parameters");
3688 goto fail;
3691 creds = object_resolve_path_component(
3692 object_get_objects_root(), credid);
3693 if (!creds) {
3694 error_setg(errp, "No TLS credentials with id '%s'",
3695 credid);
3696 goto fail;
3698 vs->tlscreds = (QCryptoTLSCreds *)
3699 object_dynamic_cast(creds,
3700 TYPE_QCRYPTO_TLS_CREDS);
3701 if (!vs->tlscreds) {
3702 error_setg(errp, "Object with id '%s' is not TLS credentials",
3703 credid);
3704 goto fail;
3706 object_ref(OBJECT(vs->tlscreds));
3708 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3709 error_setg(errp,
3710 "Expecting TLS credentials with a server endpoint");
3711 goto fail;
3713 } else {
3714 const char *path;
3715 bool tls = false, x509 = false, x509verify = false;
3716 tls = qemu_opt_get_bool(opts, "tls", false);
3717 if (tls) {
3718 path = qemu_opt_get(opts, "x509");
3720 if (path) {
3721 x509 = true;
3722 } else {
3723 path = qemu_opt_get(opts, "x509verify");
3724 if (path) {
3725 x509 = true;
3726 x509verify = true;
3729 vs->tlscreds = vnc_display_create_creds(x509,
3730 x509verify,
3731 path,
3732 vs->id,
3733 errp);
3734 if (!vs->tlscreds) {
3735 goto fail;
3739 acl = qemu_opt_get_bool(opts, "acl", false);
3741 share = qemu_opt_get(opts, "share");
3742 if (share) {
3743 if (strcmp(share, "ignore") == 0) {
3744 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3745 } else if (strcmp(share, "allow-exclusive") == 0) {
3746 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3747 } else if (strcmp(share, "force-shared") == 0) {
3748 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3749 } else {
3750 error_setg(errp, "unknown vnc share= option");
3751 goto fail;
3753 } else {
3754 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3756 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3758 #ifdef CONFIG_VNC_JPEG
3759 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3760 #endif
3761 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3762 /* adaptive updates are only used with tight encoding and
3763 * if lossy updates are enabled so we can disable all the
3764 * calculations otherwise */
3765 if (!vs->lossy) {
3766 vs->non_adaptive = true;
3769 if (acl) {
3770 if (strcmp(vs->id, "default") == 0) {
3771 vs->tlsaclname = g_strdup("vnc.x509dname");
3772 } else {
3773 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3775 qemu_acl_init(vs->tlsaclname);
3777 #ifdef CONFIG_VNC_SASL
3778 if (acl && sasl) {
3779 char *aclname;
3781 if (strcmp(vs->id, "default") == 0) {
3782 aclname = g_strdup("vnc.username");
3783 } else {
3784 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3786 vs->sasl.acl = qemu_acl_init(aclname);
3787 g_free(aclname);
3789 #endif
3791 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3792 goto fail;
3795 #ifdef CONFIG_VNC_SASL
3796 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3797 error_setg(errp, "Failed to initialize SASL auth: %s",
3798 sasl_errstring(saslErr, NULL, NULL));
3799 goto fail;
3801 #endif
3802 vs->lock_key_sync = lock_key_sync;
3804 device_id = qemu_opt_get(opts, "display");
3805 if (device_id) {
3806 DeviceState *dev;
3807 int head = qemu_opt_get_number(opts, "head", 0);
3809 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3810 if (dev == NULL) {
3811 error_setg(errp, "Device '%s' not found", device_id);
3812 goto fail;
3815 con = qemu_console_lookup_by_device(dev, head);
3816 if (con == NULL) {
3817 error_setg(errp, "Device %s is not bound to a QemuConsole",
3818 device_id);
3819 goto fail;
3821 } else {
3822 con = NULL;
3825 if (con != vs->dcl.con) {
3826 unregister_displaychangelistener(&vs->dcl);
3827 vs->dcl.con = con;
3828 register_displaychangelistener(&vs->dcl);
3831 if (reverse) {
3832 /* connect to viewer */
3833 QIOChannelSocket *sioc = NULL;
3834 vs->lsock = NULL;
3835 vs->lwebsock = NULL;
3836 if (vs->ws_enabled) {
3837 error_setg(errp, "Cannot use websockets in reverse mode");
3838 goto fail;
3840 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3841 sioc = qio_channel_socket_new();
3842 if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
3843 goto fail;
3845 vnc_connect(vs, sioc, false, false);
3846 object_unref(OBJECT(sioc));
3847 } else {
3848 vs->lsock = qio_channel_socket_new();
3849 if (qio_channel_socket_listen_sync(vs->lsock, saddr, errp) < 0) {
3850 goto fail;
3852 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3853 vs->enabled = true;
3855 if (vs->ws_enabled) {
3856 vs->lwebsock = qio_channel_socket_new();
3857 if (qio_channel_socket_listen_sync(vs->lwebsock,
3858 wsaddr, errp) < 0) {
3859 object_unref(OBJECT(vs->lsock));
3860 vs->lsock = NULL;
3861 goto fail;
3865 vs->lsock_tag = qio_channel_add_watch(
3866 QIO_CHANNEL(vs->lsock),
3867 G_IO_IN, vnc_listen_io, vs, NULL);
3868 if (vs->ws_enabled) {
3869 vs->lwebsock_tag = qio_channel_add_watch(
3870 QIO_CHANNEL(vs->lwebsock),
3871 G_IO_IN, vnc_listen_io, vs, NULL);
3875 qapi_free_SocketAddress(saddr);
3876 qapi_free_SocketAddress(wsaddr);
3877 return;
3879 fail:
3880 qapi_free_SocketAddress(saddr);
3881 qapi_free_SocketAddress(wsaddr);
3882 vs->enabled = false;
3883 vs->ws_enabled = false;
3886 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3888 VncDisplay *vs = vnc_display_find(id);
3889 QIOChannelSocket *sioc;
3891 if (!vs) {
3892 return;
3895 sioc = qio_channel_socket_new_fd(csock, NULL);
3896 if (sioc) {
3897 vnc_connect(vs, sioc, skipauth, false);
3898 object_unref(OBJECT(sioc));
3902 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3904 int i = 2;
3905 char *id;
3907 id = g_strdup("default");
3908 while (qemu_opts_find(olist, id)) {
3909 g_free(id);
3910 id = g_strdup_printf("vnc%d", i++);
3912 qemu_opts_set_id(opts, id);
3915 QemuOpts *vnc_parse(const char *str, Error **errp)
3917 QemuOptsList *olist = qemu_find_opts("vnc");
3918 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3919 const char *id;
3921 if (!opts) {
3922 return NULL;
3925 id = qemu_opts_id(opts);
3926 if (!id) {
3927 /* auto-assign id if not present */
3928 vnc_auto_assign_id(olist, opts);
3930 return opts;
3933 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3935 Error *local_err = NULL;
3936 char *id = (char *)qemu_opts_id(opts);
3938 assert(id);
3939 vnc_display_init(id);
3940 vnc_display_open(id, &local_err);
3941 if (local_err != NULL) {
3942 error_report("Failed to start VNC server: %s",
3943 error_get_pretty(local_err));
3944 error_free(local_err);
3945 exit(1);
3947 return 0;
3950 static void vnc_register_config(void)
3952 qemu_add_opts(&qemu_vnc_opts);
3954 machine_init(vnc_register_config);