ui: fix reporting of VNC auth in query-vnc-servers
[qemu/kevin.git] / ui / vnc.c
blobd0a08a780f12a0ea9966b58d7d7882d30e93303b
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "vnc.h"
29 #include "vnc-jobs.h"
30 #include "trace.h"
31 #include "hw/qdev.h"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
36 #include "qemu/acl.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
59 QTAILQ_HEAD_INITIALIZER(vnc_displays);
61 static int vnc_cursor_define(VncState *vs);
62 static void vnc_release_modifiers(VncState *vs);
64 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
66 #ifdef _VNC_DEBUG
67 static const char *mn[] = {
68 [0] = "undefined",
69 [VNC_SHARE_MODE_CONNECTING] = "connecting",
70 [VNC_SHARE_MODE_SHARED] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
74 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
75 vs->ioc, mn[vs->share_mode], mn[mode]);
76 #endif
78 switch (vs->share_mode) {
79 case VNC_SHARE_MODE_CONNECTING:
80 vs->vd->num_connecting--;
81 break;
82 case VNC_SHARE_MODE_SHARED:
83 vs->vd->num_shared--;
84 break;
85 case VNC_SHARE_MODE_EXCLUSIVE:
86 vs->vd->num_exclusive--;
87 break;
88 default:
89 break;
92 vs->share_mode = mode;
94 switch (vs->share_mode) {
95 case VNC_SHARE_MODE_CONNECTING:
96 vs->vd->num_connecting++;
97 break;
98 case VNC_SHARE_MODE_SHARED:
99 vs->vd->num_shared++;
100 break;
101 case VNC_SHARE_MODE_EXCLUSIVE:
102 vs->vd->num_exclusive++;
103 break;
104 default:
105 break;
110 static void vnc_init_basic_info(SocketAddress *addr,
111 VncBasicInfo *info,
112 Error **errp)
114 switch (addr->type) {
115 case SOCKET_ADDRESS_KIND_INET:
116 info->host = g_strdup(addr->u.inet.data->host);
117 info->service = g_strdup(addr->u.inet.data->port);
118 if (addr->u.inet.data->ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_KIND_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.data->path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 default:
132 error_setg(errp, "Unsupported socket kind %d",
133 addr->type);
134 break;
137 return;
140 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
141 VncBasicInfo *info,
142 Error **errp)
144 SocketAddress *addr = NULL;
146 if (!ioc) {
147 error_setg(errp, "No listener socket available");
148 return;
151 addr = qio_channel_socket_get_local_address(ioc, errp);
152 if (!addr) {
153 return;
156 vnc_init_basic_info(addr, info, errp);
157 qapi_free_SocketAddress(addr);
160 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
161 VncBasicInfo *info,
162 Error **errp)
164 SocketAddress *addr = NULL;
166 addr = qio_channel_socket_get_remote_address(ioc, errp);
167 if (!addr) {
168 return;
171 vnc_init_basic_info(addr, info, errp);
172 qapi_free_SocketAddress(addr);
175 static const char *vnc_auth_name(VncDisplay *vd) {
176 switch (vd->auth) {
177 case VNC_AUTH_INVALID:
178 return "invalid";
179 case VNC_AUTH_NONE:
180 return "none";
181 case VNC_AUTH_VNC:
182 return "vnc";
183 case VNC_AUTH_RA2:
184 return "ra2";
185 case VNC_AUTH_RA2NE:
186 return "ra2ne";
187 case VNC_AUTH_TIGHT:
188 return "tight";
189 case VNC_AUTH_ULTRA:
190 return "ultra";
191 case VNC_AUTH_TLS:
192 return "tls";
193 case VNC_AUTH_VENCRYPT:
194 switch (vd->subauth) {
195 case VNC_AUTH_VENCRYPT_PLAIN:
196 return "vencrypt+plain";
197 case VNC_AUTH_VENCRYPT_TLSNONE:
198 return "vencrypt+tls+none";
199 case VNC_AUTH_VENCRYPT_TLSVNC:
200 return "vencrypt+tls+vnc";
201 case VNC_AUTH_VENCRYPT_TLSPLAIN:
202 return "vencrypt+tls+plain";
203 case VNC_AUTH_VENCRYPT_X509NONE:
204 return "vencrypt+x509+none";
205 case VNC_AUTH_VENCRYPT_X509VNC:
206 return "vencrypt+x509+vnc";
207 case VNC_AUTH_VENCRYPT_X509PLAIN:
208 return "vencrypt+x509+plain";
209 case VNC_AUTH_VENCRYPT_TLSSASL:
210 return "vencrypt+tls+sasl";
211 case VNC_AUTH_VENCRYPT_X509SASL:
212 return "vencrypt+x509+sasl";
213 default:
214 return "vencrypt";
216 case VNC_AUTH_SASL:
217 return "sasl";
219 return "unknown";
222 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
224 VncServerInfo *info;
225 Error *err = NULL;
227 info = g_malloc0(sizeof(*info));
228 vnc_init_basic_info_from_server_addr(vd->lsock,
229 qapi_VncServerInfo_base(info), &err);
230 info->has_auth = true;
231 info->auth = g_strdup(vnc_auth_name(vd));
232 if (err) {
233 qapi_free_VncServerInfo(info);
234 info = NULL;
235 error_free(err);
237 return info;
240 static void vnc_client_cache_auth(VncState *client)
242 if (!client->info) {
243 return;
246 if (client->tls) {
247 client->info->x509_dname =
248 qcrypto_tls_session_get_peer_name(client->tls);
249 client->info->has_x509_dname =
250 client->info->x509_dname != NULL;
252 #ifdef CONFIG_VNC_SASL
253 if (client->sasl.conn &&
254 client->sasl.username) {
255 client->info->has_sasl_username = true;
256 client->info->sasl_username = g_strdup(client->sasl.username);
258 #endif
261 static void vnc_client_cache_addr(VncState *client)
263 Error *err = NULL;
265 client->info = g_malloc0(sizeof(*client->info));
266 vnc_init_basic_info_from_remote_addr(client->sioc,
267 qapi_VncClientInfo_base(client->info),
268 &err);
269 if (err) {
270 qapi_free_VncClientInfo(client->info);
271 client->info = NULL;
272 error_free(err);
276 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
278 VncServerInfo *si;
280 if (!vs->info) {
281 return;
284 si = vnc_server_info_get(vs->vd);
285 if (!si) {
286 return;
289 switch (event) {
290 case QAPI_EVENT_VNC_CONNECTED:
291 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
292 &error_abort);
293 break;
294 case QAPI_EVENT_VNC_INITIALIZED:
295 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
296 break;
297 case QAPI_EVENT_VNC_DISCONNECTED:
298 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
299 break;
300 default:
301 break;
304 qapi_free_VncServerInfo(si);
307 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
309 VncClientInfo *info;
310 Error *err = NULL;
312 info = g_malloc0(sizeof(*info));
314 vnc_init_basic_info_from_remote_addr(client->sioc,
315 qapi_VncClientInfo_base(info),
316 &err);
317 if (err) {
318 error_free(err);
319 qapi_free_VncClientInfo(info);
320 return NULL;
323 info->websocket = client->websocket;
325 if (client->tls) {
326 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
327 info->has_x509_dname = info->x509_dname != NULL;
329 #ifdef CONFIG_VNC_SASL
330 if (client->sasl.conn && client->sasl.username) {
331 info->has_sasl_username = true;
332 info->sasl_username = g_strdup(client->sasl.username);
334 #endif
336 return info;
339 static VncDisplay *vnc_display_find(const char *id)
341 VncDisplay *vd;
343 if (id == NULL) {
344 return QTAILQ_FIRST(&vnc_displays);
346 QTAILQ_FOREACH(vd, &vnc_displays, next) {
347 if (strcmp(id, vd->id) == 0) {
348 return vd;
351 return NULL;
354 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
356 VncClientInfoList *cinfo, *prev = NULL;
357 VncState *client;
359 QTAILQ_FOREACH(client, &vd->clients, next) {
360 cinfo = g_new0(VncClientInfoList, 1);
361 cinfo->value = qmp_query_vnc_client(client);
362 cinfo->next = prev;
363 prev = cinfo;
365 return prev;
368 VncInfo *qmp_query_vnc(Error **errp)
370 VncInfo *info = g_malloc0(sizeof(*info));
371 VncDisplay *vd = vnc_display_find(NULL);
372 SocketAddress *addr = NULL;
374 if (vd == NULL || !vd->lsock) {
375 info->enabled = false;
376 } else {
377 info->enabled = true;
379 /* for compatibility with the original command */
380 info->has_clients = true;
381 info->clients = qmp_query_client_list(vd);
383 if (vd->lsock == NULL) {
384 return info;
387 addr = qio_channel_socket_get_local_address(vd->lsock, errp);
388 if (!addr) {
389 goto out_error;
392 switch (addr->type) {
393 case SOCKET_ADDRESS_KIND_INET:
394 info->host = g_strdup(addr->u.inet.data->host);
395 info->service = g_strdup(addr->u.inet.data->port);
396 if (addr->u.inet.data->ipv6) {
397 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
398 } else {
399 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
401 break;
403 case SOCKET_ADDRESS_KIND_UNIX:
404 info->host = g_strdup("");
405 info->service = g_strdup(addr->u.q_unix.data->path);
406 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
407 break;
409 default:
410 error_setg(errp, "Unsupported socket kind %d",
411 addr->type);
412 goto out_error;
415 info->has_host = true;
416 info->has_service = true;
417 info->has_family = true;
419 info->has_auth = true;
420 info->auth = g_strdup(vnc_auth_name(vd));
423 qapi_free_SocketAddress(addr);
424 return info;
426 out_error:
427 qapi_free_SocketAddress(addr);
428 qapi_free_VncInfo(info);
429 return NULL;
433 static void qmp_query_auth(int auth, int subauth,
434 VncPrimaryAuth *qmp_auth,
435 VncVencryptSubAuth *qmp_vencrypt,
436 bool *qmp_has_vencrypt);
438 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
439 bool websocket,
440 int auth,
441 int subauth,
442 VncServerInfo2List *prev)
444 VncServerInfo2List *list;
445 VncServerInfo2 *info;
446 Error *err = NULL;
447 SocketAddress *addr;
449 addr = qio_channel_socket_get_local_address(ioc, &err);
450 if (!addr) {
451 error_free(err);
452 return prev;
455 info = g_new0(VncServerInfo2, 1);
456 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
457 qapi_free_SocketAddress(addr);
458 if (err) {
459 qapi_free_VncServerInfo2(info);
460 error_free(err);
461 return prev;
463 info->websocket = websocket;
465 qmp_query_auth(auth, subauth, &info->auth,
466 &info->vencrypt, &info->has_vencrypt);
468 list = g_new0(VncServerInfo2List, 1);
469 list->value = info;
470 list->next = prev;
471 return list;
474 static void qmp_query_auth(int auth, int subauth,
475 VncPrimaryAuth *qmp_auth,
476 VncVencryptSubAuth *qmp_vencrypt,
477 bool *qmp_has_vencrypt)
479 switch (auth) {
480 case VNC_AUTH_VNC:
481 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
482 break;
483 case VNC_AUTH_RA2:
484 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
485 break;
486 case VNC_AUTH_RA2NE:
487 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
488 break;
489 case VNC_AUTH_TIGHT:
490 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
491 break;
492 case VNC_AUTH_ULTRA:
493 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
494 break;
495 case VNC_AUTH_TLS:
496 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
497 break;
498 case VNC_AUTH_VENCRYPT:
499 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
500 *qmp_has_vencrypt = true;
501 switch (subauth) {
502 case VNC_AUTH_VENCRYPT_PLAIN:
503 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
504 break;
505 case VNC_AUTH_VENCRYPT_TLSNONE:
506 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
507 break;
508 case VNC_AUTH_VENCRYPT_TLSVNC:
509 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
510 break;
511 case VNC_AUTH_VENCRYPT_TLSPLAIN:
512 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
513 break;
514 case VNC_AUTH_VENCRYPT_X509NONE:
515 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
516 break;
517 case VNC_AUTH_VENCRYPT_X509VNC:
518 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
519 break;
520 case VNC_AUTH_VENCRYPT_X509PLAIN:
521 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
522 break;
523 case VNC_AUTH_VENCRYPT_TLSSASL:
524 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
525 break;
526 case VNC_AUTH_VENCRYPT_X509SASL:
527 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
528 break;
529 default:
530 *qmp_has_vencrypt = false;
531 break;
533 break;
534 case VNC_AUTH_SASL:
535 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
536 break;
537 case VNC_AUTH_NONE:
538 default:
539 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
540 break;
544 VncInfo2List *qmp_query_vnc_servers(Error **errp)
546 VncInfo2List *item, *prev = NULL;
547 VncInfo2 *info;
548 VncDisplay *vd;
549 DeviceState *dev;
551 QTAILQ_FOREACH(vd, &vnc_displays, next) {
552 info = g_new0(VncInfo2, 1);
553 info->id = g_strdup(vd->id);
554 info->clients = qmp_query_client_list(vd);
555 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
556 &info->vencrypt, &info->has_vencrypt);
557 if (vd->dcl.con) {
558 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
559 "device", NULL));
560 info->has_display = true;
561 info->display = g_strdup(dev->id);
563 if (vd->lsock != NULL) {
564 info->server = qmp_query_server_entry(
565 vd->lsock, false, vd->auth, vd->subauth, info->server);
567 if (vd->lwebsock != NULL) {
568 info->server = qmp_query_server_entry(
569 vd->lwebsock, true, vd->ws_auth, vd->ws_subauth, info->server);
572 item = g_new0(VncInfo2List, 1);
573 item->value = info;
574 item->next = prev;
575 prev = item;
577 return prev;
580 /* TODO
581 1) Get the queue working for IO.
582 2) there is some weirdness when using the -S option (the screen is grey
583 and not totally invalidated
584 3) resolutions > 1024
587 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
588 static void vnc_disconnect_start(VncState *vs);
590 static void vnc_colordepth(VncState *vs);
591 static void framebuffer_update_request(VncState *vs, int incremental,
592 int x_position, int y_position,
593 int w, int h);
594 static void vnc_refresh(DisplayChangeListener *dcl);
595 static int vnc_refresh_server_surface(VncDisplay *vd);
597 static int vnc_width(VncDisplay *vd)
599 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
600 VNC_DIRTY_PIXELS_PER_BIT));
603 static int vnc_height(VncDisplay *vd)
605 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
608 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
609 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
610 VncDisplay *vd,
611 int x, int y, int w, int h)
613 int width = vnc_width(vd);
614 int height = vnc_height(vd);
616 /* this is needed this to ensure we updated all affected
617 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
618 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
619 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
621 x = MIN(x, width);
622 y = MIN(y, height);
623 w = MIN(x + w, width) - x;
624 h = MIN(y + h, height);
626 for (; y < h; y++) {
627 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
628 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
632 static void vnc_dpy_update(DisplayChangeListener *dcl,
633 int x, int y, int w, int h)
635 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
636 struct VncSurface *s = &vd->guest;
638 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
641 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
642 int32_t encoding)
644 vnc_write_u16(vs, x);
645 vnc_write_u16(vs, y);
646 vnc_write_u16(vs, w);
647 vnc_write_u16(vs, h);
649 vnc_write_s32(vs, encoding);
653 static void vnc_desktop_resize(VncState *vs)
655 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
656 return;
658 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
659 vs->client_height == pixman_image_get_height(vs->vd->server)) {
660 return;
662 vs->client_width = pixman_image_get_width(vs->vd->server);
663 vs->client_height = pixman_image_get_height(vs->vd->server);
664 vnc_lock_output(vs);
665 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
666 vnc_write_u8(vs, 0);
667 vnc_write_u16(vs, 1); /* number of rects */
668 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
669 VNC_ENCODING_DESKTOPRESIZE);
670 vnc_unlock_output(vs);
671 vnc_flush(vs);
674 static void vnc_abort_display_jobs(VncDisplay *vd)
676 VncState *vs;
678 QTAILQ_FOREACH(vs, &vd->clients, next) {
679 vnc_lock_output(vs);
680 vs->abort = true;
681 vnc_unlock_output(vs);
683 QTAILQ_FOREACH(vs, &vd->clients, next) {
684 vnc_jobs_join(vs);
686 QTAILQ_FOREACH(vs, &vd->clients, next) {
687 vnc_lock_output(vs);
688 vs->abort = false;
689 vnc_unlock_output(vs);
693 int vnc_server_fb_stride(VncDisplay *vd)
695 return pixman_image_get_stride(vd->server);
698 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
700 uint8_t *ptr;
702 ptr = (uint8_t *)pixman_image_get_data(vd->server);
703 ptr += y * vnc_server_fb_stride(vd);
704 ptr += x * VNC_SERVER_FB_BYTES;
705 return ptr;
708 static void vnc_update_server_surface(VncDisplay *vd)
710 int width, height;
712 qemu_pixman_image_unref(vd->server);
713 vd->server = NULL;
715 if (QTAILQ_EMPTY(&vd->clients)) {
716 return;
719 width = vnc_width(vd);
720 height = vnc_height(vd);
721 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
722 width, height,
723 NULL, 0);
725 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
726 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
727 width, height);
730 static void vnc_dpy_switch(DisplayChangeListener *dcl,
731 DisplaySurface *surface)
733 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
734 VncState *vs;
736 vnc_abort_display_jobs(vd);
737 vd->ds = surface;
739 /* server surface */
740 vnc_update_server_surface(vd);
742 /* guest surface */
743 qemu_pixman_image_unref(vd->guest.fb);
744 vd->guest.fb = pixman_image_ref(surface->image);
745 vd->guest.format = surface->format;
747 QTAILQ_FOREACH(vs, &vd->clients, next) {
748 vnc_colordepth(vs);
749 vnc_desktop_resize(vs);
750 if (vs->vd->cursor) {
751 vnc_cursor_define(vs);
753 memset(vs->dirty, 0x00, sizeof(vs->dirty));
754 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
755 vnc_width(vd),
756 vnc_height(vd));
760 /* fastest code */
761 static void vnc_write_pixels_copy(VncState *vs,
762 void *pixels, int size)
764 vnc_write(vs, pixels, size);
767 /* slowest but generic code. */
768 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
770 uint8_t r, g, b;
772 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
773 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
774 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
775 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
776 #else
777 # error need some bits here if you change VNC_SERVER_FB_FORMAT
778 #endif
779 v = (r << vs->client_pf.rshift) |
780 (g << vs->client_pf.gshift) |
781 (b << vs->client_pf.bshift);
782 switch (vs->client_pf.bytes_per_pixel) {
783 case 1:
784 buf[0] = v;
785 break;
786 case 2:
787 if (vs->client_be) {
788 buf[0] = v >> 8;
789 buf[1] = v;
790 } else {
791 buf[1] = v >> 8;
792 buf[0] = v;
794 break;
795 default:
796 case 4:
797 if (vs->client_be) {
798 buf[0] = v >> 24;
799 buf[1] = v >> 16;
800 buf[2] = v >> 8;
801 buf[3] = v;
802 } else {
803 buf[3] = v >> 24;
804 buf[2] = v >> 16;
805 buf[1] = v >> 8;
806 buf[0] = v;
808 break;
812 static void vnc_write_pixels_generic(VncState *vs,
813 void *pixels1, int size)
815 uint8_t buf[4];
817 if (VNC_SERVER_FB_BYTES == 4) {
818 uint32_t *pixels = pixels1;
819 int n, i;
820 n = size >> 2;
821 for (i = 0; i < n; i++) {
822 vnc_convert_pixel(vs, buf, pixels[i]);
823 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
828 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
830 int i;
831 uint8_t *row;
832 VncDisplay *vd = vs->vd;
834 row = vnc_server_fb_ptr(vd, x, y);
835 for (i = 0; i < h; i++) {
836 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
837 row += vnc_server_fb_stride(vd);
839 return 1;
842 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
844 int n = 0;
845 bool encode_raw = false;
846 size_t saved_offs = vs->output.offset;
848 switch(vs->vnc_encoding) {
849 case VNC_ENCODING_ZLIB:
850 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
851 break;
852 case VNC_ENCODING_HEXTILE:
853 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
854 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
855 break;
856 case VNC_ENCODING_TIGHT:
857 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
858 break;
859 case VNC_ENCODING_TIGHT_PNG:
860 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
861 break;
862 case VNC_ENCODING_ZRLE:
863 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
864 break;
865 case VNC_ENCODING_ZYWRLE:
866 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
867 break;
868 default:
869 encode_raw = true;
870 break;
873 /* If the client has the same pixel format as our internal buffer and
874 * a RAW encoding would need less space fall back to RAW encoding to
875 * save bandwidth and processing power in the client. */
876 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
877 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
878 vs->output.offset = saved_offs;
879 encode_raw = true;
882 if (encode_raw) {
883 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
884 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
887 return n;
890 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
892 /* send bitblit op to the vnc client */
893 vnc_lock_output(vs);
894 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
895 vnc_write_u8(vs, 0);
896 vnc_write_u16(vs, 1); /* number of rects */
897 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
898 vnc_write_u16(vs, src_x);
899 vnc_write_u16(vs, src_y);
900 vnc_unlock_output(vs);
901 vnc_flush(vs);
904 static void vnc_dpy_copy(DisplayChangeListener *dcl,
905 int src_x, int src_y,
906 int dst_x, int dst_y, int w, int h)
908 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
909 VncState *vs, *vn;
910 uint8_t *src_row;
911 uint8_t *dst_row;
912 int i, x, y, pitch, inc, w_lim, s;
913 int cmp_bytes;
915 if (!vd->server) {
916 /* no client connected */
917 return;
920 vnc_refresh_server_surface(vd);
921 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
922 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
923 vs->force_update = 1;
924 vnc_update_client(vs, 1, true);
925 /* vs might be free()ed here */
929 if (!vd->server) {
930 /* no client connected */
931 return;
933 /* do bitblit op on the local surface too */
934 pitch = vnc_server_fb_stride(vd);
935 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
936 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
937 y = dst_y;
938 inc = 1;
939 if (dst_y > src_y) {
940 /* copy backwards */
941 src_row += pitch * (h-1);
942 dst_row += pitch * (h-1);
943 pitch = -pitch;
944 y = dst_y + h - 1;
945 inc = -1;
947 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
948 if (w_lim < 0) {
949 w_lim = w;
950 } else {
951 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
953 for (i = 0; i < h; i++) {
954 for (x = 0; x <= w_lim;
955 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
956 if (x == w_lim) {
957 if ((s = w - w_lim) == 0)
958 break;
959 } else if (!x) {
960 s = (VNC_DIRTY_PIXELS_PER_BIT -
961 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
962 s = MIN(s, w_lim);
963 } else {
964 s = VNC_DIRTY_PIXELS_PER_BIT;
966 cmp_bytes = s * VNC_SERVER_FB_BYTES;
967 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
968 continue;
969 memmove(dst_row, src_row, cmp_bytes);
970 QTAILQ_FOREACH(vs, &vd->clients, next) {
971 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
972 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
973 vs->dirty[y]);
977 src_row += pitch - w * VNC_SERVER_FB_BYTES;
978 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
979 y += inc;
982 QTAILQ_FOREACH(vs, &vd->clients, next) {
983 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
984 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
989 static void vnc_mouse_set(DisplayChangeListener *dcl,
990 int x, int y, int visible)
992 /* can we ask the client(s) to move the pointer ??? */
995 static int vnc_cursor_define(VncState *vs)
997 QEMUCursor *c = vs->vd->cursor;
998 int isize;
1000 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
1001 vnc_lock_output(vs);
1002 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1003 vnc_write_u8(vs, 0); /* padding */
1004 vnc_write_u16(vs, 1); /* # of rects */
1005 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1006 VNC_ENCODING_RICH_CURSOR);
1007 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
1008 vnc_write_pixels_generic(vs, c->data, isize);
1009 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
1010 vnc_unlock_output(vs);
1011 return 0;
1013 return -1;
1016 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1017 QEMUCursor *c)
1019 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1020 VncState *vs;
1022 cursor_put(vd->cursor);
1023 g_free(vd->cursor_mask);
1025 vd->cursor = c;
1026 cursor_get(vd->cursor);
1027 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1028 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1029 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1031 QTAILQ_FOREACH(vs, &vd->clients, next) {
1032 vnc_cursor_define(vs);
1036 static int find_and_clear_dirty_height(VncState *vs,
1037 int y, int last_x, int x, int height)
1039 int h;
1041 for (h = 1; h < (height - y); h++) {
1042 if (!test_bit(last_x, vs->dirty[y + h])) {
1043 break;
1045 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1048 return h;
1051 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1053 if (vs->disconnecting) {
1054 vnc_disconnect_finish(vs);
1055 return 0;
1058 vs->has_dirty += has_dirty;
1059 if (vs->need_update && !vs->disconnecting) {
1060 VncDisplay *vd = vs->vd;
1061 VncJob *job;
1062 int y;
1063 int height, width;
1064 int n = 0;
1066 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1067 /* kernel send buffers are full -> drop frames to throttle */
1068 return 0;
1070 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1071 return 0;
1074 * Send screen updates to the vnc client using the server
1075 * surface and server dirty map. guest surface updates
1076 * happening in parallel don't disturb us, the next pass will
1077 * send them to the client.
1079 job = vnc_job_new(vs);
1081 height = pixman_image_get_height(vd->server);
1082 width = pixman_image_get_width(vd->server);
1084 y = 0;
1085 for (;;) {
1086 int x, h;
1087 unsigned long x2;
1088 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1089 height * VNC_DIRTY_BPL(vs),
1090 y * VNC_DIRTY_BPL(vs));
1091 if (offset == height * VNC_DIRTY_BPL(vs)) {
1092 /* no more dirty bits */
1093 break;
1095 y = offset / VNC_DIRTY_BPL(vs);
1096 x = offset % VNC_DIRTY_BPL(vs);
1097 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1098 VNC_DIRTY_BPL(vs), x);
1099 bitmap_clear(vs->dirty[y], x, x2 - x);
1100 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1101 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1102 if (x2 > x) {
1103 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1104 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1106 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1107 y += h;
1108 if (y == height) {
1109 break;
1114 vnc_job_push(job);
1115 if (sync) {
1116 vnc_jobs_join(vs);
1118 vs->force_update = 0;
1119 vs->has_dirty = 0;
1120 return n;
1123 if (vs->disconnecting) {
1124 vnc_disconnect_finish(vs);
1125 } else if (sync) {
1126 vnc_jobs_join(vs);
1129 return 0;
1132 /* audio */
1133 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1135 VncState *vs = opaque;
1137 switch (cmd) {
1138 case AUD_CNOTIFY_DISABLE:
1139 vnc_lock_output(vs);
1140 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1141 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1142 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1143 vnc_unlock_output(vs);
1144 vnc_flush(vs);
1145 break;
1147 case AUD_CNOTIFY_ENABLE:
1148 vnc_lock_output(vs);
1149 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1150 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1151 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1152 vnc_unlock_output(vs);
1153 vnc_flush(vs);
1154 break;
1158 static void audio_capture_destroy(void *opaque)
1162 static void audio_capture(void *opaque, void *buf, int size)
1164 VncState *vs = opaque;
1166 vnc_lock_output(vs);
1167 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1168 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1169 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1170 vnc_write_u32(vs, size);
1171 vnc_write(vs, buf, size);
1172 vnc_unlock_output(vs);
1173 vnc_flush(vs);
1176 static void audio_add(VncState *vs)
1178 struct audio_capture_ops ops;
1180 if (vs->audio_cap) {
1181 error_report("audio already running");
1182 return;
1185 ops.notify = audio_capture_notify;
1186 ops.destroy = audio_capture_destroy;
1187 ops.capture = audio_capture;
1189 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1190 if (!vs->audio_cap) {
1191 error_report("Failed to add audio capture");
1195 static void audio_del(VncState *vs)
1197 if (vs->audio_cap) {
1198 AUD_del_capture(vs->audio_cap, vs);
1199 vs->audio_cap = NULL;
1203 static void vnc_disconnect_start(VncState *vs)
1205 if (vs->disconnecting) {
1206 return;
1208 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1209 if (vs->ioc_tag) {
1210 g_source_remove(vs->ioc_tag);
1212 qio_channel_close(vs->ioc, NULL);
1213 vs->disconnecting = TRUE;
1216 void vnc_disconnect_finish(VncState *vs)
1218 int i;
1220 vnc_jobs_join(vs); /* Wait encoding jobs */
1222 vnc_lock_output(vs);
1223 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1225 buffer_free(&vs->input);
1226 buffer_free(&vs->output);
1228 qapi_free_VncClientInfo(vs->info);
1230 vnc_zlib_clear(vs);
1231 vnc_tight_clear(vs);
1232 vnc_zrle_clear(vs);
1234 #ifdef CONFIG_VNC_SASL
1235 vnc_sasl_client_cleanup(vs);
1236 #endif /* CONFIG_VNC_SASL */
1237 audio_del(vs);
1238 vnc_release_modifiers(vs);
1240 if (vs->mouse_mode_notifier.notify != NULL) {
1241 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1243 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1244 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1245 /* last client gone */
1246 vnc_update_server_surface(vs->vd);
1249 vnc_unlock_output(vs);
1251 qemu_mutex_destroy(&vs->output_mutex);
1252 if (vs->bh != NULL) {
1253 qemu_bh_delete(vs->bh);
1255 buffer_free(&vs->jobs_buffer);
1257 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1258 g_free(vs->lossy_rect[i]);
1260 g_free(vs->lossy_rect);
1262 object_unref(OBJECT(vs->ioc));
1263 vs->ioc = NULL;
1264 object_unref(OBJECT(vs->sioc));
1265 vs->sioc = NULL;
1266 g_free(vs);
1269 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1271 if (ret <= 0) {
1272 if (ret == 0) {
1273 VNC_DEBUG("Closing down client sock: EOF\n");
1274 vnc_disconnect_start(vs);
1275 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1276 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1277 ret, errp ? error_get_pretty(*errp) : "Unknown");
1278 vnc_disconnect_start(vs);
1281 if (errp) {
1282 error_free(*errp);
1283 *errp = NULL;
1285 return 0;
1287 return ret;
1291 void vnc_client_error(VncState *vs)
1293 VNC_DEBUG("Closing down client sock: protocol error\n");
1294 vnc_disconnect_start(vs);
1299 * Called to write a chunk of data to the client socket. The data may
1300 * be the raw data, or may have already been encoded by SASL.
1301 * The data will be written either straight onto the socket, or
1302 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1304 * NB, it is theoretically possible to have 2 layers of encryption,
1305 * both SASL, and this TLS layer. It is highly unlikely in practice
1306 * though, since SASL encryption will typically be a no-op if TLS
1307 * is active
1309 * Returns the number of bytes written, which may be less than
1310 * the requested 'datalen' if the socket would block. Returns
1311 * -1 on error, and disconnects the client socket.
1313 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1315 Error *err = NULL;
1316 ssize_t ret;
1317 ret = qio_channel_write(
1318 vs->ioc, (const char *)data, datalen, &err);
1319 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1320 return vnc_client_io_error(vs, ret, &err);
1325 * Called to write buffered data to the client socket, when not
1326 * using any SASL SSF encryption layers. Will write as much data
1327 * as possible without blocking. If all buffered data is written,
1328 * will switch the FD poll() handler back to read monitoring.
1330 * Returns the number of bytes written, which may be less than
1331 * the buffered output data if the socket would block. Returns
1332 * -1 on error, and disconnects the client socket.
1334 static ssize_t vnc_client_write_plain(VncState *vs)
1336 ssize_t ret;
1338 #ifdef CONFIG_VNC_SASL
1339 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1340 vs->output.buffer, vs->output.capacity, vs->output.offset,
1341 vs->sasl.waitWriteSSF);
1343 if (vs->sasl.conn &&
1344 vs->sasl.runSSF &&
1345 vs->sasl.waitWriteSSF) {
1346 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1347 if (ret)
1348 vs->sasl.waitWriteSSF -= ret;
1349 } else
1350 #endif /* CONFIG_VNC_SASL */
1351 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1352 if (!ret)
1353 return 0;
1355 buffer_advance(&vs->output, ret);
1357 if (vs->output.offset == 0) {
1358 if (vs->ioc_tag) {
1359 g_source_remove(vs->ioc_tag);
1361 vs->ioc_tag = qio_channel_add_watch(
1362 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1365 return ret;
1370 * First function called whenever there is data to be written to
1371 * the client socket. Will delegate actual work according to whether
1372 * SASL SSF layers are enabled (thus requiring encryption calls)
1374 static void vnc_client_write_locked(VncState *vs)
1376 #ifdef CONFIG_VNC_SASL
1377 if (vs->sasl.conn &&
1378 vs->sasl.runSSF &&
1379 !vs->sasl.waitWriteSSF) {
1380 vnc_client_write_sasl(vs);
1381 } else
1382 #endif /* CONFIG_VNC_SASL */
1384 vnc_client_write_plain(vs);
1388 static void vnc_client_write(VncState *vs)
1391 vnc_lock_output(vs);
1392 if (vs->output.offset) {
1393 vnc_client_write_locked(vs);
1394 } else if (vs->ioc != NULL) {
1395 if (vs->ioc_tag) {
1396 g_source_remove(vs->ioc_tag);
1398 vs->ioc_tag = qio_channel_add_watch(
1399 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1401 vnc_unlock_output(vs);
1404 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1406 vs->read_handler = func;
1407 vs->read_handler_expect = expecting;
1412 * Called to read a chunk of data from the client socket. The data may
1413 * be the raw data, or may need to be further decoded by SASL.
1414 * The data will be read either straight from to the socket, or
1415 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1417 * NB, it is theoretically possible to have 2 layers of encryption,
1418 * both SASL, and this TLS layer. It is highly unlikely in practice
1419 * though, since SASL encryption will typically be a no-op if TLS
1420 * is active
1422 * Returns the number of bytes read, which may be less than
1423 * the requested 'datalen' if the socket would block. Returns
1424 * -1 on error, and disconnects the client socket.
1426 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1428 ssize_t ret;
1429 Error *err = NULL;
1430 ret = qio_channel_read(
1431 vs->ioc, (char *)data, datalen, &err);
1432 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1433 return vnc_client_io_error(vs, ret, &err);
1438 * Called to read data from the client socket to the input buffer,
1439 * when not using any SASL SSF encryption layers. Will read as much
1440 * data as possible without blocking.
1442 * Returns the number of bytes read. Returns -1 on error, and
1443 * disconnects the client socket.
1445 static ssize_t vnc_client_read_plain(VncState *vs)
1447 ssize_t ret;
1448 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1449 vs->input.buffer, vs->input.capacity, vs->input.offset);
1450 buffer_reserve(&vs->input, 4096);
1451 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1452 if (!ret)
1453 return 0;
1454 vs->input.offset += ret;
1455 return ret;
1458 static void vnc_jobs_bh(void *opaque)
1460 VncState *vs = opaque;
1462 vnc_jobs_consume_buffer(vs);
1466 * First function called whenever there is more data to be read from
1467 * the client socket. Will delegate actual work according to whether
1468 * SASL SSF layers are enabled (thus requiring decryption calls)
1469 * Returns 0 on success, -1 if client disconnected
1471 static int vnc_client_read(VncState *vs)
1473 ssize_t ret;
1475 #ifdef CONFIG_VNC_SASL
1476 if (vs->sasl.conn && vs->sasl.runSSF)
1477 ret = vnc_client_read_sasl(vs);
1478 else
1479 #endif /* CONFIG_VNC_SASL */
1480 ret = vnc_client_read_plain(vs);
1481 if (!ret) {
1482 if (vs->disconnecting) {
1483 vnc_disconnect_finish(vs);
1484 return -1;
1486 return 0;
1489 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1490 size_t len = vs->read_handler_expect;
1491 int ret;
1493 ret = vs->read_handler(vs, vs->input.buffer, len);
1494 if (vs->disconnecting) {
1495 vnc_disconnect_finish(vs);
1496 return -1;
1499 if (!ret) {
1500 buffer_advance(&vs->input, len);
1501 } else {
1502 vs->read_handler_expect = ret;
1505 return 0;
1508 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1509 GIOCondition condition, void *opaque)
1511 VncState *vs = opaque;
1512 if (condition & G_IO_IN) {
1513 if (vnc_client_read(vs) < 0) {
1514 return TRUE;
1517 if (condition & G_IO_OUT) {
1518 vnc_client_write(vs);
1520 return TRUE;
1524 void vnc_write(VncState *vs, const void *data, size_t len)
1526 buffer_reserve(&vs->output, len);
1528 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1529 if (vs->ioc_tag) {
1530 g_source_remove(vs->ioc_tag);
1532 vs->ioc_tag = qio_channel_add_watch(
1533 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1536 buffer_append(&vs->output, data, len);
1539 void vnc_write_s32(VncState *vs, int32_t value)
1541 vnc_write_u32(vs, *(uint32_t *)&value);
1544 void vnc_write_u32(VncState *vs, uint32_t value)
1546 uint8_t buf[4];
1548 buf[0] = (value >> 24) & 0xFF;
1549 buf[1] = (value >> 16) & 0xFF;
1550 buf[2] = (value >> 8) & 0xFF;
1551 buf[3] = value & 0xFF;
1553 vnc_write(vs, buf, 4);
1556 void vnc_write_u16(VncState *vs, uint16_t value)
1558 uint8_t buf[2];
1560 buf[0] = (value >> 8) & 0xFF;
1561 buf[1] = value & 0xFF;
1563 vnc_write(vs, buf, 2);
1566 void vnc_write_u8(VncState *vs, uint8_t value)
1568 vnc_write(vs, (char *)&value, 1);
1571 void vnc_flush(VncState *vs)
1573 vnc_lock_output(vs);
1574 if (vs->ioc != NULL && vs->output.offset) {
1575 vnc_client_write_locked(vs);
1577 vnc_unlock_output(vs);
1580 static uint8_t read_u8(uint8_t *data, size_t offset)
1582 return data[offset];
1585 static uint16_t read_u16(uint8_t *data, size_t offset)
1587 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1590 static int32_t read_s32(uint8_t *data, size_t offset)
1592 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1593 (data[offset + 2] << 8) | data[offset + 3]);
1596 uint32_t read_u32(uint8_t *data, size_t offset)
1598 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1599 (data[offset + 2] << 8) | data[offset + 3]);
1602 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1606 static void check_pointer_type_change(Notifier *notifier, void *data)
1608 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1609 int absolute = qemu_input_is_absolute();
1611 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1612 vnc_lock_output(vs);
1613 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1614 vnc_write_u8(vs, 0);
1615 vnc_write_u16(vs, 1);
1616 vnc_framebuffer_update(vs, absolute, 0,
1617 pixman_image_get_width(vs->vd->server),
1618 pixman_image_get_height(vs->vd->server),
1619 VNC_ENCODING_POINTER_TYPE_CHANGE);
1620 vnc_unlock_output(vs);
1621 vnc_flush(vs);
1623 vs->absolute = absolute;
1626 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1628 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1629 [INPUT_BUTTON_LEFT] = 0x01,
1630 [INPUT_BUTTON_MIDDLE] = 0x02,
1631 [INPUT_BUTTON_RIGHT] = 0x04,
1632 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1633 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1635 QemuConsole *con = vs->vd->dcl.con;
1636 int width = pixman_image_get_width(vs->vd->server);
1637 int height = pixman_image_get_height(vs->vd->server);
1639 if (vs->last_bmask != button_mask) {
1640 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1641 vs->last_bmask = button_mask;
1644 if (vs->absolute) {
1645 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1646 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1647 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1648 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1649 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1650 } else {
1651 if (vs->last_x != -1) {
1652 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1653 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1655 vs->last_x = x;
1656 vs->last_y = y;
1658 qemu_input_event_sync();
1661 static void reset_keys(VncState *vs)
1663 int i;
1664 for(i = 0; i < 256; i++) {
1665 if (vs->modifiers_state[i]) {
1666 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1667 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1668 vs->modifiers_state[i] = 0;
1673 static void press_key(VncState *vs, int keysym)
1675 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1676 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1677 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1678 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1679 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1682 static void vnc_led_state_change(VncState *vs)
1684 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1685 return;
1688 vnc_lock_output(vs);
1689 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1690 vnc_write_u8(vs, 0);
1691 vnc_write_u16(vs, 1);
1692 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1693 vnc_write_u8(vs, vs->vd->ledstate);
1694 vnc_unlock_output(vs);
1695 vnc_flush(vs);
1698 static void kbd_leds(void *opaque, int ledstate)
1700 VncDisplay *vd = opaque;
1701 VncState *client;
1703 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1704 (ledstate & QEMU_NUM_LOCK_LED),
1705 (ledstate & QEMU_SCROLL_LOCK_LED));
1707 if (ledstate == vd->ledstate) {
1708 return;
1711 vd->ledstate = ledstate;
1713 QTAILQ_FOREACH(client, &vd->clients, next) {
1714 vnc_led_state_change(client);
1718 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1720 /* QEMU console switch */
1721 switch(keycode) {
1722 case 0x2a: /* Left Shift */
1723 case 0x36: /* Right Shift */
1724 case 0x1d: /* Left CTRL */
1725 case 0x9d: /* Right CTRL */
1726 case 0x38: /* Left ALT */
1727 case 0xb8: /* Right ALT */
1728 if (down)
1729 vs->modifiers_state[keycode] = 1;
1730 else
1731 vs->modifiers_state[keycode] = 0;
1732 break;
1733 case 0x02 ... 0x0a: /* '1' to '9' keys */
1734 if (vs->vd->dcl.con == NULL &&
1735 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1736 /* Reset the modifiers sent to the current console */
1737 reset_keys(vs);
1738 console_select(keycode - 0x02);
1739 return;
1741 break;
1742 case 0x3a: /* CapsLock */
1743 case 0x45: /* NumLock */
1744 if (down)
1745 vs->modifiers_state[keycode] ^= 1;
1746 break;
1749 /* Turn off the lock state sync logic if the client support the led
1750 state extension.
1752 if (down && vs->vd->lock_key_sync &&
1753 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1754 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1755 /* If the numlock state needs to change then simulate an additional
1756 keypress before sending this one. This will happen if the user
1757 toggles numlock away from the VNC window.
1759 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1760 if (!vs->modifiers_state[0x45]) {
1761 trace_vnc_key_sync_numlock(true);
1762 vs->modifiers_state[0x45] = 1;
1763 press_key(vs, 0xff7f);
1765 } else {
1766 if (vs->modifiers_state[0x45]) {
1767 trace_vnc_key_sync_numlock(false);
1768 vs->modifiers_state[0x45] = 0;
1769 press_key(vs, 0xff7f);
1774 if (down && vs->vd->lock_key_sync &&
1775 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1776 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1777 /* If the capslock state needs to change then simulate an additional
1778 keypress before sending this one. This will happen if the user
1779 toggles capslock away from the VNC window.
1781 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1782 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1783 int capslock = !!(vs->modifiers_state[0x3a]);
1784 if (capslock) {
1785 if (uppercase == shift) {
1786 trace_vnc_key_sync_capslock(false);
1787 vs->modifiers_state[0x3a] = 0;
1788 press_key(vs, 0xffe5);
1790 } else {
1791 if (uppercase != shift) {
1792 trace_vnc_key_sync_capslock(true);
1793 vs->modifiers_state[0x3a] = 1;
1794 press_key(vs, 0xffe5);
1799 if (qemu_console_is_graphic(NULL)) {
1800 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1801 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1802 } else {
1803 bool numlock = vs->modifiers_state[0x45];
1804 bool control = (vs->modifiers_state[0x1d] ||
1805 vs->modifiers_state[0x9d]);
1806 /* QEMU console emulation */
1807 if (down) {
1808 switch (keycode) {
1809 case 0x2a: /* Left Shift */
1810 case 0x36: /* Right Shift */
1811 case 0x1d: /* Left CTRL */
1812 case 0x9d: /* Right CTRL */
1813 case 0x38: /* Left ALT */
1814 case 0xb8: /* Right ALT */
1815 break;
1816 case 0xc8:
1817 kbd_put_keysym(QEMU_KEY_UP);
1818 break;
1819 case 0xd0:
1820 kbd_put_keysym(QEMU_KEY_DOWN);
1821 break;
1822 case 0xcb:
1823 kbd_put_keysym(QEMU_KEY_LEFT);
1824 break;
1825 case 0xcd:
1826 kbd_put_keysym(QEMU_KEY_RIGHT);
1827 break;
1828 case 0xd3:
1829 kbd_put_keysym(QEMU_KEY_DELETE);
1830 break;
1831 case 0xc7:
1832 kbd_put_keysym(QEMU_KEY_HOME);
1833 break;
1834 case 0xcf:
1835 kbd_put_keysym(QEMU_KEY_END);
1836 break;
1837 case 0xc9:
1838 kbd_put_keysym(QEMU_KEY_PAGEUP);
1839 break;
1840 case 0xd1:
1841 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1842 break;
1844 case 0x47:
1845 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1846 break;
1847 case 0x48:
1848 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1849 break;
1850 case 0x49:
1851 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1852 break;
1853 case 0x4b:
1854 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1855 break;
1856 case 0x4c:
1857 kbd_put_keysym('5');
1858 break;
1859 case 0x4d:
1860 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1861 break;
1862 case 0x4f:
1863 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1864 break;
1865 case 0x50:
1866 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1867 break;
1868 case 0x51:
1869 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1870 break;
1871 case 0x52:
1872 kbd_put_keysym('0');
1873 break;
1874 case 0x53:
1875 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1876 break;
1878 case 0xb5:
1879 kbd_put_keysym('/');
1880 break;
1881 case 0x37:
1882 kbd_put_keysym('*');
1883 break;
1884 case 0x4a:
1885 kbd_put_keysym('-');
1886 break;
1887 case 0x4e:
1888 kbd_put_keysym('+');
1889 break;
1890 case 0x9c:
1891 kbd_put_keysym('\n');
1892 break;
1894 default:
1895 if (control) {
1896 kbd_put_keysym(sym & 0x1f);
1897 } else {
1898 kbd_put_keysym(sym);
1900 break;
1906 static void vnc_release_modifiers(VncState *vs)
1908 static const int keycodes[] = {
1909 /* shift, control, alt keys, both left & right */
1910 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1912 int i, keycode;
1914 if (!qemu_console_is_graphic(NULL)) {
1915 return;
1917 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1918 keycode = keycodes[i];
1919 if (!vs->modifiers_state[keycode]) {
1920 continue;
1922 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1923 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1927 static const char *code2name(int keycode)
1929 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1932 static void key_event(VncState *vs, int down, uint32_t sym)
1934 int keycode;
1935 int lsym = sym;
1937 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1938 lsym = lsym - 'A' + 'a';
1941 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1942 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1943 do_key_event(vs, down, keycode, sym);
1946 static void ext_key_event(VncState *vs, int down,
1947 uint32_t sym, uint16_t keycode)
1949 /* if the user specifies a keyboard layout, always use it */
1950 if (keyboard_layout) {
1951 key_event(vs, down, sym);
1952 } else {
1953 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1954 do_key_event(vs, down, keycode, sym);
1958 static void framebuffer_update_request(VncState *vs, int incremental,
1959 int x, int y, int w, int h)
1961 vs->need_update = 1;
1963 if (incremental) {
1964 return;
1967 vs->force_update = 1;
1968 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1971 static void send_ext_key_event_ack(VncState *vs)
1973 vnc_lock_output(vs);
1974 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1975 vnc_write_u8(vs, 0);
1976 vnc_write_u16(vs, 1);
1977 vnc_framebuffer_update(vs, 0, 0,
1978 pixman_image_get_width(vs->vd->server),
1979 pixman_image_get_height(vs->vd->server),
1980 VNC_ENCODING_EXT_KEY_EVENT);
1981 vnc_unlock_output(vs);
1982 vnc_flush(vs);
1985 static void send_ext_audio_ack(VncState *vs)
1987 vnc_lock_output(vs);
1988 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1989 vnc_write_u8(vs, 0);
1990 vnc_write_u16(vs, 1);
1991 vnc_framebuffer_update(vs, 0, 0,
1992 pixman_image_get_width(vs->vd->server),
1993 pixman_image_get_height(vs->vd->server),
1994 VNC_ENCODING_AUDIO);
1995 vnc_unlock_output(vs);
1996 vnc_flush(vs);
1999 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2001 int i;
2002 unsigned int enc = 0;
2004 vs->features = 0;
2005 vs->vnc_encoding = 0;
2006 vs->tight.compression = 9;
2007 vs->tight.quality = -1; /* Lossless by default */
2008 vs->absolute = -1;
2011 * Start from the end because the encodings are sent in order of preference.
2012 * This way the preferred encoding (first encoding defined in the array)
2013 * will be set at the end of the loop.
2015 for (i = n_encodings - 1; i >= 0; i--) {
2016 enc = encodings[i];
2017 switch (enc) {
2018 case VNC_ENCODING_RAW:
2019 vs->vnc_encoding = enc;
2020 break;
2021 case VNC_ENCODING_COPYRECT:
2022 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2023 break;
2024 case VNC_ENCODING_HEXTILE:
2025 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2026 vs->vnc_encoding = enc;
2027 break;
2028 case VNC_ENCODING_TIGHT:
2029 vs->features |= VNC_FEATURE_TIGHT_MASK;
2030 vs->vnc_encoding = enc;
2031 break;
2032 #ifdef CONFIG_VNC_PNG
2033 case VNC_ENCODING_TIGHT_PNG:
2034 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2035 vs->vnc_encoding = enc;
2036 break;
2037 #endif
2038 case VNC_ENCODING_ZLIB:
2039 vs->features |= VNC_FEATURE_ZLIB_MASK;
2040 vs->vnc_encoding = enc;
2041 break;
2042 case VNC_ENCODING_ZRLE:
2043 vs->features |= VNC_FEATURE_ZRLE_MASK;
2044 vs->vnc_encoding = enc;
2045 break;
2046 case VNC_ENCODING_ZYWRLE:
2047 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2048 vs->vnc_encoding = enc;
2049 break;
2050 case VNC_ENCODING_DESKTOPRESIZE:
2051 vs->features |= VNC_FEATURE_RESIZE_MASK;
2052 break;
2053 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2054 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2055 break;
2056 case VNC_ENCODING_RICH_CURSOR:
2057 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2058 if (vs->vd->cursor) {
2059 vnc_cursor_define(vs);
2061 break;
2062 case VNC_ENCODING_EXT_KEY_EVENT:
2063 send_ext_key_event_ack(vs);
2064 break;
2065 case VNC_ENCODING_AUDIO:
2066 send_ext_audio_ack(vs);
2067 break;
2068 case VNC_ENCODING_WMVi:
2069 vs->features |= VNC_FEATURE_WMVI_MASK;
2070 break;
2071 case VNC_ENCODING_LED_STATE:
2072 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2073 break;
2074 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2075 vs->tight.compression = (enc & 0x0F);
2076 break;
2077 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2078 if (vs->vd->lossy) {
2079 vs->tight.quality = (enc & 0x0F);
2081 break;
2082 default:
2083 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2084 break;
2087 vnc_desktop_resize(vs);
2088 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2089 vnc_led_state_change(vs);
2092 static void set_pixel_conversion(VncState *vs)
2094 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2096 if (fmt == VNC_SERVER_FB_FORMAT) {
2097 vs->write_pixels = vnc_write_pixels_copy;
2098 vnc_hextile_set_pixel_conversion(vs, 0);
2099 } else {
2100 vs->write_pixels = vnc_write_pixels_generic;
2101 vnc_hextile_set_pixel_conversion(vs, 1);
2105 static void send_color_map(VncState *vs)
2107 int i;
2109 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2110 vnc_write_u8(vs, 0); /* padding */
2111 vnc_write_u16(vs, 0); /* first color */
2112 vnc_write_u16(vs, 256); /* # of colors */
2114 for (i = 0; i < 256; i++) {
2115 PixelFormat *pf = &vs->client_pf;
2117 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2118 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2119 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2123 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2124 int big_endian_flag, int true_color_flag,
2125 int red_max, int green_max, int blue_max,
2126 int red_shift, int green_shift, int blue_shift)
2128 if (!true_color_flag) {
2129 /* Expose a reasonable default 256 color map */
2130 bits_per_pixel = 8;
2131 red_max = 7;
2132 green_max = 7;
2133 blue_max = 3;
2134 red_shift = 0;
2135 green_shift = 3;
2136 blue_shift = 6;
2139 switch (bits_per_pixel) {
2140 case 8:
2141 case 16:
2142 case 32:
2143 break;
2144 default:
2145 vnc_client_error(vs);
2146 return;
2149 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2150 vs->client_pf.rbits = hweight_long(red_max);
2151 vs->client_pf.rshift = red_shift;
2152 vs->client_pf.rmask = red_max << red_shift;
2153 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2154 vs->client_pf.gbits = hweight_long(green_max);
2155 vs->client_pf.gshift = green_shift;
2156 vs->client_pf.gmask = green_max << green_shift;
2157 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2158 vs->client_pf.bbits = hweight_long(blue_max);
2159 vs->client_pf.bshift = blue_shift;
2160 vs->client_pf.bmask = blue_max << blue_shift;
2161 vs->client_pf.bits_per_pixel = bits_per_pixel;
2162 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2163 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2164 vs->client_be = big_endian_flag;
2166 if (!true_color_flag) {
2167 send_color_map(vs);
2170 set_pixel_conversion(vs);
2172 graphic_hw_invalidate(vs->vd->dcl.con);
2173 graphic_hw_update(vs->vd->dcl.con);
2176 static void pixel_format_message (VncState *vs) {
2177 char pad[3] = { 0, 0, 0 };
2179 vs->client_pf = qemu_default_pixelformat(32);
2181 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2182 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2184 #ifdef HOST_WORDS_BIGENDIAN
2185 vnc_write_u8(vs, 1); /* big-endian-flag */
2186 #else
2187 vnc_write_u8(vs, 0); /* big-endian-flag */
2188 #endif
2189 vnc_write_u8(vs, 1); /* true-color-flag */
2190 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2191 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2192 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2193 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2194 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2195 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2196 vnc_write(vs, pad, 3); /* padding */
2198 vnc_hextile_set_pixel_conversion(vs, 0);
2199 vs->write_pixels = vnc_write_pixels_copy;
2202 static void vnc_colordepth(VncState *vs)
2204 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2205 /* Sending a WMVi message to notify the client*/
2206 vnc_lock_output(vs);
2207 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2208 vnc_write_u8(vs, 0);
2209 vnc_write_u16(vs, 1); /* number of rects */
2210 vnc_framebuffer_update(vs, 0, 0,
2211 pixman_image_get_width(vs->vd->server),
2212 pixman_image_get_height(vs->vd->server),
2213 VNC_ENCODING_WMVi);
2214 pixel_format_message(vs);
2215 vnc_unlock_output(vs);
2216 vnc_flush(vs);
2217 } else {
2218 set_pixel_conversion(vs);
2222 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2224 int i;
2225 uint16_t limit;
2226 VncDisplay *vd = vs->vd;
2228 if (data[0] > 3) {
2229 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2232 switch (data[0]) {
2233 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2234 if (len == 1)
2235 return 20;
2237 set_pixel_format(vs, read_u8(data, 4),
2238 read_u8(data, 6), read_u8(data, 7),
2239 read_u16(data, 8), read_u16(data, 10),
2240 read_u16(data, 12), read_u8(data, 14),
2241 read_u8(data, 15), read_u8(data, 16));
2242 break;
2243 case VNC_MSG_CLIENT_SET_ENCODINGS:
2244 if (len == 1)
2245 return 4;
2247 if (len == 4) {
2248 limit = read_u16(data, 2);
2249 if (limit > 0)
2250 return 4 + (limit * 4);
2251 } else
2252 limit = read_u16(data, 2);
2254 for (i = 0; i < limit; i++) {
2255 int32_t val = read_s32(data, 4 + (i * 4));
2256 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2259 set_encodings(vs, (int32_t *)(data + 4), limit);
2260 break;
2261 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2262 if (len == 1)
2263 return 10;
2265 framebuffer_update_request(vs,
2266 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2267 read_u16(data, 6), read_u16(data, 8));
2268 break;
2269 case VNC_MSG_CLIENT_KEY_EVENT:
2270 if (len == 1)
2271 return 8;
2273 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2274 break;
2275 case VNC_MSG_CLIENT_POINTER_EVENT:
2276 if (len == 1)
2277 return 6;
2279 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2280 break;
2281 case VNC_MSG_CLIENT_CUT_TEXT:
2282 if (len == 1) {
2283 return 8;
2285 if (len == 8) {
2286 uint32_t dlen = read_u32(data, 4);
2287 if (dlen > (1 << 20)) {
2288 error_report("vnc: client_cut_text msg payload has %u bytes"
2289 " which exceeds our limit of 1MB.", dlen);
2290 vnc_client_error(vs);
2291 break;
2293 if (dlen > 0) {
2294 return 8 + dlen;
2298 client_cut_text(vs, read_u32(data, 4), data + 8);
2299 break;
2300 case VNC_MSG_CLIENT_QEMU:
2301 if (len == 1)
2302 return 2;
2304 switch (read_u8(data, 1)) {
2305 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2306 if (len == 2)
2307 return 12;
2309 ext_key_event(vs, read_u16(data, 2),
2310 read_u32(data, 4), read_u32(data, 8));
2311 break;
2312 case VNC_MSG_CLIENT_QEMU_AUDIO:
2313 if (len == 2)
2314 return 4;
2316 switch (read_u16 (data, 2)) {
2317 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2318 audio_add(vs);
2319 break;
2320 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2321 audio_del(vs);
2322 break;
2323 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2324 if (len == 4)
2325 return 10;
2326 switch (read_u8(data, 4)) {
2327 case 0: vs->as.fmt = AUD_FMT_U8; break;
2328 case 1: vs->as.fmt = AUD_FMT_S8; break;
2329 case 2: vs->as.fmt = AUD_FMT_U16; break;
2330 case 3: vs->as.fmt = AUD_FMT_S16; break;
2331 case 4: vs->as.fmt = AUD_FMT_U32; break;
2332 case 5: vs->as.fmt = AUD_FMT_S32; break;
2333 default:
2334 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2335 vnc_client_error(vs);
2336 break;
2338 vs->as.nchannels = read_u8(data, 5);
2339 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2340 VNC_DEBUG("Invalid audio channel coount %d\n",
2341 read_u8(data, 5));
2342 vnc_client_error(vs);
2343 break;
2345 vs->as.freq = read_u32(data, 6);
2346 break;
2347 default:
2348 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2349 vnc_client_error(vs);
2350 break;
2352 break;
2354 default:
2355 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2356 vnc_client_error(vs);
2357 break;
2359 break;
2360 default:
2361 VNC_DEBUG("Msg: %d\n", data[0]);
2362 vnc_client_error(vs);
2363 break;
2366 vnc_read_when(vs, protocol_client_msg, 1);
2367 return 0;
2370 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2372 char buf[1024];
2373 VncShareMode mode;
2374 int size;
2376 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2377 switch (vs->vd->share_policy) {
2378 case VNC_SHARE_POLICY_IGNORE:
2380 * Ignore the shared flag. Nothing to do here.
2382 * Doesn't conform to the rfb spec but is traditional qemu
2383 * behavior, thus left here as option for compatibility
2384 * reasons.
2386 break;
2387 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2389 * Policy: Allow clients ask for exclusive access.
2391 * Implementation: When a client asks for exclusive access,
2392 * disconnect all others. Shared connects are allowed as long
2393 * as no exclusive connection exists.
2395 * This is how the rfb spec suggests to handle the shared flag.
2397 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2398 VncState *client;
2399 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2400 if (vs == client) {
2401 continue;
2403 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2404 client->share_mode != VNC_SHARE_MODE_SHARED) {
2405 continue;
2407 vnc_disconnect_start(client);
2410 if (mode == VNC_SHARE_MODE_SHARED) {
2411 if (vs->vd->num_exclusive > 0) {
2412 vnc_disconnect_start(vs);
2413 return 0;
2416 break;
2417 case VNC_SHARE_POLICY_FORCE_SHARED:
2419 * Policy: Shared connects only.
2420 * Implementation: Disallow clients asking for exclusive access.
2422 * Useful for shared desktop sessions where you don't want
2423 * someone forgetting to say -shared when running the vnc
2424 * client disconnect everybody else.
2426 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2427 vnc_disconnect_start(vs);
2428 return 0;
2430 break;
2432 vnc_set_share_mode(vs, mode);
2434 if (vs->vd->num_shared > vs->vd->connections_limit) {
2435 vnc_disconnect_start(vs);
2436 return 0;
2439 vs->client_width = pixman_image_get_width(vs->vd->server);
2440 vs->client_height = pixman_image_get_height(vs->vd->server);
2441 vnc_write_u16(vs, vs->client_width);
2442 vnc_write_u16(vs, vs->client_height);
2444 pixel_format_message(vs);
2446 if (qemu_name) {
2447 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2448 if (size > sizeof(buf)) {
2449 size = sizeof(buf);
2451 } else {
2452 size = snprintf(buf, sizeof(buf), "QEMU");
2455 vnc_write_u32(vs, size);
2456 vnc_write(vs, buf, size);
2457 vnc_flush(vs);
2459 vnc_client_cache_auth(vs);
2460 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2462 vnc_read_when(vs, protocol_client_msg, 1);
2464 return 0;
2467 void start_client_init(VncState *vs)
2469 vnc_read_when(vs, protocol_client_init, 1);
2472 static void make_challenge(VncState *vs)
2474 int i;
2476 srand(time(NULL)+getpid()+getpid()*987654+rand());
2478 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2479 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2482 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2484 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2485 size_t i, pwlen;
2486 unsigned char key[8];
2487 time_t now = time(NULL);
2488 QCryptoCipher *cipher = NULL;
2489 Error *err = NULL;
2491 if (!vs->vd->password) {
2492 VNC_DEBUG("No password configured on server");
2493 goto reject;
2495 if (vs->vd->expires < now) {
2496 VNC_DEBUG("Password is expired");
2497 goto reject;
2500 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2502 /* Calculate the expected challenge response */
2503 pwlen = strlen(vs->vd->password);
2504 for (i=0; i<sizeof(key); i++)
2505 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2507 cipher = qcrypto_cipher_new(
2508 QCRYPTO_CIPHER_ALG_DES_RFB,
2509 QCRYPTO_CIPHER_MODE_ECB,
2510 key, G_N_ELEMENTS(key),
2511 &err);
2512 if (!cipher) {
2513 VNC_DEBUG("Cannot initialize cipher %s",
2514 error_get_pretty(err));
2515 error_free(err);
2516 goto reject;
2519 if (qcrypto_cipher_encrypt(cipher,
2520 vs->challenge,
2521 response,
2522 VNC_AUTH_CHALLENGE_SIZE,
2523 &err) < 0) {
2524 VNC_DEBUG("Cannot encrypt challenge %s",
2525 error_get_pretty(err));
2526 error_free(err);
2527 goto reject;
2530 /* Compare expected vs actual challenge response */
2531 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2532 VNC_DEBUG("Client challenge response did not match\n");
2533 goto reject;
2534 } else {
2535 VNC_DEBUG("Accepting VNC challenge response\n");
2536 vnc_write_u32(vs, 0); /* Accept auth */
2537 vnc_flush(vs);
2539 start_client_init(vs);
2542 qcrypto_cipher_free(cipher);
2543 return 0;
2545 reject:
2546 vnc_write_u32(vs, 1); /* Reject auth */
2547 if (vs->minor >= 8) {
2548 static const char err[] = "Authentication failed";
2549 vnc_write_u32(vs, sizeof(err));
2550 vnc_write(vs, err, sizeof(err));
2552 vnc_flush(vs);
2553 vnc_client_error(vs);
2554 qcrypto_cipher_free(cipher);
2555 return 0;
2558 void start_auth_vnc(VncState *vs)
2560 make_challenge(vs);
2561 /* Send client a 'random' challenge */
2562 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2563 vnc_flush(vs);
2565 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2569 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2571 /* We only advertise 1 auth scheme at a time, so client
2572 * must pick the one we sent. Verify this */
2573 if (data[0] != vs->auth) { /* Reject auth */
2574 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2575 vnc_write_u32(vs, 1);
2576 if (vs->minor >= 8) {
2577 static const char err[] = "Authentication failed";
2578 vnc_write_u32(vs, sizeof(err));
2579 vnc_write(vs, err, sizeof(err));
2581 vnc_client_error(vs);
2582 } else { /* Accept requested auth */
2583 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2584 switch (vs->auth) {
2585 case VNC_AUTH_NONE:
2586 VNC_DEBUG("Accept auth none\n");
2587 if (vs->minor >= 8) {
2588 vnc_write_u32(vs, 0); /* Accept auth completion */
2589 vnc_flush(vs);
2591 start_client_init(vs);
2592 break;
2594 case VNC_AUTH_VNC:
2595 VNC_DEBUG("Start VNC auth\n");
2596 start_auth_vnc(vs);
2597 break;
2599 case VNC_AUTH_VENCRYPT:
2600 VNC_DEBUG("Accept VeNCrypt auth\n");
2601 start_auth_vencrypt(vs);
2602 break;
2604 #ifdef CONFIG_VNC_SASL
2605 case VNC_AUTH_SASL:
2606 VNC_DEBUG("Accept SASL auth\n");
2607 start_auth_sasl(vs);
2608 break;
2609 #endif /* CONFIG_VNC_SASL */
2611 default: /* Should not be possible, but just in case */
2612 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2613 vnc_write_u8(vs, 1);
2614 if (vs->minor >= 8) {
2615 static const char err[] = "Authentication failed";
2616 vnc_write_u32(vs, sizeof(err));
2617 vnc_write(vs, err, sizeof(err));
2619 vnc_client_error(vs);
2622 return 0;
2625 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2627 char local[13];
2629 memcpy(local, version, 12);
2630 local[12] = 0;
2632 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2633 VNC_DEBUG("Malformed protocol version %s\n", local);
2634 vnc_client_error(vs);
2635 return 0;
2637 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2638 if (vs->major != 3 ||
2639 (vs->minor != 3 &&
2640 vs->minor != 4 &&
2641 vs->minor != 5 &&
2642 vs->minor != 7 &&
2643 vs->minor != 8)) {
2644 VNC_DEBUG("Unsupported client version\n");
2645 vnc_write_u32(vs, VNC_AUTH_INVALID);
2646 vnc_flush(vs);
2647 vnc_client_error(vs);
2648 return 0;
2650 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2651 * as equivalent to v3.3 by servers
2653 if (vs->minor == 4 || vs->minor == 5)
2654 vs->minor = 3;
2656 if (vs->minor == 3) {
2657 if (vs->auth == VNC_AUTH_NONE) {
2658 VNC_DEBUG("Tell client auth none\n");
2659 vnc_write_u32(vs, vs->auth);
2660 vnc_flush(vs);
2661 start_client_init(vs);
2662 } else if (vs->auth == VNC_AUTH_VNC) {
2663 VNC_DEBUG("Tell client VNC auth\n");
2664 vnc_write_u32(vs, vs->auth);
2665 vnc_flush(vs);
2666 start_auth_vnc(vs);
2667 } else {
2668 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2669 vnc_write_u32(vs, VNC_AUTH_INVALID);
2670 vnc_flush(vs);
2671 vnc_client_error(vs);
2673 } else {
2674 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2675 vnc_write_u8(vs, 1); /* num auth */
2676 vnc_write_u8(vs, vs->auth);
2677 vnc_read_when(vs, protocol_client_auth, 1);
2678 vnc_flush(vs);
2681 return 0;
2684 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2686 struct VncSurface *vs = &vd->guest;
2688 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2691 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2693 int i, j;
2695 w = (x + w) / VNC_STAT_RECT;
2696 h = (y + h) / VNC_STAT_RECT;
2697 x /= VNC_STAT_RECT;
2698 y /= VNC_STAT_RECT;
2700 for (j = y; j <= h; j++) {
2701 for (i = x; i <= w; i++) {
2702 vs->lossy_rect[j][i] = 1;
2707 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2709 VncState *vs;
2710 int sty = y / VNC_STAT_RECT;
2711 int stx = x / VNC_STAT_RECT;
2712 int has_dirty = 0;
2714 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2715 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2717 QTAILQ_FOREACH(vs, &vd->clients, next) {
2718 int j;
2720 /* kernel send buffers are full -> refresh later */
2721 if (vs->output.offset) {
2722 continue;
2725 if (!vs->lossy_rect[sty][stx]) {
2726 continue;
2729 vs->lossy_rect[sty][stx] = 0;
2730 for (j = 0; j < VNC_STAT_RECT; ++j) {
2731 bitmap_set(vs->dirty[y + j],
2732 x / VNC_DIRTY_PIXELS_PER_BIT,
2733 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2735 has_dirty++;
2738 return has_dirty;
2741 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2743 int width = MIN(pixman_image_get_width(vd->guest.fb),
2744 pixman_image_get_width(vd->server));
2745 int height = MIN(pixman_image_get_height(vd->guest.fb),
2746 pixman_image_get_height(vd->server));
2747 int x, y;
2748 struct timeval res;
2749 int has_dirty = 0;
2751 for (y = 0; y < height; y += VNC_STAT_RECT) {
2752 for (x = 0; x < width; x += VNC_STAT_RECT) {
2753 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2755 rect->updated = false;
2759 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2761 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2762 return has_dirty;
2764 vd->guest.last_freq_check = *tv;
2766 for (y = 0; y < height; y += VNC_STAT_RECT) {
2767 for (x = 0; x < width; x += VNC_STAT_RECT) {
2768 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2769 int count = ARRAY_SIZE(rect->times);
2770 struct timeval min, max;
2772 if (!timerisset(&rect->times[count - 1])) {
2773 continue ;
2776 max = rect->times[(rect->idx + count - 1) % count];
2777 qemu_timersub(tv, &max, &res);
2779 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2780 rect->freq = 0;
2781 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2782 memset(rect->times, 0, sizeof (rect->times));
2783 continue ;
2786 min = rect->times[rect->idx];
2787 max = rect->times[(rect->idx + count - 1) % count];
2788 qemu_timersub(&max, &min, &res);
2790 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2791 rect->freq /= count;
2792 rect->freq = 1. / rect->freq;
2795 return has_dirty;
2798 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2800 int i, j;
2801 double total = 0;
2802 int num = 0;
2804 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2805 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2807 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2808 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2809 total += vnc_stat_rect(vs->vd, i, j)->freq;
2810 num++;
2814 if (num) {
2815 return total / num;
2816 } else {
2817 return 0;
2821 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2823 VncRectStat *rect;
2825 rect = vnc_stat_rect(vd, x, y);
2826 if (rect->updated) {
2827 return ;
2829 rect->times[rect->idx] = *tv;
2830 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2831 rect->updated = true;
2834 static int vnc_refresh_server_surface(VncDisplay *vd)
2836 int width = MIN(pixman_image_get_width(vd->guest.fb),
2837 pixman_image_get_width(vd->server));
2838 int height = MIN(pixman_image_get_height(vd->guest.fb),
2839 pixman_image_get_height(vd->server));
2840 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2841 uint8_t *guest_row0 = NULL, *server_row0;
2842 VncState *vs;
2843 int has_dirty = 0;
2844 pixman_image_t *tmpbuf = NULL;
2846 struct timeval tv = { 0, 0 };
2848 if (!vd->non_adaptive) {
2849 gettimeofday(&tv, NULL);
2850 has_dirty = vnc_update_stats(vd, &tv);
2854 * Walk through the guest dirty map.
2855 * Check and copy modified bits from guest to server surface.
2856 * Update server dirty map.
2858 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2859 server_stride = guest_stride = guest_ll =
2860 pixman_image_get_stride(vd->server);
2861 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2862 server_stride);
2863 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2864 int width = pixman_image_get_width(vd->server);
2865 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2866 } else {
2867 int guest_bpp =
2868 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2869 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2870 guest_stride = pixman_image_get_stride(vd->guest.fb);
2871 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2873 line_bytes = MIN(server_stride, guest_ll);
2875 for (;;) {
2876 int x;
2877 uint8_t *guest_ptr, *server_ptr;
2878 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2879 height * VNC_DIRTY_BPL(&vd->guest),
2880 y * VNC_DIRTY_BPL(&vd->guest));
2881 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2882 /* no more dirty bits */
2883 break;
2885 y = offset / VNC_DIRTY_BPL(&vd->guest);
2886 x = offset % VNC_DIRTY_BPL(&vd->guest);
2888 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2890 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2891 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2892 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2893 } else {
2894 guest_ptr = guest_row0 + y * guest_stride;
2896 guest_ptr += x * cmp_bytes;
2898 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2899 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2900 int _cmp_bytes = cmp_bytes;
2901 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2902 continue;
2904 if ((x + 1) * cmp_bytes > line_bytes) {
2905 _cmp_bytes = line_bytes - x * cmp_bytes;
2907 assert(_cmp_bytes >= 0);
2908 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2909 continue;
2911 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2912 if (!vd->non_adaptive) {
2913 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2914 y, &tv);
2916 QTAILQ_FOREACH(vs, &vd->clients, next) {
2917 set_bit(x, vs->dirty[y]);
2919 has_dirty++;
2922 y++;
2924 qemu_pixman_image_unref(tmpbuf);
2925 return has_dirty;
2928 static void vnc_refresh(DisplayChangeListener *dcl)
2930 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2931 VncState *vs, *vn;
2932 int has_dirty, rects = 0;
2934 if (QTAILQ_EMPTY(&vd->clients)) {
2935 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2936 return;
2939 graphic_hw_update(vd->dcl.con);
2941 if (vnc_trylock_display(vd)) {
2942 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2943 return;
2946 has_dirty = vnc_refresh_server_surface(vd);
2947 vnc_unlock_display(vd);
2949 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2950 rects += vnc_update_client(vs, has_dirty, false);
2951 /* vs might be free()ed here */
2954 if (has_dirty && rects) {
2955 vd->dcl.update_interval /= 2;
2956 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2957 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2959 } else {
2960 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2961 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2962 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2967 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2968 bool skipauth, bool websocket)
2970 VncState *vs = g_new0(VncState, 1);
2971 bool first_client = QTAILQ_EMPTY(&vd->clients);
2972 int i;
2974 vs->sioc = sioc;
2975 object_ref(OBJECT(vs->sioc));
2976 vs->ioc = QIO_CHANNEL(sioc);
2977 object_ref(OBJECT(vs->ioc));
2978 vs->vd = vd;
2980 buffer_init(&vs->input, "vnc-input/%p", sioc);
2981 buffer_init(&vs->output, "vnc-output/%p", sioc);
2982 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2984 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2985 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2986 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2987 #ifdef CONFIG_VNC_JPEG
2988 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2989 #endif
2990 #ifdef CONFIG_VNC_PNG
2991 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2992 #endif
2993 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2994 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2995 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2996 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2998 if (skipauth) {
2999 vs->auth = VNC_AUTH_NONE;
3000 vs->subauth = VNC_AUTH_INVALID;
3001 } else {
3002 if (websocket) {
3003 vs->auth = vd->ws_auth;
3004 vs->subauth = VNC_AUTH_INVALID;
3005 } else {
3006 vs->auth = vd->auth;
3007 vs->subauth = vd->subauth;
3010 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3011 sioc, websocket, vs->auth, vs->subauth);
3013 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3014 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3015 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3018 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3019 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3020 qio_channel_set_blocking(vs->ioc, false, NULL);
3021 if (websocket) {
3022 vs->websocket = 1;
3023 if (vd->tlscreds) {
3024 vs->ioc_tag = qio_channel_add_watch(
3025 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3026 } else {
3027 vs->ioc_tag = qio_channel_add_watch(
3028 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
3030 } else {
3031 vs->ioc_tag = qio_channel_add_watch(
3032 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
3035 vnc_client_cache_addr(vs);
3036 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3037 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3039 vs->last_x = -1;
3040 vs->last_y = -1;
3042 vs->as.freq = 44100;
3043 vs->as.nchannels = 2;
3044 vs->as.fmt = AUD_FMT_S16;
3045 vs->as.endianness = 0;
3047 qemu_mutex_init(&vs->output_mutex);
3048 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3050 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3051 if (first_client) {
3052 vnc_update_server_surface(vd);
3055 graphic_hw_update(vd->dcl.con);
3057 if (!vs->websocket) {
3058 vnc_start_protocol(vs);
3061 if (vd->num_connecting > vd->connections_limit) {
3062 QTAILQ_FOREACH(vs, &vd->clients, next) {
3063 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3064 vnc_disconnect_start(vs);
3065 return;
3071 void vnc_start_protocol(VncState *vs)
3073 vnc_write(vs, "RFB 003.008\n", 12);
3074 vnc_flush(vs);
3075 vnc_read_when(vs, protocol_version, 12);
3077 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3078 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3081 static gboolean vnc_listen_io(QIOChannel *ioc,
3082 GIOCondition condition,
3083 void *opaque)
3085 VncDisplay *vd = opaque;
3086 QIOChannelSocket *sioc = NULL;
3087 Error *err = NULL;
3089 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3090 if (sioc != NULL) {
3091 qio_channel_set_name(QIO_CHANNEL(sioc),
3092 ioc != QIO_CHANNEL(vd->lsock) ?
3093 "vnc-ws-server" : "vnc-server");
3094 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3095 vnc_connect(vd, sioc, false,
3096 ioc != QIO_CHANNEL(vd->lsock));
3097 object_unref(OBJECT(sioc));
3098 } else {
3099 /* client probably closed connection before we got there */
3100 error_free(err);
3103 return TRUE;
3106 static const DisplayChangeListenerOps dcl_ops = {
3107 .dpy_name = "vnc",
3108 .dpy_refresh = vnc_refresh,
3109 .dpy_gfx_copy = vnc_dpy_copy,
3110 .dpy_gfx_update = vnc_dpy_update,
3111 .dpy_gfx_switch = vnc_dpy_switch,
3112 .dpy_gfx_check_format = qemu_pixman_check_format,
3113 .dpy_mouse_set = vnc_mouse_set,
3114 .dpy_cursor_define = vnc_dpy_cursor_define,
3117 void vnc_display_init(const char *id)
3119 VncDisplay *vd;
3121 if (vnc_display_find(id) != NULL) {
3122 return;
3124 vd = g_malloc0(sizeof(*vd));
3126 vd->id = strdup(id);
3127 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3129 QTAILQ_INIT(&vd->clients);
3130 vd->expires = TIME_MAX;
3132 if (keyboard_layout) {
3133 trace_vnc_key_map_init(keyboard_layout);
3134 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3135 } else {
3136 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3139 if (!vd->kbd_layout) {
3140 exit(1);
3143 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3144 vd->connections_limit = 32;
3146 qemu_mutex_init(&vd->mutex);
3147 vnc_start_worker_thread();
3149 vd->dcl.ops = &dcl_ops;
3150 register_displaychangelistener(&vd->dcl);
3154 static void vnc_display_close(VncDisplay *vd)
3156 if (!vd) {
3157 return;
3159 vd->is_unix = false;
3160 if (vd->lsock != NULL) {
3161 if (vd->lsock_tag) {
3162 g_source_remove(vd->lsock_tag);
3164 object_unref(OBJECT(vd->lsock));
3165 vd->lsock = NULL;
3167 if (vd->lwebsock != NULL) {
3168 if (vd->lwebsock_tag) {
3169 g_source_remove(vd->lwebsock_tag);
3171 object_unref(OBJECT(vd->lwebsock));
3172 vd->lwebsock = NULL;
3174 vd->auth = VNC_AUTH_INVALID;
3175 vd->subauth = VNC_AUTH_INVALID;
3176 if (vd->tlscreds) {
3177 object_unparent(OBJECT(vd->tlscreds));
3178 vd->tlscreds = NULL;
3180 g_free(vd->tlsaclname);
3181 vd->tlsaclname = NULL;
3182 if (vd->lock_key_sync) {
3183 qemu_remove_led_event_handler(vd->led);
3187 int vnc_display_password(const char *id, const char *password)
3189 VncDisplay *vd = vnc_display_find(id);
3191 if (!vd) {
3192 return -EINVAL;
3194 if (vd->auth == VNC_AUTH_NONE) {
3195 error_printf_unless_qmp("If you want use passwords please enable "
3196 "password auth using '-vnc ${dpy},password'.\n");
3197 return -EINVAL;
3200 g_free(vd->password);
3201 vd->password = g_strdup(password);
3203 return 0;
3206 int vnc_display_pw_expire(const char *id, time_t expires)
3208 VncDisplay *vd = vnc_display_find(id);
3210 if (!vd) {
3211 return -EINVAL;
3214 vd->expires = expires;
3215 return 0;
3218 static void vnc_display_print_local_addr(VncDisplay *vd)
3220 SocketAddress *addr;
3221 Error *err = NULL;
3223 addr = qio_channel_socket_get_local_address(vd->lsock, &err);
3224 if (!addr) {
3225 return;
3228 if (addr->type != SOCKET_ADDRESS_KIND_INET) {
3229 qapi_free_SocketAddress(addr);
3230 return;
3232 error_printf_unless_qmp("VNC server running on %s:%s\n",
3233 addr->u.inet.data->host,
3234 addr->u.inet.data->port);
3235 qapi_free_SocketAddress(addr);
3238 static QemuOptsList qemu_vnc_opts = {
3239 .name = "vnc",
3240 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3241 .implied_opt_name = "vnc",
3242 .desc = {
3244 .name = "vnc",
3245 .type = QEMU_OPT_STRING,
3247 .name = "websocket",
3248 .type = QEMU_OPT_STRING,
3250 .name = "tls-creds",
3251 .type = QEMU_OPT_STRING,
3253 /* Deprecated in favour of tls-creds */
3254 .name = "x509",
3255 .type = QEMU_OPT_STRING,
3257 .name = "share",
3258 .type = QEMU_OPT_STRING,
3260 .name = "display",
3261 .type = QEMU_OPT_STRING,
3263 .name = "head",
3264 .type = QEMU_OPT_NUMBER,
3266 .name = "connections",
3267 .type = QEMU_OPT_NUMBER,
3269 .name = "to",
3270 .type = QEMU_OPT_NUMBER,
3272 .name = "ipv4",
3273 .type = QEMU_OPT_BOOL,
3275 .name = "ipv6",
3276 .type = QEMU_OPT_BOOL,
3278 .name = "password",
3279 .type = QEMU_OPT_BOOL,
3281 .name = "reverse",
3282 .type = QEMU_OPT_BOOL,
3284 .name = "lock-key-sync",
3285 .type = QEMU_OPT_BOOL,
3287 .name = "key-delay-ms",
3288 .type = QEMU_OPT_NUMBER,
3290 .name = "sasl",
3291 .type = QEMU_OPT_BOOL,
3293 /* Deprecated in favour of tls-creds */
3294 .name = "tls",
3295 .type = QEMU_OPT_BOOL,
3297 /* Deprecated in favour of tls-creds */
3298 .name = "x509verify",
3299 .type = QEMU_OPT_STRING,
3301 .name = "acl",
3302 .type = QEMU_OPT_BOOL,
3304 .name = "lossy",
3305 .type = QEMU_OPT_BOOL,
3307 .name = "non-adaptive",
3308 .type = QEMU_OPT_BOOL,
3310 { /* end of list */ }
3315 static int
3316 vnc_display_setup_auth(int *auth,
3317 int *subauth,
3318 QCryptoTLSCreds *tlscreds,
3319 bool password,
3320 bool sasl,
3321 bool websocket,
3322 Error **errp)
3325 * We have a choice of 3 authentication options
3327 * 1. none
3328 * 2. vnc
3329 * 3. sasl
3331 * The channel can be run in 2 modes
3333 * 1. clear
3334 * 2. tls
3336 * And TLS can use 2 types of credentials
3338 * 1. anon
3339 * 2. x509
3341 * We thus have 9 possible logical combinations
3343 * 1. clear + none
3344 * 2. clear + vnc
3345 * 3. clear + sasl
3346 * 4. tls + anon + none
3347 * 5. tls + anon + vnc
3348 * 6. tls + anon + sasl
3349 * 7. tls + x509 + none
3350 * 8. tls + x509 + vnc
3351 * 9. tls + x509 + sasl
3353 * These need to be mapped into the VNC auth schemes
3354 * in an appropriate manner. In regular VNC, all the
3355 * TLS options get mapped into VNC_AUTH_VENCRYPT
3356 * sub-auth types.
3358 * In websockets, the https:// protocol already provides
3359 * TLS support, so there is no need to make use of the
3360 * VeNCrypt extension. Furthermore, websockets browser
3361 * clients could not use VeNCrypt even if they wanted to,
3362 * as they cannot control when the TLS handshake takes
3363 * place. Thus there is no option but to rely on https://,
3364 * meaning combinations 4->6 and 7->9 will be mapped to
3365 * VNC auth schemes in the same way as combos 1->3.
3367 * Regardless of fact that we have a different mapping to
3368 * VNC auth mechs for plain VNC vs websockets VNC, the end
3369 * result has the same security characteristics.
3371 if (websocket || !tlscreds) {
3372 if (password) {
3373 VNC_DEBUG("Initializing VNC server with password auth\n");
3374 *auth = VNC_AUTH_VNC;
3375 } else if (sasl) {
3376 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3377 *auth = VNC_AUTH_SASL;
3378 } else {
3379 VNC_DEBUG("Initializing VNC server with no auth\n");
3380 *auth = VNC_AUTH_NONE;
3382 *subauth = VNC_AUTH_INVALID;
3383 } else {
3384 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3385 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3386 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3387 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3389 if (!is_x509 && !is_anon) {
3390 error_setg(errp,
3391 "Unsupported TLS cred type %s",
3392 object_get_typename(OBJECT(tlscreds)));
3393 return -1;
3395 *auth = VNC_AUTH_VENCRYPT;
3396 if (password) {
3397 if (is_x509) {
3398 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3399 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3400 } else {
3401 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3402 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3405 } else if (sasl) {
3406 if (is_x509) {
3407 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3408 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3409 } else {
3410 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3411 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3413 } else {
3414 if (is_x509) {
3415 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3416 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3417 } else {
3418 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3419 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3423 return 0;
3428 * Handle back compat with old CLI syntax by creating some
3429 * suitable QCryptoTLSCreds objects
3431 static QCryptoTLSCreds *
3432 vnc_display_create_creds(bool x509,
3433 bool x509verify,
3434 const char *dir,
3435 const char *id,
3436 Error **errp)
3438 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3439 Object *parent = object_get_objects_root();
3440 Object *creds;
3441 Error *err = NULL;
3443 if (x509) {
3444 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3445 parent,
3446 credsid,
3447 &err,
3448 "endpoint", "server",
3449 "dir", dir,
3450 "verify-peer", x509verify ? "yes" : "no",
3451 NULL);
3452 } else {
3453 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3454 parent,
3455 credsid,
3456 &err,
3457 "endpoint", "server",
3458 NULL);
3461 g_free(credsid);
3463 if (err) {
3464 error_propagate(errp, err);
3465 return NULL;
3468 return QCRYPTO_TLS_CREDS(creds);
3472 void vnc_display_open(const char *id, Error **errp)
3474 VncDisplay *vd = vnc_display_find(id);
3475 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3476 SocketAddress *saddr = NULL, *wsaddr = NULL;
3477 const char *share, *device_id;
3478 QemuConsole *con;
3479 bool password = false;
3480 bool reverse = false;
3481 const char *vnc;
3482 char *h;
3483 const char *credid;
3484 int show_vnc_port = 0;
3485 bool sasl = false;
3486 #ifdef CONFIG_VNC_SASL
3487 int saslErr;
3488 #endif
3489 int acl = 0;
3490 int lock_key_sync = 1;
3491 int key_delay_ms;
3492 bool ws_enabled = false;
3494 if (!vd) {
3495 error_setg(errp, "VNC display not active");
3496 return;
3498 vnc_display_close(vd);
3500 if (!opts) {
3501 return;
3503 vnc = qemu_opt_get(opts, "vnc");
3504 if (!vnc || strcmp(vnc, "none") == 0) {
3505 return;
3508 h = strrchr(vnc, ':');
3509 if (h) {
3510 size_t hlen = h - vnc;
3512 const char *websocket = qemu_opt_get(opts, "websocket");
3513 int to = qemu_opt_get_number(opts, "to", 0);
3514 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3515 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3516 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3517 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3519 saddr = g_new0(SocketAddress, 1);
3520 if (websocket) {
3521 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3522 error_setg(errp,
3523 "SHA1 hash support is required for websockets");
3524 goto fail;
3527 wsaddr = g_new0(SocketAddress, 1);
3528 ws_enabled = true;
3531 if (strncmp(vnc, "unix:", 5) == 0) {
3532 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3533 saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
3534 saddr->u.q_unix.data->path = g_strdup(vnc + 5);
3536 if (ws_enabled) {
3537 error_setg(errp, "UNIX sockets not supported with websock");
3538 goto fail;
3540 } else {
3541 unsigned long long baseport;
3542 InetSocketAddress *inet;
3543 saddr->type = SOCKET_ADDRESS_KIND_INET;
3544 inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
3545 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3546 inet->host = g_strndup(vnc + 1, hlen - 2);
3547 } else {
3548 inet->host = g_strndup(vnc, hlen);
3550 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3551 error_setg(errp, "can't convert to a number: %s", h + 1);
3552 goto fail;
3554 if (baseport > 65535 ||
3555 baseport + 5900 > 65535) {
3556 error_setg(errp, "port %s out of range", h + 1);
3557 goto fail;
3559 inet->port = g_strdup_printf(
3560 "%d", (int)baseport + 5900);
3562 if (to) {
3563 inet->has_to = true;
3564 inet->to = to + 5900;
3565 show_vnc_port = 1;
3567 inet->ipv4 = ipv4;
3568 inet->has_ipv4 = has_ipv4;
3569 inet->ipv6 = ipv6;
3570 inet->has_ipv6 = has_ipv6;
3572 if (ws_enabled) {
3573 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3574 inet = wsaddr->u.inet.data = g_new0(InetSocketAddress, 1);
3575 inet->host = g_strdup(saddr->u.inet.data->host);
3576 if (g_str_equal(websocket, "") ||
3577 g_str_equal(websocket, "on")) {
3578 inet->port = g_strdup_printf(
3579 "%d", (int)baseport + 5700);
3580 } else {
3581 inet->port = g_strdup(websocket);
3584 if (to) {
3585 inet->has_to = true;
3586 inet->to = to;
3588 inet->ipv4 = ipv4;
3589 inet->has_ipv4 = has_ipv4;
3590 inet->ipv6 = ipv6;
3591 inet->has_ipv6 = has_ipv6;
3594 } else {
3595 error_setg(errp, "no vnc port specified");
3596 goto fail;
3599 password = qemu_opt_get_bool(opts, "password", false);
3600 if (password) {
3601 if (fips_get_state()) {
3602 error_setg(errp,
3603 "VNC password auth disabled due to FIPS mode, "
3604 "consider using the VeNCrypt or SASL authentication "
3605 "methods as an alternative");
3606 goto fail;
3608 if (!qcrypto_cipher_supports(
3609 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3610 error_setg(errp,
3611 "Cipher backend does not support DES RFB algorithm");
3612 goto fail;
3616 reverse = qemu_opt_get_bool(opts, "reverse", false);
3617 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3618 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
3619 sasl = qemu_opt_get_bool(opts, "sasl", false);
3620 #ifndef CONFIG_VNC_SASL
3621 if (sasl) {
3622 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3623 goto fail;
3625 #endif /* CONFIG_VNC_SASL */
3626 credid = qemu_opt_get(opts, "tls-creds");
3627 if (credid) {
3628 Object *creds;
3629 if (qemu_opt_get(opts, "tls") ||
3630 qemu_opt_get(opts, "x509") ||
3631 qemu_opt_get(opts, "x509verify")) {
3632 error_setg(errp,
3633 "'tls-creds' parameter is mutually exclusive with "
3634 "'tls', 'x509' and 'x509verify' parameters");
3635 goto fail;
3638 creds = object_resolve_path_component(
3639 object_get_objects_root(), credid);
3640 if (!creds) {
3641 error_setg(errp, "No TLS credentials with id '%s'",
3642 credid);
3643 goto fail;
3645 vd->tlscreds = (QCryptoTLSCreds *)
3646 object_dynamic_cast(creds,
3647 TYPE_QCRYPTO_TLS_CREDS);
3648 if (!vd->tlscreds) {
3649 error_setg(errp, "Object with id '%s' is not TLS credentials",
3650 credid);
3651 goto fail;
3653 object_ref(OBJECT(vd->tlscreds));
3655 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3656 error_setg(errp,
3657 "Expecting TLS credentials with a server endpoint");
3658 goto fail;
3660 } else {
3661 const char *path;
3662 bool tls = false, x509 = false, x509verify = false;
3663 tls = qemu_opt_get_bool(opts, "tls", false);
3664 if (tls) {
3665 path = qemu_opt_get(opts, "x509");
3667 if (path) {
3668 x509 = true;
3669 } else {
3670 path = qemu_opt_get(opts, "x509verify");
3671 if (path) {
3672 x509 = true;
3673 x509verify = true;
3676 vd->tlscreds = vnc_display_create_creds(x509,
3677 x509verify,
3678 path,
3679 vd->id,
3680 errp);
3681 if (!vd->tlscreds) {
3682 goto fail;
3686 acl = qemu_opt_get_bool(opts, "acl", false);
3688 share = qemu_opt_get(opts, "share");
3689 if (share) {
3690 if (strcmp(share, "ignore") == 0) {
3691 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
3692 } else if (strcmp(share, "allow-exclusive") == 0) {
3693 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3694 } else if (strcmp(share, "force-shared") == 0) {
3695 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3696 } else {
3697 error_setg(errp, "unknown vnc share= option");
3698 goto fail;
3700 } else {
3701 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3703 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3705 #ifdef CONFIG_VNC_JPEG
3706 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
3707 #endif
3708 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3709 /* adaptive updates are only used with tight encoding and
3710 * if lossy updates are enabled so we can disable all the
3711 * calculations otherwise */
3712 if (!vd->lossy) {
3713 vd->non_adaptive = true;
3716 if (acl) {
3717 if (strcmp(vd->id, "default") == 0) {
3718 vd->tlsaclname = g_strdup("vnc.x509dname");
3719 } else {
3720 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
3722 qemu_acl_init(vd->tlsaclname);
3724 #ifdef CONFIG_VNC_SASL
3725 if (acl && sasl) {
3726 char *aclname;
3728 if (strcmp(vd->id, "default") == 0) {
3729 aclname = g_strdup("vnc.username");
3730 } else {
3731 aclname = g_strdup_printf("vnc.%s.username", vd->id);
3733 vd->sasl.acl = qemu_acl_init(aclname);
3734 g_free(aclname);
3736 #endif
3738 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
3739 vd->tlscreds, password,
3740 sasl, false, errp) < 0) {
3741 goto fail;
3744 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
3745 vd->tlscreds, password,
3746 sasl, true, errp) < 0) {
3747 goto fail;
3750 #ifdef CONFIG_VNC_SASL
3751 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3752 error_setg(errp, "Failed to initialize SASL auth: %s",
3753 sasl_errstring(saslErr, NULL, NULL));
3754 goto fail;
3756 #endif
3757 vd->lock_key_sync = lock_key_sync;
3758 if (lock_key_sync) {
3759 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
3761 vd->ledstate = 0;
3762 vd->key_delay_ms = key_delay_ms;
3764 device_id = qemu_opt_get(opts, "display");
3765 if (device_id) {
3766 int head = qemu_opt_get_number(opts, "head", 0);
3767 Error *err = NULL;
3769 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3770 if (err) {
3771 error_propagate(errp, err);
3772 goto fail;
3774 } else {
3775 con = NULL;
3778 if (con != vd->dcl.con) {
3779 unregister_displaychangelistener(&vd->dcl);
3780 vd->dcl.con = con;
3781 register_displaychangelistener(&vd->dcl);
3784 if (reverse) {
3785 /* connect to viewer */
3786 QIOChannelSocket *sioc = NULL;
3787 vd->lsock = NULL;
3788 vd->lwebsock = NULL;
3789 if (ws_enabled) {
3790 error_setg(errp, "Cannot use websockets in reverse mode");
3791 goto fail;
3793 vd->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3794 sioc = qio_channel_socket_new();
3795 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3796 if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
3797 goto fail;
3799 vnc_connect(vd, sioc, false, false);
3800 object_unref(OBJECT(sioc));
3801 } else {
3802 vd->lsock = qio_channel_socket_new();
3803 qio_channel_set_name(QIO_CHANNEL(vd->lsock), "vnc-listen");
3804 if (qio_channel_socket_listen_sync(vd->lsock, saddr, errp) < 0) {
3805 goto fail;
3807 vd->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3809 if (ws_enabled) {
3810 vd->lwebsock = qio_channel_socket_new();
3811 qio_channel_set_name(QIO_CHANNEL(vd->lwebsock), "vnc-ws-listen");
3812 if (qio_channel_socket_listen_sync(vd->lwebsock,
3813 wsaddr, errp) < 0) {
3814 object_unref(OBJECT(vd->lsock));
3815 vd->lsock = NULL;
3816 goto fail;
3820 vd->lsock_tag = qio_channel_add_watch(
3821 QIO_CHANNEL(vd->lsock),
3822 G_IO_IN, vnc_listen_io, vd, NULL);
3823 if (ws_enabled) {
3824 vd->lwebsock_tag = qio_channel_add_watch(
3825 QIO_CHANNEL(vd->lwebsock),
3826 G_IO_IN, vnc_listen_io, vd, NULL);
3830 if (show_vnc_port) {
3831 vnc_display_print_local_addr(vd);
3834 qapi_free_SocketAddress(saddr);
3835 qapi_free_SocketAddress(wsaddr);
3836 return;
3838 fail:
3839 qapi_free_SocketAddress(saddr);
3840 qapi_free_SocketAddress(wsaddr);
3841 ws_enabled = false;
3844 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3846 VncDisplay *vd = vnc_display_find(id);
3847 QIOChannelSocket *sioc;
3849 if (!vd) {
3850 return;
3853 sioc = qio_channel_socket_new_fd(csock, NULL);
3854 if (sioc) {
3855 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
3856 vnc_connect(vd, sioc, skipauth, false);
3857 object_unref(OBJECT(sioc));
3861 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3863 int i = 2;
3864 char *id;
3866 id = g_strdup("default");
3867 while (qemu_opts_find(olist, id)) {
3868 g_free(id);
3869 id = g_strdup_printf("vnc%d", i++);
3871 qemu_opts_set_id(opts, id);
3874 QemuOpts *vnc_parse(const char *str, Error **errp)
3876 QemuOptsList *olist = qemu_find_opts("vnc");
3877 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3878 const char *id;
3880 if (!opts) {
3881 return NULL;
3884 id = qemu_opts_id(opts);
3885 if (!id) {
3886 /* auto-assign id if not present */
3887 vnc_auto_assign_id(olist, opts);
3889 return opts;
3892 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3894 Error *local_err = NULL;
3895 char *id = (char *)qemu_opts_id(opts);
3897 assert(id);
3898 vnc_display_init(id);
3899 vnc_display_open(id, &local_err);
3900 if (local_err != NULL) {
3901 error_reportf_err(local_err, "Failed to start VNC server: ");
3902 exit(1);
3904 return 0;
3907 static void vnc_register_config(void)
3909 qemu_add_opts(&qemu_vnc_opts);
3911 opts_init(vnc_register_config);