pcie: Don't try triggering a LSI when not defined
[qemu/rayw.git] / ui / vnc.c
blob6261d922953b4825158603bdc7af07a1df7cd71d
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-core.h"
32 #include "sysemu/sysemu.h"
33 #include "sysemu/runstate.h"
34 #include "qemu/error-report.h"
35 #include "qemu/main-loop.h"
36 #include "qemu/module.h"
37 #include "qemu/option.h"
38 #include "qemu/sockets.h"
39 #include "qemu/timer.h"
40 #include "authz/list.h"
41 #include "qemu/config-file.h"
42 #include "qapi/qapi-emit-events.h"
43 #include "qapi/qapi-events-ui.h"
44 #include "qapi/error.h"
45 #include "qapi/qapi-commands-ui.h"
46 #include "ui/input.h"
47 #include "crypto/hash.h"
48 #include "crypto/tlscreds.h"
49 #include "crypto/tlscredsanon.h"
50 #include "crypto/tlscredsx509.h"
51 #include "crypto/random.h"
52 #include "crypto/secret_common.h"
53 #include "qom/object_interfaces.h"
54 #include "qemu/cutils.h"
55 #include "qemu/help_option.h"
56 #include "io/dns-resolver.h"
58 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
59 #define VNC_REFRESH_INTERVAL_INC 50
60 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
61 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
62 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
64 #include "vnc_keysym.h"
65 #include "crypto/cipher.h"
67 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
68 QTAILQ_HEAD_INITIALIZER(vnc_displays);
70 static int vnc_cursor_define(VncState *vs);
71 static void vnc_update_throttle_offset(VncState *vs);
73 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
75 #ifdef _VNC_DEBUG
76 static const char *mn[] = {
77 [0] = "undefined",
78 [VNC_SHARE_MODE_CONNECTING] = "connecting",
79 [VNC_SHARE_MODE_SHARED] = "shared",
80 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
81 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
83 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
84 vs->ioc, mn[vs->share_mode], mn[mode]);
85 #endif
87 switch (vs->share_mode) {
88 case VNC_SHARE_MODE_CONNECTING:
89 vs->vd->num_connecting--;
90 break;
91 case VNC_SHARE_MODE_SHARED:
92 vs->vd->num_shared--;
93 break;
94 case VNC_SHARE_MODE_EXCLUSIVE:
95 vs->vd->num_exclusive--;
96 break;
97 default:
98 break;
101 vs->share_mode = mode;
103 switch (vs->share_mode) {
104 case VNC_SHARE_MODE_CONNECTING:
105 vs->vd->num_connecting++;
106 break;
107 case VNC_SHARE_MODE_SHARED:
108 vs->vd->num_shared++;
109 break;
110 case VNC_SHARE_MODE_EXCLUSIVE:
111 vs->vd->num_exclusive++;
112 break;
113 default:
114 break;
119 static void vnc_init_basic_info(SocketAddress *addr,
120 VncBasicInfo *info,
121 Error **errp)
123 switch (addr->type) {
124 case SOCKET_ADDRESS_TYPE_INET:
125 info->host = g_strdup(addr->u.inet.host);
126 info->service = g_strdup(addr->u.inet.port);
127 if (addr->u.inet.ipv6) {
128 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
129 } else {
130 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
132 break;
134 case SOCKET_ADDRESS_TYPE_UNIX:
135 info->host = g_strdup("");
136 info->service = g_strdup(addr->u.q_unix.path);
137 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
138 break;
140 case SOCKET_ADDRESS_TYPE_VSOCK:
141 case SOCKET_ADDRESS_TYPE_FD:
142 error_setg(errp, "Unsupported socket address type %s",
143 SocketAddressType_str(addr->type));
144 break;
145 default:
146 abort();
149 return;
152 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
153 VncBasicInfo *info,
154 Error **errp)
156 SocketAddress *addr = NULL;
158 if (!ioc) {
159 error_setg(errp, "No listener socket available");
160 return;
163 addr = qio_channel_socket_get_local_address(ioc, errp);
164 if (!addr) {
165 return;
168 vnc_init_basic_info(addr, info, errp);
169 qapi_free_SocketAddress(addr);
172 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
173 VncBasicInfo *info,
174 Error **errp)
176 SocketAddress *addr = NULL;
178 addr = qio_channel_socket_get_remote_address(ioc, errp);
179 if (!addr) {
180 return;
183 vnc_init_basic_info(addr, info, errp);
184 qapi_free_SocketAddress(addr);
187 static const char *vnc_auth_name(VncDisplay *vd) {
188 switch (vd->auth) {
189 case VNC_AUTH_INVALID:
190 return "invalid";
191 case VNC_AUTH_NONE:
192 return "none";
193 case VNC_AUTH_VNC:
194 return "vnc";
195 case VNC_AUTH_RA2:
196 return "ra2";
197 case VNC_AUTH_RA2NE:
198 return "ra2ne";
199 case VNC_AUTH_TIGHT:
200 return "tight";
201 case VNC_AUTH_ULTRA:
202 return "ultra";
203 case VNC_AUTH_TLS:
204 return "tls";
205 case VNC_AUTH_VENCRYPT:
206 switch (vd->subauth) {
207 case VNC_AUTH_VENCRYPT_PLAIN:
208 return "vencrypt+plain";
209 case VNC_AUTH_VENCRYPT_TLSNONE:
210 return "vencrypt+tls+none";
211 case VNC_AUTH_VENCRYPT_TLSVNC:
212 return "vencrypt+tls+vnc";
213 case VNC_AUTH_VENCRYPT_TLSPLAIN:
214 return "vencrypt+tls+plain";
215 case VNC_AUTH_VENCRYPT_X509NONE:
216 return "vencrypt+x509+none";
217 case VNC_AUTH_VENCRYPT_X509VNC:
218 return "vencrypt+x509+vnc";
219 case VNC_AUTH_VENCRYPT_X509PLAIN:
220 return "vencrypt+x509+plain";
221 case VNC_AUTH_VENCRYPT_TLSSASL:
222 return "vencrypt+tls+sasl";
223 case VNC_AUTH_VENCRYPT_X509SASL:
224 return "vencrypt+x509+sasl";
225 default:
226 return "vencrypt";
228 case VNC_AUTH_SASL:
229 return "sasl";
231 return "unknown";
234 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
236 VncServerInfo *info;
237 Error *err = NULL;
239 if (!vd->listener || !vd->listener->nsioc) {
240 return NULL;
243 info = g_malloc0(sizeof(*info));
244 vnc_init_basic_info_from_server_addr(vd->listener->sioc[0],
245 qapi_VncServerInfo_base(info), &err);
246 info->has_auth = true;
247 info->auth = g_strdup(vnc_auth_name(vd));
248 if (err) {
249 qapi_free_VncServerInfo(info);
250 info = NULL;
251 error_free(err);
253 return info;
256 static void vnc_client_cache_auth(VncState *client)
258 if (!client->info) {
259 return;
262 if (client->tls) {
263 client->info->x509_dname =
264 qcrypto_tls_session_get_peer_name(client->tls);
265 client->info->has_x509_dname =
266 client->info->x509_dname != NULL;
268 #ifdef CONFIG_VNC_SASL
269 if (client->sasl.conn &&
270 client->sasl.username) {
271 client->info->has_sasl_username = true;
272 client->info->sasl_username = g_strdup(client->sasl.username);
274 #endif
277 static void vnc_client_cache_addr(VncState *client)
279 Error *err = NULL;
281 client->info = g_malloc0(sizeof(*client->info));
282 vnc_init_basic_info_from_remote_addr(client->sioc,
283 qapi_VncClientInfo_base(client->info),
284 &err);
285 client->info->websocket = client->websocket;
286 if (err) {
287 qapi_free_VncClientInfo(client->info);
288 client->info = NULL;
289 error_free(err);
293 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
295 VncServerInfo *si;
297 if (!vs->info) {
298 return;
301 si = vnc_server_info_get(vs->vd);
302 if (!si) {
303 return;
306 switch (event) {
307 case QAPI_EVENT_VNC_CONNECTED:
308 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info));
309 break;
310 case QAPI_EVENT_VNC_INITIALIZED:
311 qapi_event_send_vnc_initialized(si, vs->info);
312 break;
313 case QAPI_EVENT_VNC_DISCONNECTED:
314 qapi_event_send_vnc_disconnected(si, vs->info);
315 break;
316 default:
317 break;
320 qapi_free_VncServerInfo(si);
323 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
325 VncClientInfo *info;
326 Error *err = NULL;
328 info = g_malloc0(sizeof(*info));
330 vnc_init_basic_info_from_remote_addr(client->sioc,
331 qapi_VncClientInfo_base(info),
332 &err);
333 if (err) {
334 error_free(err);
335 qapi_free_VncClientInfo(info);
336 return NULL;
339 info->websocket = client->websocket;
341 if (client->tls) {
342 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
343 info->has_x509_dname = info->x509_dname != NULL;
345 #ifdef CONFIG_VNC_SASL
346 if (client->sasl.conn && client->sasl.username) {
347 info->has_sasl_username = true;
348 info->sasl_username = g_strdup(client->sasl.username);
350 #endif
352 return info;
355 static VncDisplay *vnc_display_find(const char *id)
357 VncDisplay *vd;
359 if (id == NULL) {
360 return QTAILQ_FIRST(&vnc_displays);
362 QTAILQ_FOREACH(vd, &vnc_displays, next) {
363 if (strcmp(id, vd->id) == 0) {
364 return vd;
367 return NULL;
370 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
372 VncClientInfoList *prev = NULL;
373 VncState *client;
375 QTAILQ_FOREACH(client, &vd->clients, next) {
376 QAPI_LIST_PREPEND(prev, qmp_query_vnc_client(client));
378 return prev;
381 VncInfo *qmp_query_vnc(Error **errp)
383 VncInfo *info = g_malloc0(sizeof(*info));
384 VncDisplay *vd = vnc_display_find(NULL);
385 SocketAddress *addr = NULL;
387 if (vd == NULL || !vd->listener || !vd->listener->nsioc) {
388 info->enabled = false;
389 } else {
390 info->enabled = true;
392 /* for compatibility with the original command */
393 info->has_clients = true;
394 info->clients = qmp_query_client_list(vd);
396 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0],
397 errp);
398 if (!addr) {
399 goto out_error;
402 switch (addr->type) {
403 case SOCKET_ADDRESS_TYPE_INET:
404 info->host = g_strdup(addr->u.inet.host);
405 info->service = g_strdup(addr->u.inet.port);
406 if (addr->u.inet.ipv6) {
407 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
408 } else {
409 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
411 break;
413 case SOCKET_ADDRESS_TYPE_UNIX:
414 info->host = g_strdup("");
415 info->service = g_strdup(addr->u.q_unix.path);
416 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
417 break;
419 case SOCKET_ADDRESS_TYPE_VSOCK:
420 case SOCKET_ADDRESS_TYPE_FD:
421 error_setg(errp, "Unsupported socket address type %s",
422 SocketAddressType_str(addr->type));
423 goto out_error;
424 default:
425 abort();
428 info->has_host = true;
429 info->has_service = true;
430 info->has_family = true;
432 info->has_auth = true;
433 info->auth = g_strdup(vnc_auth_name(vd));
436 qapi_free_SocketAddress(addr);
437 return info;
439 out_error:
440 qapi_free_SocketAddress(addr);
441 qapi_free_VncInfo(info);
442 return NULL;
446 static void qmp_query_auth(int auth, int subauth,
447 VncPrimaryAuth *qmp_auth,
448 VncVencryptSubAuth *qmp_vencrypt,
449 bool *qmp_has_vencrypt);
451 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
452 bool websocket,
453 int auth,
454 int subauth,
455 VncServerInfo2List *prev)
457 VncServerInfo2 *info;
458 Error *err = NULL;
459 SocketAddress *addr;
461 addr = qio_channel_socket_get_local_address(ioc, NULL);
462 if (!addr) {
463 return prev;
466 info = g_new0(VncServerInfo2, 1);
467 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
468 qapi_free_SocketAddress(addr);
469 if (err) {
470 qapi_free_VncServerInfo2(info);
471 error_free(err);
472 return prev;
474 info->websocket = websocket;
476 qmp_query_auth(auth, subauth, &info->auth,
477 &info->vencrypt, &info->has_vencrypt);
479 QAPI_LIST_PREPEND(prev, info);
480 return prev;
483 static void qmp_query_auth(int auth, int subauth,
484 VncPrimaryAuth *qmp_auth,
485 VncVencryptSubAuth *qmp_vencrypt,
486 bool *qmp_has_vencrypt)
488 switch (auth) {
489 case VNC_AUTH_VNC:
490 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
491 break;
492 case VNC_AUTH_RA2:
493 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
494 break;
495 case VNC_AUTH_RA2NE:
496 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
497 break;
498 case VNC_AUTH_TIGHT:
499 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
500 break;
501 case VNC_AUTH_ULTRA:
502 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
503 break;
504 case VNC_AUTH_TLS:
505 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
506 break;
507 case VNC_AUTH_VENCRYPT:
508 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
509 *qmp_has_vencrypt = true;
510 switch (subauth) {
511 case VNC_AUTH_VENCRYPT_PLAIN:
512 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
513 break;
514 case VNC_AUTH_VENCRYPT_TLSNONE:
515 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
516 break;
517 case VNC_AUTH_VENCRYPT_TLSVNC:
518 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
519 break;
520 case VNC_AUTH_VENCRYPT_TLSPLAIN:
521 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
522 break;
523 case VNC_AUTH_VENCRYPT_X509NONE:
524 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
525 break;
526 case VNC_AUTH_VENCRYPT_X509VNC:
527 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
528 break;
529 case VNC_AUTH_VENCRYPT_X509PLAIN:
530 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
531 break;
532 case VNC_AUTH_VENCRYPT_TLSSASL:
533 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
534 break;
535 case VNC_AUTH_VENCRYPT_X509SASL:
536 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
537 break;
538 default:
539 *qmp_has_vencrypt = false;
540 break;
542 break;
543 case VNC_AUTH_SASL:
544 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
545 break;
546 case VNC_AUTH_NONE:
547 default:
548 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
549 break;
553 VncInfo2List *qmp_query_vnc_servers(Error **errp)
555 VncInfo2List *prev = NULL;
556 VncInfo2 *info;
557 VncDisplay *vd;
558 DeviceState *dev;
559 size_t i;
561 QTAILQ_FOREACH(vd, &vnc_displays, next) {
562 info = g_new0(VncInfo2, 1);
563 info->id = g_strdup(vd->id);
564 info->clients = qmp_query_client_list(vd);
565 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
566 &info->vencrypt, &info->has_vencrypt);
567 if (vd->dcl.con) {
568 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
569 "device", &error_abort));
570 info->has_display = true;
571 info->display = g_strdup(dev->id);
573 for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) {
574 info->server = qmp_query_server_entry(
575 vd->listener->sioc[i], false, vd->auth, vd->subauth,
576 info->server);
578 for (i = 0; vd->wslistener != NULL && i < vd->wslistener->nsioc; i++) {
579 info->server = qmp_query_server_entry(
580 vd->wslistener->sioc[i], true, vd->ws_auth,
581 vd->ws_subauth, info->server);
584 QAPI_LIST_PREPEND(prev, info);
586 return prev;
589 bool vnc_display_reload_certs(const char *id, Error **errp)
591 VncDisplay *vd = vnc_display_find(id);
592 QCryptoTLSCredsClass *creds = NULL;
594 if (!vd) {
595 error_setg(errp, "Can not find vnc display");
596 return false;
599 if (!vd->tlscreds) {
600 error_setg(errp, "vnc tls is not enabled");
601 return false;
604 creds = QCRYPTO_TLS_CREDS_GET_CLASS(OBJECT(vd->tlscreds));
605 if (creds->reload == NULL) {
606 error_setg(errp, "%s doesn't support to reload TLS credential",
607 object_get_typename(OBJECT(vd->tlscreds)));
608 return false;
610 if (!creds->reload(vd->tlscreds, errp)) {
611 return false;
614 return true;
617 /* TODO
618 1) Get the queue working for IO.
619 2) there is some weirdness when using the -S option (the screen is grey
620 and not totally invalidated
621 3) resolutions > 1024
624 static int vnc_update_client(VncState *vs, int has_dirty);
625 static void vnc_disconnect_start(VncState *vs);
627 static void vnc_colordepth(VncState *vs);
628 static void framebuffer_update_request(VncState *vs, int incremental,
629 int x_position, int y_position,
630 int w, int h);
631 static void vnc_refresh(DisplayChangeListener *dcl);
632 static int vnc_refresh_server_surface(VncDisplay *vd);
634 static int vnc_width(VncDisplay *vd)
636 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
637 VNC_DIRTY_PIXELS_PER_BIT));
640 static int vnc_true_width(VncDisplay *vd)
642 return MIN(VNC_MAX_WIDTH, surface_width(vd->ds));
645 static int vnc_height(VncDisplay *vd)
647 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
650 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
651 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
652 VncDisplay *vd,
653 int x, int y, int w, int h)
655 int width = vnc_width(vd);
656 int height = vnc_height(vd);
658 /* this is needed this to ensure we updated all affected
659 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
660 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
661 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
663 x = MIN(x, width);
664 y = MIN(y, height);
665 w = MIN(x + w, width) - x;
666 h = MIN(y + h, height);
668 for (; y < h; y++) {
669 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
670 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
674 static void vnc_dpy_update(DisplayChangeListener *dcl,
675 int x, int y, int w, int h)
677 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
678 struct VncSurface *s = &vd->guest;
680 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
683 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
684 int32_t encoding)
686 vnc_write_u16(vs, x);
687 vnc_write_u16(vs, y);
688 vnc_write_u16(vs, w);
689 vnc_write_u16(vs, h);
691 vnc_write_s32(vs, encoding);
694 static void vnc_desktop_resize_ext(VncState *vs, int reject_reason)
696 trace_vnc_msg_server_ext_desktop_resize(
697 vs, vs->ioc, vs->client_width, vs->client_height, reject_reason);
699 vnc_lock_output(vs);
700 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
701 vnc_write_u8(vs, 0);
702 vnc_write_u16(vs, 1); /* number of rects */
703 vnc_framebuffer_update(vs,
704 reject_reason ? 1 : 0,
705 reject_reason,
706 vs->client_width, vs->client_height,
707 VNC_ENCODING_DESKTOP_RESIZE_EXT);
708 vnc_write_u8(vs, 1); /* number of screens */
709 vnc_write_u8(vs, 0); /* padding */
710 vnc_write_u8(vs, 0); /* padding */
711 vnc_write_u8(vs, 0); /* padding */
712 vnc_write_u32(vs, 0); /* screen id */
713 vnc_write_u16(vs, 0); /* screen x-pos */
714 vnc_write_u16(vs, 0); /* screen y-pos */
715 vnc_write_u16(vs, vs->client_width);
716 vnc_write_u16(vs, vs->client_height);
717 vnc_write_u32(vs, 0); /* screen flags */
718 vnc_unlock_output(vs);
719 vnc_flush(vs);
722 static void vnc_desktop_resize(VncState *vs)
724 if (vs->ioc == NULL || (!vnc_has_feature(vs, VNC_FEATURE_RESIZE) &&
725 !vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT))) {
726 return;
728 if (vs->client_width == vs->vd->true_width &&
729 vs->client_height == pixman_image_get_height(vs->vd->server)) {
730 return;
733 assert(vs->vd->true_width < 65536 &&
734 vs->vd->true_width >= 0);
735 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
736 pixman_image_get_height(vs->vd->server) >= 0);
737 vs->client_width = vs->vd->true_width;
738 vs->client_height = pixman_image_get_height(vs->vd->server);
740 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
741 vnc_desktop_resize_ext(vs, 0);
742 return;
745 trace_vnc_msg_server_desktop_resize(
746 vs, vs->ioc, vs->client_width, vs->client_height);
748 vnc_lock_output(vs);
749 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
750 vnc_write_u8(vs, 0);
751 vnc_write_u16(vs, 1); /* number of rects */
752 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
753 VNC_ENCODING_DESKTOPRESIZE);
754 vnc_unlock_output(vs);
755 vnc_flush(vs);
758 static void vnc_abort_display_jobs(VncDisplay *vd)
760 VncState *vs;
762 QTAILQ_FOREACH(vs, &vd->clients, next) {
763 vnc_lock_output(vs);
764 vs->abort = true;
765 vnc_unlock_output(vs);
767 QTAILQ_FOREACH(vs, &vd->clients, next) {
768 vnc_jobs_join(vs);
770 QTAILQ_FOREACH(vs, &vd->clients, next) {
771 vnc_lock_output(vs);
772 if (vs->update == VNC_STATE_UPDATE_NONE &&
773 vs->job_update != VNC_STATE_UPDATE_NONE) {
774 /* job aborted before completion */
775 vs->update = vs->job_update;
776 vs->job_update = VNC_STATE_UPDATE_NONE;
778 vs->abort = false;
779 vnc_unlock_output(vs);
783 int vnc_server_fb_stride(VncDisplay *vd)
785 return pixman_image_get_stride(vd->server);
788 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
790 uint8_t *ptr;
792 ptr = (uint8_t *)pixman_image_get_data(vd->server);
793 ptr += y * vnc_server_fb_stride(vd);
794 ptr += x * VNC_SERVER_FB_BYTES;
795 return ptr;
798 static void vnc_update_server_surface(VncDisplay *vd)
800 int width, height;
802 qemu_pixman_image_unref(vd->server);
803 vd->server = NULL;
805 if (QTAILQ_EMPTY(&vd->clients)) {
806 return;
809 width = vnc_width(vd);
810 height = vnc_height(vd);
811 vd->true_width = vnc_true_width(vd);
812 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
813 width, height,
814 NULL, 0);
816 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
817 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
818 width, height);
821 static bool vnc_check_pageflip(DisplaySurface *s1,
822 DisplaySurface *s2)
824 return (s1 != NULL &&
825 s2 != NULL &&
826 surface_width(s1) == surface_width(s2) &&
827 surface_height(s1) == surface_height(s2) &&
828 surface_format(s1) == surface_format(s2));
832 static void vnc_dpy_switch(DisplayChangeListener *dcl,
833 DisplaySurface *surface)
835 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
836 bool pageflip = vnc_check_pageflip(vd->ds, surface);
837 VncState *vs;
839 vnc_abort_display_jobs(vd);
840 vd->ds = surface;
842 /* guest surface */
843 qemu_pixman_image_unref(vd->guest.fb);
844 vd->guest.fb = pixman_image_ref(surface->image);
845 vd->guest.format = surface->format;
848 if (pageflip) {
849 trace_vnc_server_dpy_pageflip(vd,
850 surface_width(surface),
851 surface_height(surface),
852 surface_format(surface));
853 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
854 surface_width(surface),
855 surface_height(surface));
856 return;
859 trace_vnc_server_dpy_recreate(vd,
860 surface_width(surface),
861 surface_height(surface),
862 surface_format(surface));
863 /* server surface */
864 vnc_update_server_surface(vd);
866 QTAILQ_FOREACH(vs, &vd->clients, next) {
867 vnc_colordepth(vs);
868 vnc_desktop_resize(vs);
869 vnc_cursor_define(vs);
870 memset(vs->dirty, 0x00, sizeof(vs->dirty));
871 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
872 vnc_width(vd),
873 vnc_height(vd));
874 vnc_update_throttle_offset(vs);
878 /* fastest code */
879 static void vnc_write_pixels_copy(VncState *vs,
880 void *pixels, int size)
882 vnc_write(vs, pixels, size);
885 /* slowest but generic code. */
886 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
888 uint8_t r, g, b;
890 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
891 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
892 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
893 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
894 #else
895 # error need some bits here if you change VNC_SERVER_FB_FORMAT
896 #endif
897 v = (r << vs->client_pf.rshift) |
898 (g << vs->client_pf.gshift) |
899 (b << vs->client_pf.bshift);
900 switch (vs->client_pf.bytes_per_pixel) {
901 case 1:
902 buf[0] = v;
903 break;
904 case 2:
905 if (vs->client_be) {
906 buf[0] = v >> 8;
907 buf[1] = v;
908 } else {
909 buf[1] = v >> 8;
910 buf[0] = v;
912 break;
913 default:
914 case 4:
915 if (vs->client_be) {
916 buf[0] = v >> 24;
917 buf[1] = v >> 16;
918 buf[2] = v >> 8;
919 buf[3] = v;
920 } else {
921 buf[3] = v >> 24;
922 buf[2] = v >> 16;
923 buf[1] = v >> 8;
924 buf[0] = v;
926 break;
930 static void vnc_write_pixels_generic(VncState *vs,
931 void *pixels1, int size)
933 uint8_t buf[4];
935 if (VNC_SERVER_FB_BYTES == 4) {
936 uint32_t *pixels = pixels1;
937 int n, i;
938 n = size >> 2;
939 for (i = 0; i < n; i++) {
940 vnc_convert_pixel(vs, buf, pixels[i]);
941 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
946 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
948 int i;
949 uint8_t *row;
950 VncDisplay *vd = vs->vd;
952 row = vnc_server_fb_ptr(vd, x, y);
953 for (i = 0; i < h; i++) {
954 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
955 row += vnc_server_fb_stride(vd);
957 return 1;
960 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
962 int n = 0;
964 switch(vs->vnc_encoding) {
965 case VNC_ENCODING_ZLIB:
966 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
967 break;
968 case VNC_ENCODING_HEXTILE:
969 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
970 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
971 break;
972 case VNC_ENCODING_TIGHT:
973 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
974 break;
975 case VNC_ENCODING_TIGHT_PNG:
976 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
977 break;
978 case VNC_ENCODING_ZRLE:
979 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
980 break;
981 case VNC_ENCODING_ZYWRLE:
982 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
983 break;
984 default:
985 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
986 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
987 break;
989 return n;
992 static void vnc_mouse_set(DisplayChangeListener *dcl,
993 int x, int y, int visible)
995 /* can we ask the client(s) to move the pointer ??? */
998 static int vnc_cursor_define(VncState *vs)
1000 QEMUCursor *c = vs->vd->cursor;
1001 int isize;
1003 if (!vs->vd->cursor) {
1004 return -1;
1007 if (vnc_has_feature(vs, VNC_FEATURE_ALPHA_CURSOR)) {
1008 vnc_lock_output(vs);
1009 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1010 vnc_write_u8(vs, 0); /* padding */
1011 vnc_write_u16(vs, 1); /* # of rects */
1012 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1013 VNC_ENCODING_ALPHA_CURSOR);
1014 vnc_write_s32(vs, VNC_ENCODING_RAW);
1015 vnc_write(vs, c->data, c->width * c->height * 4);
1016 vnc_unlock_output(vs);
1017 return 0;
1019 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
1020 vnc_lock_output(vs);
1021 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1022 vnc_write_u8(vs, 0); /* padding */
1023 vnc_write_u16(vs, 1); /* # of rects */
1024 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1025 VNC_ENCODING_RICH_CURSOR);
1026 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
1027 vnc_write_pixels_generic(vs, c->data, isize);
1028 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
1029 vnc_unlock_output(vs);
1030 return 0;
1032 return -1;
1035 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1036 QEMUCursor *c)
1038 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1039 VncState *vs;
1041 cursor_put(vd->cursor);
1042 g_free(vd->cursor_mask);
1044 vd->cursor = c;
1045 cursor_get(vd->cursor);
1046 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1047 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1048 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1050 QTAILQ_FOREACH(vs, &vd->clients, next) {
1051 vnc_cursor_define(vs);
1055 static int find_and_clear_dirty_height(VncState *vs,
1056 int y, int last_x, int x, int height)
1058 int h;
1060 for (h = 1; h < (height - y); h++) {
1061 if (!test_bit(last_x, vs->dirty[y + h])) {
1062 break;
1064 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1067 return h;
1071 * Figure out how much pending data we should allow in the output
1072 * buffer before we throttle incremental display updates, and/or
1073 * drop audio samples.
1075 * We allow for equiv of 1 full display's worth of FB updates,
1076 * and 1 second of audio samples. If audio backlog was larger
1077 * than that the client would already suffering awful audio
1078 * glitches, so dropping samples is no worse really).
1080 static void vnc_update_throttle_offset(VncState *vs)
1082 size_t offset =
1083 vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
1085 if (vs->audio_cap) {
1086 int bps;
1087 switch (vs->as.fmt) {
1088 default:
1089 case AUDIO_FORMAT_U8:
1090 case AUDIO_FORMAT_S8:
1091 bps = 1;
1092 break;
1093 case AUDIO_FORMAT_U16:
1094 case AUDIO_FORMAT_S16:
1095 bps = 2;
1096 break;
1097 case AUDIO_FORMAT_U32:
1098 case AUDIO_FORMAT_S32:
1099 bps = 4;
1100 break;
1102 offset += vs->as.freq * bps * vs->as.nchannels;
1105 /* Put a floor of 1MB on offset, so that if we have a large pending
1106 * buffer and the display is resized to a small size & back again
1107 * we don't suddenly apply a tiny send limit
1109 offset = MAX(offset, 1024 * 1024);
1111 if (vs->throttle_output_offset != offset) {
1112 trace_vnc_client_throttle_threshold(
1113 vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
1114 vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
1117 vs->throttle_output_offset = offset;
1120 static bool vnc_should_update(VncState *vs)
1122 switch (vs->update) {
1123 case VNC_STATE_UPDATE_NONE:
1124 break;
1125 case VNC_STATE_UPDATE_INCREMENTAL:
1126 /* Only allow incremental updates if the pending send queue
1127 * is less than the permitted threshold, and the job worker
1128 * is completely idle.
1130 if (vs->output.offset < vs->throttle_output_offset &&
1131 vs->job_update == VNC_STATE_UPDATE_NONE) {
1132 return true;
1134 trace_vnc_client_throttle_incremental(
1135 vs, vs->ioc, vs->job_update, vs->output.offset);
1136 break;
1137 case VNC_STATE_UPDATE_FORCE:
1138 /* Only allow forced updates if the pending send queue
1139 * does not contain a previous forced update, and the
1140 * job worker is completely idle.
1142 * Note this means we'll queue a forced update, even if
1143 * the output buffer size is otherwise over the throttle
1144 * output limit.
1146 if (vs->force_update_offset == 0 &&
1147 vs->job_update == VNC_STATE_UPDATE_NONE) {
1148 return true;
1150 trace_vnc_client_throttle_forced(
1151 vs, vs->ioc, vs->job_update, vs->force_update_offset);
1152 break;
1154 return false;
1157 static int vnc_update_client(VncState *vs, int has_dirty)
1159 VncDisplay *vd = vs->vd;
1160 VncJob *job;
1161 int y;
1162 int height, width;
1163 int n = 0;
1165 if (vs->disconnecting) {
1166 vnc_disconnect_finish(vs);
1167 return 0;
1170 vs->has_dirty += has_dirty;
1171 if (!vnc_should_update(vs)) {
1172 return 0;
1175 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
1176 return 0;
1180 * Send screen updates to the vnc client using the server
1181 * surface and server dirty map. guest surface updates
1182 * happening in parallel don't disturb us, the next pass will
1183 * send them to the client.
1185 job = vnc_job_new(vs);
1187 height = pixman_image_get_height(vd->server);
1188 width = pixman_image_get_width(vd->server);
1190 y = 0;
1191 for (;;) {
1192 int x, h;
1193 unsigned long x2;
1194 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1195 height * VNC_DIRTY_BPL(vs),
1196 y * VNC_DIRTY_BPL(vs));
1197 if (offset == height * VNC_DIRTY_BPL(vs)) {
1198 /* no more dirty bits */
1199 break;
1201 y = offset / VNC_DIRTY_BPL(vs);
1202 x = offset % VNC_DIRTY_BPL(vs);
1203 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1204 VNC_DIRTY_BPL(vs), x);
1205 bitmap_clear(vs->dirty[y], x, x2 - x);
1206 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1207 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1208 if (x2 > x) {
1209 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1210 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1212 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1213 y += h;
1214 if (y == height) {
1215 break;
1220 vs->job_update = vs->update;
1221 vs->update = VNC_STATE_UPDATE_NONE;
1222 vnc_job_push(job);
1223 vs->has_dirty = 0;
1224 return n;
1227 /* audio */
1228 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1230 VncState *vs = opaque;
1232 assert(vs->magic == VNC_MAGIC);
1233 switch (cmd) {
1234 case AUD_CNOTIFY_DISABLE:
1235 trace_vnc_msg_server_audio_end(vs, vs->ioc);
1236 vnc_lock_output(vs);
1237 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1238 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1239 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1240 vnc_unlock_output(vs);
1241 vnc_flush(vs);
1242 break;
1244 case AUD_CNOTIFY_ENABLE:
1245 trace_vnc_msg_server_audio_begin(vs, vs->ioc);
1246 vnc_lock_output(vs);
1247 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1248 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1249 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1250 vnc_unlock_output(vs);
1251 vnc_flush(vs);
1252 break;
1256 static void audio_capture_destroy(void *opaque)
1260 static void audio_capture(void *opaque, const void *buf, int size)
1262 VncState *vs = opaque;
1264 assert(vs->magic == VNC_MAGIC);
1265 trace_vnc_msg_server_audio_data(vs, vs->ioc, buf, size);
1266 vnc_lock_output(vs);
1267 if (vs->output.offset < vs->throttle_output_offset) {
1268 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1269 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1270 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1271 vnc_write_u32(vs, size);
1272 vnc_write(vs, buf, size);
1273 } else {
1274 trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
1276 vnc_unlock_output(vs);
1277 vnc_flush(vs);
1280 static void audio_add(VncState *vs)
1282 struct audio_capture_ops ops;
1284 if (vs->audio_cap) {
1285 error_report("audio already running");
1286 return;
1289 ops.notify = audio_capture_notify;
1290 ops.destroy = audio_capture_destroy;
1291 ops.capture = audio_capture;
1293 vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs);
1294 if (!vs->audio_cap) {
1295 error_report("Failed to add audio capture");
1299 static void audio_del(VncState *vs)
1301 if (vs->audio_cap) {
1302 AUD_del_capture(vs->audio_cap, vs);
1303 vs->audio_cap = NULL;
1307 static void vnc_disconnect_start(VncState *vs)
1309 if (vs->disconnecting) {
1310 return;
1312 trace_vnc_client_disconnect_start(vs, vs->ioc);
1313 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1314 if (vs->ioc_tag) {
1315 g_source_remove(vs->ioc_tag);
1316 vs->ioc_tag = 0;
1318 qio_channel_close(vs->ioc, NULL);
1319 vs->disconnecting = TRUE;
1322 void vnc_disconnect_finish(VncState *vs)
1324 int i;
1326 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1328 vnc_jobs_join(vs); /* Wait encoding jobs */
1330 vnc_lock_output(vs);
1331 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1333 buffer_free(&vs->input);
1334 buffer_free(&vs->output);
1336 qapi_free_VncClientInfo(vs->info);
1338 vnc_zlib_clear(vs);
1339 vnc_tight_clear(vs);
1340 vnc_zrle_clear(vs);
1342 #ifdef CONFIG_VNC_SASL
1343 vnc_sasl_client_cleanup(vs);
1344 #endif /* CONFIG_VNC_SASL */
1345 audio_del(vs);
1346 qkbd_state_lift_all_keys(vs->vd->kbd);
1348 if (vs->mouse_mode_notifier.notify != NULL) {
1349 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1351 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1352 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1353 /* last client gone */
1354 vnc_update_server_surface(vs->vd);
1356 vnc_unlock_output(vs);
1358 if (vs->cbpeer.notifier.notify) {
1359 qemu_clipboard_peer_unregister(&vs->cbpeer);
1362 qemu_mutex_destroy(&vs->output_mutex);
1363 if (vs->bh != NULL) {
1364 qemu_bh_delete(vs->bh);
1366 buffer_free(&vs->jobs_buffer);
1368 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1369 g_free(vs->lossy_rect[i]);
1371 g_free(vs->lossy_rect);
1373 object_unref(OBJECT(vs->ioc));
1374 vs->ioc = NULL;
1375 object_unref(OBJECT(vs->sioc));
1376 vs->sioc = NULL;
1377 vs->magic = 0;
1378 g_free(vs->zrle);
1379 g_free(vs->tight);
1380 g_free(vs);
1383 size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err)
1385 if (ret <= 0) {
1386 if (ret == 0) {
1387 trace_vnc_client_eof(vs, vs->ioc);
1388 vnc_disconnect_start(vs);
1389 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1390 trace_vnc_client_io_error(vs, vs->ioc,
1391 err ? error_get_pretty(err) : "Unknown");
1392 vnc_disconnect_start(vs);
1395 error_free(err);
1396 return 0;
1398 return ret;
1402 void vnc_client_error(VncState *vs)
1404 VNC_DEBUG("Closing down client sock: protocol error\n");
1405 vnc_disconnect_start(vs);
1410 * Called to write a chunk of data to the client socket. The data may
1411 * be the raw data, or may have already been encoded by SASL.
1412 * The data will be written either straight onto the socket, or
1413 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1415 * NB, it is theoretically possible to have 2 layers of encryption,
1416 * both SASL, and this TLS layer. It is highly unlikely in practice
1417 * though, since SASL encryption will typically be a no-op if TLS
1418 * is active
1420 * Returns the number of bytes written, which may be less than
1421 * the requested 'datalen' if the socket would block. Returns
1422 * 0 on I/O error, and disconnects the client socket.
1424 size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1426 Error *err = NULL;
1427 ssize_t ret;
1428 ret = qio_channel_write(vs->ioc, (const char *)data, datalen, &err);
1429 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1430 return vnc_client_io_error(vs, ret, err);
1435 * Called to write buffered data to the client socket, when not
1436 * using any SASL SSF encryption layers. Will write as much data
1437 * as possible without blocking. If all buffered data is written,
1438 * will switch the FD poll() handler back to read monitoring.
1440 * Returns the number of bytes written, which may be less than
1441 * the buffered output data if the socket would block. Returns
1442 * 0 on I/O error, and disconnects the client socket.
1444 static size_t vnc_client_write_plain(VncState *vs)
1446 size_t offset;
1447 size_t ret;
1449 #ifdef CONFIG_VNC_SASL
1450 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1451 vs->output.buffer, vs->output.capacity, vs->output.offset,
1452 vs->sasl.waitWriteSSF);
1454 if (vs->sasl.conn &&
1455 vs->sasl.runSSF &&
1456 vs->sasl.waitWriteSSF) {
1457 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1458 if (ret)
1459 vs->sasl.waitWriteSSF -= ret;
1460 } else
1461 #endif /* CONFIG_VNC_SASL */
1462 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1463 if (!ret)
1464 return 0;
1466 if (ret >= vs->force_update_offset) {
1467 if (vs->force_update_offset != 0) {
1468 trace_vnc_client_unthrottle_forced(vs, vs->ioc);
1470 vs->force_update_offset = 0;
1471 } else {
1472 vs->force_update_offset -= ret;
1474 offset = vs->output.offset;
1475 buffer_advance(&vs->output, ret);
1476 if (offset >= vs->throttle_output_offset &&
1477 vs->output.offset < vs->throttle_output_offset) {
1478 trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
1481 if (vs->output.offset == 0) {
1482 if (vs->ioc_tag) {
1483 g_source_remove(vs->ioc_tag);
1485 vs->ioc_tag = qio_channel_add_watch(
1486 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1487 vnc_client_io, vs, NULL);
1490 return ret;
1495 * First function called whenever there is data to be written to
1496 * the client socket. Will delegate actual work according to whether
1497 * SASL SSF layers are enabled (thus requiring encryption calls)
1499 static void vnc_client_write_locked(VncState *vs)
1501 #ifdef CONFIG_VNC_SASL
1502 if (vs->sasl.conn &&
1503 vs->sasl.runSSF &&
1504 !vs->sasl.waitWriteSSF) {
1505 vnc_client_write_sasl(vs);
1506 } else
1507 #endif /* CONFIG_VNC_SASL */
1509 vnc_client_write_plain(vs);
1513 static void vnc_client_write(VncState *vs)
1515 assert(vs->magic == VNC_MAGIC);
1516 vnc_lock_output(vs);
1517 if (vs->output.offset) {
1518 vnc_client_write_locked(vs);
1519 } else if (vs->ioc != NULL) {
1520 if (vs->ioc_tag) {
1521 g_source_remove(vs->ioc_tag);
1523 vs->ioc_tag = qio_channel_add_watch(
1524 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1525 vnc_client_io, vs, NULL);
1527 vnc_unlock_output(vs);
1530 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1532 vs->read_handler = func;
1533 vs->read_handler_expect = expecting;
1538 * Called to read a chunk of data from the client socket. The data may
1539 * be the raw data, or may need to be further decoded by SASL.
1540 * The data will be read either straight from to the socket, or
1541 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1543 * NB, it is theoretically possible to have 2 layers of encryption,
1544 * both SASL, and this TLS layer. It is highly unlikely in practice
1545 * though, since SASL encryption will typically be a no-op if TLS
1546 * is active
1548 * Returns the number of bytes read, which may be less than
1549 * the requested 'datalen' if the socket would block. Returns
1550 * 0 on I/O error or EOF, and disconnects the client socket.
1552 size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1554 ssize_t ret;
1555 Error *err = NULL;
1556 ret = qio_channel_read(vs->ioc, (char *)data, datalen, &err);
1557 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1558 return vnc_client_io_error(vs, ret, err);
1563 * Called to read data from the client socket to the input buffer,
1564 * when not using any SASL SSF encryption layers. Will read as much
1565 * data as possible without blocking.
1567 * Returns the number of bytes read, which may be less than
1568 * the requested 'datalen' if the socket would block. Returns
1569 * 0 on I/O error or EOF, and disconnects the client socket.
1571 static size_t vnc_client_read_plain(VncState *vs)
1573 size_t ret;
1574 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1575 vs->input.buffer, vs->input.capacity, vs->input.offset);
1576 buffer_reserve(&vs->input, 4096);
1577 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1578 if (!ret)
1579 return 0;
1580 vs->input.offset += ret;
1581 return ret;
1584 static void vnc_jobs_bh(void *opaque)
1586 VncState *vs = opaque;
1588 assert(vs->magic == VNC_MAGIC);
1589 vnc_jobs_consume_buffer(vs);
1593 * First function called whenever there is more data to be read from
1594 * the client socket. Will delegate actual work according to whether
1595 * SASL SSF layers are enabled (thus requiring decryption calls)
1596 * Returns 0 on success, -1 if client disconnected
1598 static int vnc_client_read(VncState *vs)
1600 size_t ret;
1602 #ifdef CONFIG_VNC_SASL
1603 if (vs->sasl.conn && vs->sasl.runSSF)
1604 ret = vnc_client_read_sasl(vs);
1605 else
1606 #endif /* CONFIG_VNC_SASL */
1607 ret = vnc_client_read_plain(vs);
1608 if (!ret) {
1609 if (vs->disconnecting) {
1610 vnc_disconnect_finish(vs);
1611 return -1;
1613 return 0;
1616 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1617 size_t len = vs->read_handler_expect;
1618 int ret;
1620 ret = vs->read_handler(vs, vs->input.buffer, len);
1621 if (vs->disconnecting) {
1622 vnc_disconnect_finish(vs);
1623 return -1;
1626 if (!ret) {
1627 buffer_advance(&vs->input, len);
1628 } else {
1629 vs->read_handler_expect = ret;
1632 return 0;
1635 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1636 GIOCondition condition, void *opaque)
1638 VncState *vs = opaque;
1640 assert(vs->magic == VNC_MAGIC);
1642 if (condition & (G_IO_HUP | G_IO_ERR)) {
1643 vnc_disconnect_start(vs);
1644 return TRUE;
1647 if (condition & G_IO_IN) {
1648 if (vnc_client_read(vs) < 0) {
1649 /* vs is free()ed here */
1650 return TRUE;
1653 if (condition & G_IO_OUT) {
1654 vnc_client_write(vs);
1657 if (vs->disconnecting) {
1658 if (vs->ioc_tag != 0) {
1659 g_source_remove(vs->ioc_tag);
1661 vs->ioc_tag = 0;
1663 return TRUE;
1668 * Scale factor to apply to vs->throttle_output_offset when checking for
1669 * hard limit. Worst case normal usage could be x2, if we have a complete
1670 * incremental update and complete forced update in the output buffer.
1671 * So x3 should be good enough, but we pick x5 to be conservative and thus
1672 * (hopefully) never trigger incorrectly.
1674 #define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1676 void vnc_write(VncState *vs, const void *data, size_t len)
1678 assert(vs->magic == VNC_MAGIC);
1679 if (vs->disconnecting) {
1680 return;
1682 /* Protection against malicious client/guest to prevent our output
1683 * buffer growing without bound if client stops reading data. This
1684 * should rarely trigger, because we have earlier throttling code
1685 * which stops issuing framebuffer updates and drops audio data
1686 * if the throttle_output_offset value is exceeded. So we only reach
1687 * this higher level if a huge number of pseudo-encodings get
1688 * triggered while data can't be sent on the socket.
1690 * NB throttle_output_offset can be zero during early protocol
1691 * handshake, or from the job thread's VncState clone
1693 if (vs->throttle_output_offset != 0 &&
1694 (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
1695 vs->throttle_output_offset) {
1696 trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
1697 vs->throttle_output_offset);
1698 vnc_disconnect_start(vs);
1699 return;
1701 buffer_reserve(&vs->output, len);
1703 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1704 if (vs->ioc_tag) {
1705 g_source_remove(vs->ioc_tag);
1707 vs->ioc_tag = qio_channel_add_watch(
1708 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT,
1709 vnc_client_io, vs, NULL);
1712 buffer_append(&vs->output, data, len);
1715 void vnc_write_s32(VncState *vs, int32_t value)
1717 vnc_write_u32(vs, *(uint32_t *)&value);
1720 void vnc_write_u32(VncState *vs, uint32_t value)
1722 uint8_t buf[4];
1724 buf[0] = (value >> 24) & 0xFF;
1725 buf[1] = (value >> 16) & 0xFF;
1726 buf[2] = (value >> 8) & 0xFF;
1727 buf[3] = value & 0xFF;
1729 vnc_write(vs, buf, 4);
1732 void vnc_write_u16(VncState *vs, uint16_t value)
1734 uint8_t buf[2];
1736 buf[0] = (value >> 8) & 0xFF;
1737 buf[1] = value & 0xFF;
1739 vnc_write(vs, buf, 2);
1742 void vnc_write_u8(VncState *vs, uint8_t value)
1744 vnc_write(vs, (char *)&value, 1);
1747 void vnc_flush(VncState *vs)
1749 vnc_lock_output(vs);
1750 if (vs->ioc != NULL && vs->output.offset) {
1751 vnc_client_write_locked(vs);
1753 if (vs->disconnecting) {
1754 if (vs->ioc_tag != 0) {
1755 g_source_remove(vs->ioc_tag);
1757 vs->ioc_tag = 0;
1759 vnc_unlock_output(vs);
1762 static uint8_t read_u8(uint8_t *data, size_t offset)
1764 return data[offset];
1767 static uint16_t read_u16(uint8_t *data, size_t offset)
1769 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1772 static int32_t read_s32(uint8_t *data, size_t offset)
1774 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1775 (data[offset + 2] << 8) | data[offset + 3]);
1778 uint32_t read_u32(uint8_t *data, size_t offset)
1780 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1781 (data[offset + 2] << 8) | data[offset + 3]);
1784 static void check_pointer_type_change(Notifier *notifier, void *data)
1786 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1787 int absolute = qemu_input_is_absolute();
1789 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1790 vnc_lock_output(vs);
1791 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1792 vnc_write_u8(vs, 0);
1793 vnc_write_u16(vs, 1);
1794 vnc_framebuffer_update(vs, absolute, 0,
1795 pixman_image_get_width(vs->vd->server),
1796 pixman_image_get_height(vs->vd->server),
1797 VNC_ENCODING_POINTER_TYPE_CHANGE);
1798 vnc_unlock_output(vs);
1799 vnc_flush(vs);
1801 vs->absolute = absolute;
1804 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1806 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1807 [INPUT_BUTTON_LEFT] = 0x01,
1808 [INPUT_BUTTON_MIDDLE] = 0x02,
1809 [INPUT_BUTTON_RIGHT] = 0x04,
1810 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1811 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1813 QemuConsole *con = vs->vd->dcl.con;
1814 int width = pixman_image_get_width(vs->vd->server);
1815 int height = pixman_image_get_height(vs->vd->server);
1817 if (vs->last_bmask != button_mask) {
1818 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1819 vs->last_bmask = button_mask;
1822 if (vs->absolute) {
1823 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1824 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1825 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1826 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1827 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1828 } else {
1829 if (vs->last_x != -1) {
1830 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1831 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1833 vs->last_x = x;
1834 vs->last_y = y;
1836 qemu_input_event_sync();
1839 static void press_key(VncState *vs, QKeyCode qcode)
1841 qkbd_state_key_event(vs->vd->kbd, qcode, true);
1842 qkbd_state_key_event(vs->vd->kbd, qcode, false);
1845 static void vnc_led_state_change(VncState *vs)
1847 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1848 return;
1851 vnc_lock_output(vs);
1852 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1853 vnc_write_u8(vs, 0);
1854 vnc_write_u16(vs, 1);
1855 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1856 vnc_write_u8(vs, vs->vd->ledstate);
1857 vnc_unlock_output(vs);
1858 vnc_flush(vs);
1861 static void kbd_leds(void *opaque, int ledstate)
1863 VncDisplay *vd = opaque;
1864 VncState *client;
1866 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1867 (ledstate & QEMU_NUM_LOCK_LED),
1868 (ledstate & QEMU_SCROLL_LOCK_LED));
1870 if (ledstate == vd->ledstate) {
1871 return;
1874 vd->ledstate = ledstate;
1876 QTAILQ_FOREACH(client, &vd->clients, next) {
1877 vnc_led_state_change(client);
1881 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1883 QKeyCode qcode = qemu_input_key_number_to_qcode(keycode);
1885 /* QEMU console switch */
1886 switch (qcode) {
1887 case Q_KEY_CODE_1 ... Q_KEY_CODE_9: /* '1' to '9' keys */
1888 if (vs->vd->dcl.con == NULL && down &&
1889 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) &&
1890 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {
1891 /* Reset the modifiers sent to the current console */
1892 qkbd_state_lift_all_keys(vs->vd->kbd);
1893 console_select(qcode - Q_KEY_CODE_1);
1894 return;
1896 default:
1897 break;
1900 /* Turn off the lock state sync logic if the client support the led
1901 state extension.
1903 if (down && vs->vd->lock_key_sync &&
1904 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1905 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1906 /* If the numlock state needs to change then simulate an additional
1907 keypress before sending this one. This will happen if the user
1908 toggles numlock away from the VNC window.
1910 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1911 if (!qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1912 trace_vnc_key_sync_numlock(true);
1913 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1915 } else {
1916 if (qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1917 trace_vnc_key_sync_numlock(false);
1918 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1923 if (down && vs->vd->lock_key_sync &&
1924 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1925 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1926 /* If the capslock state needs to change then simulate an additional
1927 keypress before sending this one. This will happen if the user
1928 toggles capslock away from the VNC window.
1930 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1931 bool shift = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_SHIFT);
1932 bool capslock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CAPSLOCK);
1933 if (capslock) {
1934 if (uppercase == shift) {
1935 trace_vnc_key_sync_capslock(false);
1936 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1938 } else {
1939 if (uppercase != shift) {
1940 trace_vnc_key_sync_capslock(true);
1941 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1946 qkbd_state_key_event(vs->vd->kbd, qcode, down);
1947 if (!qemu_console_is_graphic(NULL)) {
1948 bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK);
1949 bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL);
1950 /* QEMU console emulation */
1951 if (down) {
1952 switch (keycode) {
1953 case 0x2a: /* Left Shift */
1954 case 0x36: /* Right Shift */
1955 case 0x1d: /* Left CTRL */
1956 case 0x9d: /* Right CTRL */
1957 case 0x38: /* Left ALT */
1958 case 0xb8: /* Right ALT */
1959 break;
1960 case 0xc8:
1961 kbd_put_keysym(QEMU_KEY_UP);
1962 break;
1963 case 0xd0:
1964 kbd_put_keysym(QEMU_KEY_DOWN);
1965 break;
1966 case 0xcb:
1967 kbd_put_keysym(QEMU_KEY_LEFT);
1968 break;
1969 case 0xcd:
1970 kbd_put_keysym(QEMU_KEY_RIGHT);
1971 break;
1972 case 0xd3:
1973 kbd_put_keysym(QEMU_KEY_DELETE);
1974 break;
1975 case 0xc7:
1976 kbd_put_keysym(QEMU_KEY_HOME);
1977 break;
1978 case 0xcf:
1979 kbd_put_keysym(QEMU_KEY_END);
1980 break;
1981 case 0xc9:
1982 kbd_put_keysym(QEMU_KEY_PAGEUP);
1983 break;
1984 case 0xd1:
1985 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1986 break;
1988 case 0x47:
1989 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1990 break;
1991 case 0x48:
1992 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1993 break;
1994 case 0x49:
1995 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1996 break;
1997 case 0x4b:
1998 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1999 break;
2000 case 0x4c:
2001 kbd_put_keysym('5');
2002 break;
2003 case 0x4d:
2004 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
2005 break;
2006 case 0x4f:
2007 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
2008 break;
2009 case 0x50:
2010 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
2011 break;
2012 case 0x51:
2013 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
2014 break;
2015 case 0x52:
2016 kbd_put_keysym('0');
2017 break;
2018 case 0x53:
2019 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
2020 break;
2022 case 0xb5:
2023 kbd_put_keysym('/');
2024 break;
2025 case 0x37:
2026 kbd_put_keysym('*');
2027 break;
2028 case 0x4a:
2029 kbd_put_keysym('-');
2030 break;
2031 case 0x4e:
2032 kbd_put_keysym('+');
2033 break;
2034 case 0x9c:
2035 kbd_put_keysym('\n');
2036 break;
2038 default:
2039 if (control) {
2040 kbd_put_keysym(sym & 0x1f);
2041 } else {
2042 kbd_put_keysym(sym);
2044 break;
2050 static const char *code2name(int keycode)
2052 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
2055 static void key_event(VncState *vs, int down, uint32_t sym)
2057 int keycode;
2058 int lsym = sym;
2060 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2061 lsym = lsym - 'A' + 'a';
2064 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
2065 vs->vd->kbd, down) & SCANCODE_KEYMASK;
2066 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2067 do_key_event(vs, down, keycode, sym);
2070 static void ext_key_event(VncState *vs, int down,
2071 uint32_t sym, uint16_t keycode)
2073 /* if the user specifies a keyboard layout, always use it */
2074 if (keyboard_layout) {
2075 key_event(vs, down, sym);
2076 } else {
2077 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2078 do_key_event(vs, down, keycode, sym);
2082 static void framebuffer_update_request(VncState *vs, int incremental,
2083 int x, int y, int w, int h)
2085 if (incremental) {
2086 if (vs->update != VNC_STATE_UPDATE_FORCE) {
2087 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
2089 } else {
2090 vs->update = VNC_STATE_UPDATE_FORCE;
2091 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2092 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
2093 vnc_desktop_resize_ext(vs, 0);
2098 static void send_ext_key_event_ack(VncState *vs)
2100 vnc_lock_output(vs);
2101 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2102 vnc_write_u8(vs, 0);
2103 vnc_write_u16(vs, 1);
2104 vnc_framebuffer_update(vs, 0, 0,
2105 pixman_image_get_width(vs->vd->server),
2106 pixman_image_get_height(vs->vd->server),
2107 VNC_ENCODING_EXT_KEY_EVENT);
2108 vnc_unlock_output(vs);
2109 vnc_flush(vs);
2112 static void send_ext_audio_ack(VncState *vs)
2114 vnc_lock_output(vs);
2115 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2116 vnc_write_u8(vs, 0);
2117 vnc_write_u16(vs, 1);
2118 vnc_framebuffer_update(vs, 0, 0,
2119 pixman_image_get_width(vs->vd->server),
2120 pixman_image_get_height(vs->vd->server),
2121 VNC_ENCODING_AUDIO);
2122 vnc_unlock_output(vs);
2123 vnc_flush(vs);
2126 static void send_xvp_message(VncState *vs, int code)
2128 vnc_lock_output(vs);
2129 vnc_write_u8(vs, VNC_MSG_SERVER_XVP);
2130 vnc_write_u8(vs, 0); /* pad */
2131 vnc_write_u8(vs, 1); /* version */
2132 vnc_write_u8(vs, code);
2133 vnc_unlock_output(vs);
2134 vnc_flush(vs);
2137 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2139 int i;
2140 unsigned int enc = 0;
2142 vs->features = 0;
2143 vs->vnc_encoding = 0;
2144 vs->tight->compression = 9;
2145 vs->tight->quality = -1; /* Lossless by default */
2146 vs->absolute = -1;
2149 * Start from the end because the encodings are sent in order of preference.
2150 * This way the preferred encoding (first encoding defined in the array)
2151 * will be set at the end of the loop.
2153 for (i = n_encodings - 1; i >= 0; i--) {
2154 enc = encodings[i];
2155 switch (enc) {
2156 case VNC_ENCODING_RAW:
2157 vs->vnc_encoding = enc;
2158 break;
2159 case VNC_ENCODING_HEXTILE:
2160 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2161 vs->vnc_encoding = enc;
2162 break;
2163 case VNC_ENCODING_TIGHT:
2164 vs->features |= VNC_FEATURE_TIGHT_MASK;
2165 vs->vnc_encoding = enc;
2166 break;
2167 #ifdef CONFIG_VNC_PNG
2168 case VNC_ENCODING_TIGHT_PNG:
2169 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2170 vs->vnc_encoding = enc;
2171 break;
2172 #endif
2173 case VNC_ENCODING_ZLIB:
2175 * VNC_ENCODING_ZRLE compresses better than VNC_ENCODING_ZLIB.
2176 * So prioritize ZRLE, even if the client hints that it prefers
2177 * ZLIB.
2179 if ((vs->features & VNC_FEATURE_ZRLE_MASK) == 0) {
2180 vs->features |= VNC_FEATURE_ZLIB_MASK;
2181 vs->vnc_encoding = enc;
2183 break;
2184 case VNC_ENCODING_ZRLE:
2185 vs->features |= VNC_FEATURE_ZRLE_MASK;
2186 vs->vnc_encoding = enc;
2187 break;
2188 case VNC_ENCODING_ZYWRLE:
2189 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2190 vs->vnc_encoding = enc;
2191 break;
2192 case VNC_ENCODING_DESKTOPRESIZE:
2193 vs->features |= VNC_FEATURE_RESIZE_MASK;
2194 break;
2195 case VNC_ENCODING_DESKTOP_RESIZE_EXT:
2196 vs->features |= VNC_FEATURE_RESIZE_EXT_MASK;
2197 break;
2198 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2199 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2200 break;
2201 case VNC_ENCODING_RICH_CURSOR:
2202 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2203 break;
2204 case VNC_ENCODING_ALPHA_CURSOR:
2205 vs->features |= VNC_FEATURE_ALPHA_CURSOR_MASK;
2206 break;
2207 case VNC_ENCODING_EXT_KEY_EVENT:
2208 send_ext_key_event_ack(vs);
2209 break;
2210 case VNC_ENCODING_AUDIO:
2211 send_ext_audio_ack(vs);
2212 break;
2213 case VNC_ENCODING_WMVi:
2214 vs->features |= VNC_FEATURE_WMVI_MASK;
2215 break;
2216 case VNC_ENCODING_LED_STATE:
2217 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2218 break;
2219 case VNC_ENCODING_XVP:
2220 if (vs->vd->power_control) {
2221 vs->features |= VNC_FEATURE_XVP;
2222 send_xvp_message(vs, VNC_XVP_CODE_INIT);
2224 break;
2225 case VNC_ENCODING_CLIPBOARD_EXT:
2226 vs->features |= VNC_FEATURE_CLIPBOARD_EXT_MASK;
2227 vnc_server_cut_text_caps(vs);
2228 break;
2229 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2230 vs->tight->compression = (enc & 0x0F);
2231 break;
2232 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2233 if (vs->vd->lossy) {
2234 vs->tight->quality = (enc & 0x0F);
2236 break;
2237 default:
2238 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2239 break;
2242 vnc_desktop_resize(vs);
2243 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2244 vnc_led_state_change(vs);
2245 vnc_cursor_define(vs);
2248 static void set_pixel_conversion(VncState *vs)
2250 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2252 if (fmt == VNC_SERVER_FB_FORMAT) {
2253 vs->write_pixels = vnc_write_pixels_copy;
2254 vnc_hextile_set_pixel_conversion(vs, 0);
2255 } else {
2256 vs->write_pixels = vnc_write_pixels_generic;
2257 vnc_hextile_set_pixel_conversion(vs, 1);
2261 static void send_color_map(VncState *vs)
2263 int i;
2265 vnc_lock_output(vs);
2266 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2267 vnc_write_u8(vs, 0); /* padding */
2268 vnc_write_u16(vs, 0); /* first color */
2269 vnc_write_u16(vs, 256); /* # of colors */
2271 for (i = 0; i < 256; i++) {
2272 PixelFormat *pf = &vs->client_pf;
2274 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2275 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2276 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2278 vnc_unlock_output(vs);
2281 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2282 int big_endian_flag, int true_color_flag,
2283 int red_max, int green_max, int blue_max,
2284 int red_shift, int green_shift, int blue_shift)
2286 if (!true_color_flag) {
2287 /* Expose a reasonable default 256 color map */
2288 bits_per_pixel = 8;
2289 red_max = 7;
2290 green_max = 7;
2291 blue_max = 3;
2292 red_shift = 0;
2293 green_shift = 3;
2294 blue_shift = 6;
2297 switch (bits_per_pixel) {
2298 case 8:
2299 case 16:
2300 case 32:
2301 break;
2302 default:
2303 vnc_client_error(vs);
2304 return;
2307 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2308 vs->client_pf.rbits = ctpopl(red_max);
2309 vs->client_pf.rshift = red_shift;
2310 vs->client_pf.rmask = red_max << red_shift;
2311 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2312 vs->client_pf.gbits = ctpopl(green_max);
2313 vs->client_pf.gshift = green_shift;
2314 vs->client_pf.gmask = green_max << green_shift;
2315 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2316 vs->client_pf.bbits = ctpopl(blue_max);
2317 vs->client_pf.bshift = blue_shift;
2318 vs->client_pf.bmask = blue_max << blue_shift;
2319 vs->client_pf.bits_per_pixel = bits_per_pixel;
2320 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2321 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2322 vs->client_be = big_endian_flag;
2324 if (!true_color_flag) {
2325 send_color_map(vs);
2328 set_pixel_conversion(vs);
2330 graphic_hw_invalidate(vs->vd->dcl.con);
2331 graphic_hw_update(vs->vd->dcl.con);
2334 static void pixel_format_message (VncState *vs) {
2335 char pad[3] = { 0, 0, 0 };
2337 vs->client_pf = qemu_default_pixelformat(32);
2339 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2340 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2342 #if HOST_BIG_ENDIAN
2343 vnc_write_u8(vs, 1); /* big-endian-flag */
2344 #else
2345 vnc_write_u8(vs, 0); /* big-endian-flag */
2346 #endif
2347 vnc_write_u8(vs, 1); /* true-color-flag */
2348 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2349 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2350 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2351 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2352 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2353 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2354 vnc_write(vs, pad, 3); /* padding */
2356 vnc_hextile_set_pixel_conversion(vs, 0);
2357 vs->write_pixels = vnc_write_pixels_copy;
2360 static void vnc_colordepth(VncState *vs)
2362 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2363 /* Sending a WMVi message to notify the client*/
2364 vnc_lock_output(vs);
2365 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2366 vnc_write_u8(vs, 0);
2367 vnc_write_u16(vs, 1); /* number of rects */
2368 vnc_framebuffer_update(vs, 0, 0,
2369 vs->client_width,
2370 vs->client_height,
2371 VNC_ENCODING_WMVi);
2372 pixel_format_message(vs);
2373 vnc_unlock_output(vs);
2374 vnc_flush(vs);
2375 } else {
2376 set_pixel_conversion(vs);
2380 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2382 int i;
2383 uint16_t limit;
2384 uint32_t freq;
2385 VncDisplay *vd = vs->vd;
2387 if (data[0] > 3) {
2388 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2391 switch (data[0]) {
2392 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2393 if (len == 1)
2394 return 20;
2396 set_pixel_format(vs, read_u8(data, 4),
2397 read_u8(data, 6), read_u8(data, 7),
2398 read_u16(data, 8), read_u16(data, 10),
2399 read_u16(data, 12), read_u8(data, 14),
2400 read_u8(data, 15), read_u8(data, 16));
2401 break;
2402 case VNC_MSG_CLIENT_SET_ENCODINGS:
2403 if (len == 1)
2404 return 4;
2406 if (len == 4) {
2407 limit = read_u16(data, 2);
2408 if (limit > 0)
2409 return 4 + (limit * 4);
2410 } else
2411 limit = read_u16(data, 2);
2413 for (i = 0; i < limit; i++) {
2414 int32_t val = read_s32(data, 4 + (i * 4));
2415 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2418 set_encodings(vs, (int32_t *)(data + 4), limit);
2419 break;
2420 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2421 if (len == 1)
2422 return 10;
2424 framebuffer_update_request(vs,
2425 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2426 read_u16(data, 6), read_u16(data, 8));
2427 break;
2428 case VNC_MSG_CLIENT_KEY_EVENT:
2429 if (len == 1)
2430 return 8;
2432 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2433 break;
2434 case VNC_MSG_CLIENT_POINTER_EVENT:
2435 if (len == 1)
2436 return 6;
2438 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2439 break;
2440 case VNC_MSG_CLIENT_CUT_TEXT:
2441 if (len == 1) {
2442 return 8;
2444 if (len == 8) {
2445 uint32_t dlen = abs(read_s32(data, 4));
2446 if (dlen > (1 << 20)) {
2447 error_report("vnc: client_cut_text msg payload has %u bytes"
2448 " which exceeds our limit of 1MB.", dlen);
2449 vnc_client_error(vs);
2450 break;
2452 if (dlen > 0) {
2453 return 8 + dlen;
2457 if (read_s32(data, 4) < 0) {
2458 vnc_client_cut_text_ext(vs, abs(read_s32(data, 4)),
2459 read_u32(data, 8), data + 12);
2460 break;
2462 vnc_client_cut_text(vs, read_u32(data, 4), data + 8);
2463 break;
2464 case VNC_MSG_CLIENT_XVP:
2465 if (!(vs->features & VNC_FEATURE_XVP)) {
2466 error_report("vnc: xvp client message while disabled");
2467 vnc_client_error(vs);
2468 break;
2470 if (len == 1) {
2471 return 4;
2473 if (len == 4) {
2474 uint8_t version = read_u8(data, 2);
2475 uint8_t action = read_u8(data, 3);
2477 if (version != 1) {
2478 error_report("vnc: xvp client message version %d != 1",
2479 version);
2480 vnc_client_error(vs);
2481 break;
2484 switch (action) {
2485 case VNC_XVP_ACTION_SHUTDOWN:
2486 qemu_system_powerdown_request();
2487 break;
2488 case VNC_XVP_ACTION_REBOOT:
2489 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2490 break;
2491 case VNC_XVP_ACTION_RESET:
2492 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
2493 break;
2494 default:
2495 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2496 break;
2499 break;
2500 case VNC_MSG_CLIENT_QEMU:
2501 if (len == 1)
2502 return 2;
2504 switch (read_u8(data, 1)) {
2505 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2506 if (len == 2)
2507 return 12;
2509 ext_key_event(vs, read_u16(data, 2),
2510 read_u32(data, 4), read_u32(data, 8));
2511 break;
2512 case VNC_MSG_CLIENT_QEMU_AUDIO:
2513 if (len == 2)
2514 return 4;
2516 switch (read_u16 (data, 2)) {
2517 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2518 trace_vnc_msg_client_audio_enable(vs, vs->ioc);
2519 audio_add(vs);
2520 break;
2521 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2522 trace_vnc_msg_client_audio_disable(vs, vs->ioc);
2523 audio_del(vs);
2524 break;
2525 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2526 if (len == 4)
2527 return 10;
2528 switch (read_u8(data, 4)) {
2529 case 0: vs->as.fmt = AUDIO_FORMAT_U8; break;
2530 case 1: vs->as.fmt = AUDIO_FORMAT_S8; break;
2531 case 2: vs->as.fmt = AUDIO_FORMAT_U16; break;
2532 case 3: vs->as.fmt = AUDIO_FORMAT_S16; break;
2533 case 4: vs->as.fmt = AUDIO_FORMAT_U32; break;
2534 case 5: vs->as.fmt = AUDIO_FORMAT_S32; break;
2535 default:
2536 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2537 vnc_client_error(vs);
2538 break;
2540 vs->as.nchannels = read_u8(data, 5);
2541 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2542 VNC_DEBUG("Invalid audio channel count %d\n",
2543 read_u8(data, 5));
2544 vnc_client_error(vs);
2545 break;
2547 freq = read_u32(data, 6);
2548 /* No official limit for protocol, but 48khz is a sensible
2549 * upper bound for trustworthy clients, and this limit
2550 * protects calculations involving 'vs->as.freq' later.
2552 if (freq > 48000) {
2553 VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
2554 vnc_client_error(vs);
2555 break;
2557 vs->as.freq = freq;
2558 trace_vnc_msg_client_audio_format(
2559 vs, vs->ioc, vs->as.fmt, vs->as.nchannels, vs->as.freq);
2560 break;
2561 default:
2562 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2563 vnc_client_error(vs);
2564 break;
2566 break;
2568 default:
2569 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2570 vnc_client_error(vs);
2571 break;
2573 break;
2574 case VNC_MSG_CLIENT_SET_DESKTOP_SIZE:
2576 size_t size;
2577 uint8_t screens;
2578 int w, h;
2580 if (len < 8) {
2581 return 8;
2584 screens = read_u8(data, 6);
2585 size = 8 + screens * 16;
2586 if (len < size) {
2587 return size;
2589 w = read_u16(data, 2);
2590 h = read_u16(data, 4);
2592 trace_vnc_msg_client_set_desktop_size(vs, vs->ioc, w, h, screens);
2593 if (dpy_ui_info_supported(vs->vd->dcl.con)) {
2594 QemuUIInfo info;
2595 memset(&info, 0, sizeof(info));
2596 info.width = w;
2597 info.height = h;
2598 dpy_set_ui_info(vs->vd->dcl.con, &info, false);
2599 vnc_desktop_resize_ext(vs, 4 /* Request forwarded */);
2600 } else {
2601 vnc_desktop_resize_ext(vs, 3 /* Invalid screen layout */);
2604 break;
2606 default:
2607 VNC_DEBUG("Msg: %d\n", data[0]);
2608 vnc_client_error(vs);
2609 break;
2612 vnc_update_throttle_offset(vs);
2613 vnc_read_when(vs, protocol_client_msg, 1);
2614 return 0;
2617 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2619 char buf[1024];
2620 VncShareMode mode;
2621 int size;
2623 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2624 switch (vs->vd->share_policy) {
2625 case VNC_SHARE_POLICY_IGNORE:
2627 * Ignore the shared flag. Nothing to do here.
2629 * Doesn't conform to the rfb spec but is traditional qemu
2630 * behavior, thus left here as option for compatibility
2631 * reasons.
2633 break;
2634 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2636 * Policy: Allow clients ask for exclusive access.
2638 * Implementation: When a client asks for exclusive access,
2639 * disconnect all others. Shared connects are allowed as long
2640 * as no exclusive connection exists.
2642 * This is how the rfb spec suggests to handle the shared flag.
2644 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2645 VncState *client;
2646 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2647 if (vs == client) {
2648 continue;
2650 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2651 client->share_mode != VNC_SHARE_MODE_SHARED) {
2652 continue;
2654 vnc_disconnect_start(client);
2657 if (mode == VNC_SHARE_MODE_SHARED) {
2658 if (vs->vd->num_exclusive > 0) {
2659 vnc_disconnect_start(vs);
2660 return 0;
2663 break;
2664 case VNC_SHARE_POLICY_FORCE_SHARED:
2666 * Policy: Shared connects only.
2667 * Implementation: Disallow clients asking for exclusive access.
2669 * Useful for shared desktop sessions where you don't want
2670 * someone forgetting to say -shared when running the vnc
2671 * client disconnect everybody else.
2673 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2674 vnc_disconnect_start(vs);
2675 return 0;
2677 break;
2679 vnc_set_share_mode(vs, mode);
2681 if (vs->vd->num_shared > vs->vd->connections_limit) {
2682 vnc_disconnect_start(vs);
2683 return 0;
2686 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
2687 pixman_image_get_width(vs->vd->server) >= 0);
2688 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
2689 pixman_image_get_height(vs->vd->server) >= 0);
2690 vs->client_width = pixman_image_get_width(vs->vd->server);
2691 vs->client_height = pixman_image_get_height(vs->vd->server);
2692 vnc_write_u16(vs, vs->client_width);
2693 vnc_write_u16(vs, vs->client_height);
2695 pixel_format_message(vs);
2697 if (qemu_name) {
2698 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2699 if (size > sizeof(buf)) {
2700 size = sizeof(buf);
2702 } else {
2703 size = snprintf(buf, sizeof(buf), "QEMU");
2706 vnc_write_u32(vs, size);
2707 vnc_write(vs, buf, size);
2708 vnc_flush(vs);
2710 vnc_client_cache_auth(vs);
2711 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2713 vnc_read_when(vs, protocol_client_msg, 1);
2715 return 0;
2718 void start_client_init(VncState *vs)
2720 vnc_read_when(vs, protocol_client_init, 1);
2723 static void authentication_failed(VncState *vs)
2725 vnc_write_u32(vs, 1); /* Reject auth */
2726 if (vs->minor >= 8) {
2727 static const char err[] = "Authentication failed";
2728 vnc_write_u32(vs, sizeof(err));
2729 vnc_write(vs, err, sizeof(err));
2731 vnc_flush(vs);
2732 vnc_client_error(vs);
2735 static void
2736 vnc_munge_des_rfb_key(unsigned char *key, size_t nkey)
2738 size_t i;
2739 for (i = 0; i < nkey; i++) {
2740 uint8_t r = key[i];
2741 r = (r & 0xf0) >> 4 | (r & 0x0f) << 4;
2742 r = (r & 0xcc) >> 2 | (r & 0x33) << 2;
2743 r = (r & 0xaa) >> 1 | (r & 0x55) << 1;
2744 key[i] = r;
2748 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2750 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2751 size_t i, pwlen;
2752 unsigned char key[8];
2753 time_t now = time(NULL);
2754 QCryptoCipher *cipher = NULL;
2755 Error *err = NULL;
2757 if (!vs->vd->password) {
2758 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2759 goto reject;
2761 if (vs->vd->expires < now) {
2762 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2763 goto reject;
2766 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2768 /* Calculate the expected challenge response */
2769 pwlen = strlen(vs->vd->password);
2770 for (i=0; i<sizeof(key); i++)
2771 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2772 vnc_munge_des_rfb_key(key, sizeof(key));
2774 cipher = qcrypto_cipher_new(
2775 QCRYPTO_CIPHER_ALG_DES,
2776 QCRYPTO_CIPHER_MODE_ECB,
2777 key, G_N_ELEMENTS(key),
2778 &err);
2779 if (!cipher) {
2780 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2781 error_get_pretty(err));
2782 error_free(err);
2783 goto reject;
2786 if (qcrypto_cipher_encrypt(cipher,
2787 vs->challenge,
2788 response,
2789 VNC_AUTH_CHALLENGE_SIZE,
2790 &err) < 0) {
2791 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2792 error_get_pretty(err));
2793 error_free(err);
2794 goto reject;
2797 /* Compare expected vs actual challenge response */
2798 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2799 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2800 goto reject;
2801 } else {
2802 trace_vnc_auth_pass(vs, vs->auth);
2803 vnc_write_u32(vs, 0); /* Accept auth */
2804 vnc_flush(vs);
2806 start_client_init(vs);
2809 qcrypto_cipher_free(cipher);
2810 return 0;
2812 reject:
2813 authentication_failed(vs);
2814 qcrypto_cipher_free(cipher);
2815 return 0;
2818 void start_auth_vnc(VncState *vs)
2820 Error *err = NULL;
2822 if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) {
2823 trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
2824 error_get_pretty(err));
2825 error_free(err);
2826 authentication_failed(vs);
2827 return;
2830 /* Send client a 'random' challenge */
2831 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2832 vnc_flush(vs);
2834 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2838 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2840 /* We only advertise 1 auth scheme at a time, so client
2841 * must pick the one we sent. Verify this */
2842 if (data[0] != vs->auth) { /* Reject auth */
2843 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2844 authentication_failed(vs);
2845 } else { /* Accept requested auth */
2846 trace_vnc_auth_start(vs, vs->auth);
2847 switch (vs->auth) {
2848 case VNC_AUTH_NONE:
2849 if (vs->minor >= 8) {
2850 vnc_write_u32(vs, 0); /* Accept auth completion */
2851 vnc_flush(vs);
2853 trace_vnc_auth_pass(vs, vs->auth);
2854 start_client_init(vs);
2855 break;
2857 case VNC_AUTH_VNC:
2858 start_auth_vnc(vs);
2859 break;
2861 case VNC_AUTH_VENCRYPT:
2862 start_auth_vencrypt(vs);
2863 break;
2865 #ifdef CONFIG_VNC_SASL
2866 case VNC_AUTH_SASL:
2867 start_auth_sasl(vs);
2868 break;
2869 #endif /* CONFIG_VNC_SASL */
2871 default: /* Should not be possible, but just in case */
2872 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2873 authentication_failed(vs);
2876 return 0;
2879 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2881 char local[13];
2883 memcpy(local, version, 12);
2884 local[12] = 0;
2886 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2887 VNC_DEBUG("Malformed protocol version %s\n", local);
2888 vnc_client_error(vs);
2889 return 0;
2891 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2892 if (vs->major != 3 ||
2893 (vs->minor != 3 &&
2894 vs->minor != 4 &&
2895 vs->minor != 5 &&
2896 vs->minor != 7 &&
2897 vs->minor != 8)) {
2898 VNC_DEBUG("Unsupported client version\n");
2899 vnc_write_u32(vs, VNC_AUTH_INVALID);
2900 vnc_flush(vs);
2901 vnc_client_error(vs);
2902 return 0;
2904 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2905 * as equivalent to v3.3 by servers
2907 if (vs->minor == 4 || vs->minor == 5)
2908 vs->minor = 3;
2910 if (vs->minor == 3) {
2911 trace_vnc_auth_start(vs, vs->auth);
2912 if (vs->auth == VNC_AUTH_NONE) {
2913 vnc_write_u32(vs, vs->auth);
2914 vnc_flush(vs);
2915 trace_vnc_auth_pass(vs, vs->auth);
2916 start_client_init(vs);
2917 } else if (vs->auth == VNC_AUTH_VNC) {
2918 VNC_DEBUG("Tell client VNC auth\n");
2919 vnc_write_u32(vs, vs->auth);
2920 vnc_flush(vs);
2921 start_auth_vnc(vs);
2922 } else {
2923 trace_vnc_auth_fail(vs, vs->auth,
2924 "Unsupported auth method for v3.3", "");
2925 vnc_write_u32(vs, VNC_AUTH_INVALID);
2926 vnc_flush(vs);
2927 vnc_client_error(vs);
2929 } else {
2930 vnc_write_u8(vs, 1); /* num auth */
2931 vnc_write_u8(vs, vs->auth);
2932 vnc_read_when(vs, protocol_client_auth, 1);
2933 vnc_flush(vs);
2936 return 0;
2939 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2941 struct VncSurface *vs = &vd->guest;
2943 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2946 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2948 int i, j;
2950 w = (x + w) / VNC_STAT_RECT;
2951 h = (y + h) / VNC_STAT_RECT;
2952 x /= VNC_STAT_RECT;
2953 y /= VNC_STAT_RECT;
2955 for (j = y; j <= h; j++) {
2956 for (i = x; i <= w; i++) {
2957 vs->lossy_rect[j][i] = 1;
2962 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2964 VncState *vs;
2965 int sty = y / VNC_STAT_RECT;
2966 int stx = x / VNC_STAT_RECT;
2967 int has_dirty = 0;
2969 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2970 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2972 QTAILQ_FOREACH(vs, &vd->clients, next) {
2973 int j;
2975 /* kernel send buffers are full -> refresh later */
2976 if (vs->output.offset) {
2977 continue;
2980 if (!vs->lossy_rect[sty][stx]) {
2981 continue;
2984 vs->lossy_rect[sty][stx] = 0;
2985 for (j = 0; j < VNC_STAT_RECT; ++j) {
2986 bitmap_set(vs->dirty[y + j],
2987 x / VNC_DIRTY_PIXELS_PER_BIT,
2988 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2990 has_dirty++;
2993 return has_dirty;
2996 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2998 int width = MIN(pixman_image_get_width(vd->guest.fb),
2999 pixman_image_get_width(vd->server));
3000 int height = MIN(pixman_image_get_height(vd->guest.fb),
3001 pixman_image_get_height(vd->server));
3002 int x, y;
3003 struct timeval res;
3004 int has_dirty = 0;
3006 for (y = 0; y < height; y += VNC_STAT_RECT) {
3007 for (x = 0; x < width; x += VNC_STAT_RECT) {
3008 VncRectStat *rect = vnc_stat_rect(vd, x, y);
3010 rect->updated = false;
3014 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
3016 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
3017 return has_dirty;
3019 vd->guest.last_freq_check = *tv;
3021 for (y = 0; y < height; y += VNC_STAT_RECT) {
3022 for (x = 0; x < width; x += VNC_STAT_RECT) {
3023 VncRectStat *rect= vnc_stat_rect(vd, x, y);
3024 int count = ARRAY_SIZE(rect->times);
3025 struct timeval min, max;
3027 if (!timerisset(&rect->times[count - 1])) {
3028 continue ;
3031 max = rect->times[(rect->idx + count - 1) % count];
3032 qemu_timersub(tv, &max, &res);
3034 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
3035 rect->freq = 0;
3036 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
3037 memset(rect->times, 0, sizeof (rect->times));
3038 continue ;
3041 min = rect->times[rect->idx];
3042 max = rect->times[(rect->idx + count - 1) % count];
3043 qemu_timersub(&max, &min, &res);
3045 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
3046 rect->freq /= count;
3047 rect->freq = 1. / rect->freq;
3050 return has_dirty;
3053 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
3055 int i, j;
3056 double total = 0;
3057 int num = 0;
3059 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
3060 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
3062 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
3063 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
3064 total += vnc_stat_rect(vs->vd, i, j)->freq;
3065 num++;
3069 if (num) {
3070 return total / num;
3071 } else {
3072 return 0;
3076 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
3078 VncRectStat *rect;
3080 rect = vnc_stat_rect(vd, x, y);
3081 if (rect->updated) {
3082 return ;
3084 rect->times[rect->idx] = *tv;
3085 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
3086 rect->updated = true;
3089 static int vnc_refresh_server_surface(VncDisplay *vd)
3091 int width = MIN(pixman_image_get_width(vd->guest.fb),
3092 pixman_image_get_width(vd->server));
3093 int height = MIN(pixman_image_get_height(vd->guest.fb),
3094 pixman_image_get_height(vd->server));
3095 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
3096 uint8_t *guest_row0 = NULL, *server_row0;
3097 VncState *vs;
3098 int has_dirty = 0;
3099 pixman_image_t *tmpbuf = NULL;
3100 unsigned long offset;
3101 int x;
3102 uint8_t *guest_ptr, *server_ptr;
3104 struct timeval tv = { 0, 0 };
3106 if (!vd->non_adaptive) {
3107 gettimeofday(&tv, NULL);
3108 has_dirty = vnc_update_stats(vd, &tv);
3111 offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3112 height * VNC_DIRTY_BPL(&vd->guest), 0);
3113 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3114 /* no dirty bits in guest surface */
3115 return has_dirty;
3119 * Walk through the guest dirty map.
3120 * Check and copy modified bits from guest to server surface.
3121 * Update server dirty map.
3123 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
3124 server_stride = guest_stride = guest_ll =
3125 pixman_image_get_stride(vd->server);
3126 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
3127 server_stride);
3128 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3129 int width = pixman_image_get_width(vd->server);
3130 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
3131 } else {
3132 int guest_bpp =
3133 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
3134 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
3135 guest_stride = pixman_image_get_stride(vd->guest.fb);
3136 guest_ll = pixman_image_get_width(vd->guest.fb)
3137 * DIV_ROUND_UP(guest_bpp, 8);
3139 line_bytes = MIN(server_stride, guest_ll);
3141 for (;;) {
3142 y = offset / VNC_DIRTY_BPL(&vd->guest);
3143 x = offset % VNC_DIRTY_BPL(&vd->guest);
3145 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
3147 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3148 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
3149 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
3150 } else {
3151 guest_ptr = guest_row0 + y * guest_stride;
3153 guest_ptr += x * cmp_bytes;
3155 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
3156 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
3157 int _cmp_bytes = cmp_bytes;
3158 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
3159 continue;
3161 if ((x + 1) * cmp_bytes > line_bytes) {
3162 _cmp_bytes = line_bytes - x * cmp_bytes;
3164 assert(_cmp_bytes >= 0);
3165 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
3166 continue;
3168 memcpy(server_ptr, guest_ptr, _cmp_bytes);
3169 if (!vd->non_adaptive) {
3170 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
3171 y, &tv);
3173 QTAILQ_FOREACH(vs, &vd->clients, next) {
3174 set_bit(x, vs->dirty[y]);
3176 has_dirty++;
3179 y++;
3180 offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3181 height * VNC_DIRTY_BPL(&vd->guest),
3182 y * VNC_DIRTY_BPL(&vd->guest));
3183 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3184 /* no more dirty bits */
3185 break;
3188 qemu_pixman_image_unref(tmpbuf);
3189 return has_dirty;
3192 static void vnc_refresh(DisplayChangeListener *dcl)
3194 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
3195 VncState *vs, *vn;
3196 int has_dirty, rects = 0;
3198 if (QTAILQ_EMPTY(&vd->clients)) {
3199 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
3200 return;
3203 graphic_hw_update(vd->dcl.con);
3205 if (vnc_trylock_display(vd)) {
3206 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3207 return;
3210 has_dirty = vnc_refresh_server_surface(vd);
3211 vnc_unlock_display(vd);
3213 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
3214 rects += vnc_update_client(vs, has_dirty);
3215 /* vs might be free()ed here */
3218 if (has_dirty && rects) {
3219 vd->dcl.update_interval /= 2;
3220 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3221 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3223 } else {
3224 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3225 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3226 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3231 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
3232 bool skipauth, bool websocket)
3234 VncState *vs = g_new0(VncState, 1);
3235 bool first_client = QTAILQ_EMPTY(&vd->clients);
3236 int i;
3238 trace_vnc_client_connect(vs, sioc);
3239 vs->zrle = g_new0(VncZrle, 1);
3240 vs->tight = g_new0(VncTight, 1);
3241 vs->magic = VNC_MAGIC;
3242 vs->sioc = sioc;
3243 object_ref(OBJECT(vs->sioc));
3244 vs->ioc = QIO_CHANNEL(sioc);
3245 object_ref(OBJECT(vs->ioc));
3246 vs->vd = vd;
3248 buffer_init(&vs->input, "vnc-input/%p", sioc);
3249 buffer_init(&vs->output, "vnc-output/%p", sioc);
3250 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
3252 buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc);
3253 buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc);
3254 buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc);
3255 #ifdef CONFIG_VNC_JPEG
3256 buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc);
3257 #endif
3258 #ifdef CONFIG_VNC_PNG
3259 buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc);
3260 #endif
3261 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3262 buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc);
3263 buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc);
3264 buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc);
3266 if (skipauth) {
3267 vs->auth = VNC_AUTH_NONE;
3268 vs->subauth = VNC_AUTH_INVALID;
3269 } else {
3270 if (websocket) {
3271 vs->auth = vd->ws_auth;
3272 vs->subauth = VNC_AUTH_INVALID;
3273 } else {
3274 vs->auth = vd->auth;
3275 vs->subauth = vd->subauth;
3278 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3279 sioc, websocket, vs->auth, vs->subauth);
3281 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3282 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3283 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3286 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3287 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3288 qio_channel_set_blocking(vs->ioc, false, NULL);
3289 if (vs->ioc_tag) {
3290 g_source_remove(vs->ioc_tag);
3292 if (websocket) {
3293 vs->websocket = 1;
3294 if (vd->tlscreds) {
3295 vs->ioc_tag = qio_channel_add_watch(
3296 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3297 vncws_tls_handshake_io, vs, NULL);
3298 } else {
3299 vs->ioc_tag = qio_channel_add_watch(
3300 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3301 vncws_handshake_io, vs, NULL);
3303 } else {
3304 vs->ioc_tag = qio_channel_add_watch(
3305 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3306 vnc_client_io, vs, NULL);
3309 vnc_client_cache_addr(vs);
3310 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3311 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3313 vs->last_x = -1;
3314 vs->last_y = -1;
3316 vs->as.freq = 44100;
3317 vs->as.nchannels = 2;
3318 vs->as.fmt = AUDIO_FORMAT_S16;
3319 vs->as.endianness = 0;
3321 qemu_mutex_init(&vs->output_mutex);
3322 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3324 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3325 if (first_client) {
3326 vnc_update_server_surface(vd);
3329 graphic_hw_update(vd->dcl.con);
3331 if (!vs->websocket) {
3332 vnc_start_protocol(vs);
3335 if (vd->num_connecting > vd->connections_limit) {
3336 QTAILQ_FOREACH(vs, &vd->clients, next) {
3337 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3338 vnc_disconnect_start(vs);
3339 return;
3345 void vnc_start_protocol(VncState *vs)
3347 vnc_write(vs, "RFB 003.008\n", 12);
3348 vnc_flush(vs);
3349 vnc_read_when(vs, protocol_version, 12);
3351 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3352 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3355 static void vnc_listen_io(QIONetListener *listener,
3356 QIOChannelSocket *cioc,
3357 void *opaque)
3359 VncDisplay *vd = opaque;
3360 bool isWebsock = listener == vd->wslistener;
3362 qio_channel_set_name(QIO_CHANNEL(cioc),
3363 isWebsock ? "vnc-ws-server" : "vnc-server");
3364 qio_channel_set_delay(QIO_CHANNEL(cioc), false);
3365 vnc_connect(vd, cioc, false, isWebsock);
3368 static const DisplayChangeListenerOps dcl_ops = {
3369 .dpy_name = "vnc",
3370 .dpy_refresh = vnc_refresh,
3371 .dpy_gfx_update = vnc_dpy_update,
3372 .dpy_gfx_switch = vnc_dpy_switch,
3373 .dpy_gfx_check_format = qemu_pixman_check_format,
3374 .dpy_mouse_set = vnc_mouse_set,
3375 .dpy_cursor_define = vnc_dpy_cursor_define,
3378 void vnc_display_init(const char *id, Error **errp)
3380 VncDisplay *vd;
3382 if (vnc_display_find(id) != NULL) {
3383 return;
3385 vd = g_malloc0(sizeof(*vd));
3387 vd->id = strdup(id);
3388 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3390 QTAILQ_INIT(&vd->clients);
3391 vd->expires = TIME_MAX;
3393 if (keyboard_layout) {
3394 trace_vnc_key_map_init(keyboard_layout);
3395 vd->kbd_layout = init_keyboard_layout(name2keysym,
3396 keyboard_layout, errp);
3397 } else {
3398 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
3401 if (!vd->kbd_layout) {
3402 return;
3405 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3406 vd->connections_limit = 32;
3408 qemu_mutex_init(&vd->mutex);
3409 vnc_start_worker_thread();
3411 vd->dcl.ops = &dcl_ops;
3412 register_displaychangelistener(&vd->dcl);
3413 vd->kbd = qkbd_state_init(vd->dcl.con);
3417 static void vnc_display_close(VncDisplay *vd)
3419 if (!vd) {
3420 return;
3422 vd->is_unix = false;
3424 if (vd->listener) {
3425 qio_net_listener_disconnect(vd->listener);
3426 object_unref(OBJECT(vd->listener));
3428 vd->listener = NULL;
3430 if (vd->wslistener) {
3431 qio_net_listener_disconnect(vd->wslistener);
3432 object_unref(OBJECT(vd->wslistener));
3434 vd->wslistener = NULL;
3436 vd->auth = VNC_AUTH_INVALID;
3437 vd->subauth = VNC_AUTH_INVALID;
3438 if (vd->tlscreds) {
3439 object_unref(OBJECT(vd->tlscreds));
3440 vd->tlscreds = NULL;
3442 if (vd->tlsauthz) {
3443 object_unparent(OBJECT(vd->tlsauthz));
3444 vd->tlsauthz = NULL;
3446 g_free(vd->tlsauthzid);
3447 vd->tlsauthzid = NULL;
3448 if (vd->lock_key_sync) {
3449 qemu_remove_led_event_handler(vd->led);
3450 vd->led = NULL;
3452 #ifdef CONFIG_VNC_SASL
3453 if (vd->sasl.authz) {
3454 object_unparent(OBJECT(vd->sasl.authz));
3455 vd->sasl.authz = NULL;
3457 g_free(vd->sasl.authzid);
3458 vd->sasl.authzid = NULL;
3459 #endif
3462 int vnc_display_password(const char *id, const char *password)
3464 VncDisplay *vd = vnc_display_find(id);
3466 if (!vd) {
3467 return -EINVAL;
3469 if (vd->auth == VNC_AUTH_NONE) {
3470 error_printf_unless_qmp("If you want use passwords please enable "
3471 "password auth using '-vnc ${dpy},password'.\n");
3472 return -EINVAL;
3475 g_free(vd->password);
3476 vd->password = g_strdup(password);
3478 return 0;
3481 int vnc_display_pw_expire(const char *id, time_t expires)
3483 VncDisplay *vd = vnc_display_find(id);
3485 if (!vd) {
3486 return -EINVAL;
3489 vd->expires = expires;
3490 return 0;
3493 static void vnc_display_print_local_addr(VncDisplay *vd)
3495 SocketAddress *addr;
3497 if (!vd->listener || !vd->listener->nsioc) {
3498 return;
3501 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], NULL);
3502 if (!addr) {
3503 return;
3506 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3507 qapi_free_SocketAddress(addr);
3508 return;
3510 error_printf_unless_qmp("VNC server running on %s:%s\n",
3511 addr->u.inet.host,
3512 addr->u.inet.port);
3513 qapi_free_SocketAddress(addr);
3516 static QemuOptsList qemu_vnc_opts = {
3517 .name = "vnc",
3518 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3519 .implied_opt_name = "vnc",
3520 .desc = {
3522 .name = "vnc",
3523 .type = QEMU_OPT_STRING,
3525 .name = "websocket",
3526 .type = QEMU_OPT_STRING,
3528 .name = "tls-creds",
3529 .type = QEMU_OPT_STRING,
3531 .name = "share",
3532 .type = QEMU_OPT_STRING,
3534 .name = "display",
3535 .type = QEMU_OPT_STRING,
3537 .name = "head",
3538 .type = QEMU_OPT_NUMBER,
3540 .name = "connections",
3541 .type = QEMU_OPT_NUMBER,
3543 .name = "to",
3544 .type = QEMU_OPT_NUMBER,
3546 .name = "ipv4",
3547 .type = QEMU_OPT_BOOL,
3549 .name = "ipv6",
3550 .type = QEMU_OPT_BOOL,
3552 .name = "password",
3553 .type = QEMU_OPT_BOOL,
3555 .name = "password-secret",
3556 .type = QEMU_OPT_STRING,
3558 .name = "reverse",
3559 .type = QEMU_OPT_BOOL,
3561 .name = "lock-key-sync",
3562 .type = QEMU_OPT_BOOL,
3564 .name = "key-delay-ms",
3565 .type = QEMU_OPT_NUMBER,
3567 .name = "sasl",
3568 .type = QEMU_OPT_BOOL,
3570 .name = "tls-authz",
3571 .type = QEMU_OPT_STRING,
3573 .name = "sasl-authz",
3574 .type = QEMU_OPT_STRING,
3576 .name = "lossy",
3577 .type = QEMU_OPT_BOOL,
3579 .name = "non-adaptive",
3580 .type = QEMU_OPT_BOOL,
3582 .name = "audiodev",
3583 .type = QEMU_OPT_STRING,
3585 .name = "power-control",
3586 .type = QEMU_OPT_BOOL,
3588 { /* end of list */ }
3593 static int
3594 vnc_display_setup_auth(int *auth,
3595 int *subauth,
3596 QCryptoTLSCreds *tlscreds,
3597 bool password,
3598 bool sasl,
3599 bool websocket,
3600 Error **errp)
3603 * We have a choice of 3 authentication options
3605 * 1. none
3606 * 2. vnc
3607 * 3. sasl
3609 * The channel can be run in 2 modes
3611 * 1. clear
3612 * 2. tls
3614 * And TLS can use 2 types of credentials
3616 * 1. anon
3617 * 2. x509
3619 * We thus have 9 possible logical combinations
3621 * 1. clear + none
3622 * 2. clear + vnc
3623 * 3. clear + sasl
3624 * 4. tls + anon + none
3625 * 5. tls + anon + vnc
3626 * 6. tls + anon + sasl
3627 * 7. tls + x509 + none
3628 * 8. tls + x509 + vnc
3629 * 9. tls + x509 + sasl
3631 * These need to be mapped into the VNC auth schemes
3632 * in an appropriate manner. In regular VNC, all the
3633 * TLS options get mapped into VNC_AUTH_VENCRYPT
3634 * sub-auth types.
3636 * In websockets, the https:// protocol already provides
3637 * TLS support, so there is no need to make use of the
3638 * VeNCrypt extension. Furthermore, websockets browser
3639 * clients could not use VeNCrypt even if they wanted to,
3640 * as they cannot control when the TLS handshake takes
3641 * place. Thus there is no option but to rely on https://,
3642 * meaning combinations 4->6 and 7->9 will be mapped to
3643 * VNC auth schemes in the same way as combos 1->3.
3645 * Regardless of fact that we have a different mapping to
3646 * VNC auth mechs for plain VNC vs websockets VNC, the end
3647 * result has the same security characteristics.
3649 if (websocket || !tlscreds) {
3650 if (password) {
3651 VNC_DEBUG("Initializing VNC server with password auth\n");
3652 *auth = VNC_AUTH_VNC;
3653 } else if (sasl) {
3654 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3655 *auth = VNC_AUTH_SASL;
3656 } else {
3657 VNC_DEBUG("Initializing VNC server with no auth\n");
3658 *auth = VNC_AUTH_NONE;
3660 *subauth = VNC_AUTH_INVALID;
3661 } else {
3662 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3663 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3664 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3665 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3667 if (!is_x509 && !is_anon) {
3668 error_setg(errp,
3669 "Unsupported TLS cred type %s",
3670 object_get_typename(OBJECT(tlscreds)));
3671 return -1;
3673 *auth = VNC_AUTH_VENCRYPT;
3674 if (password) {
3675 if (is_x509) {
3676 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3677 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3678 } else {
3679 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3680 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3683 } else if (sasl) {
3684 if (is_x509) {
3685 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3686 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3687 } else {
3688 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3689 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3691 } else {
3692 if (is_x509) {
3693 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3694 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3695 } else {
3696 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3697 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3701 return 0;
3705 static int vnc_display_get_address(const char *addrstr,
3706 bool websocket,
3707 bool reverse,
3708 int displaynum,
3709 int to,
3710 bool has_ipv4,
3711 bool has_ipv6,
3712 bool ipv4,
3713 bool ipv6,
3714 SocketAddress **retaddr,
3715 Error **errp)
3717 int ret = -1;
3718 SocketAddress *addr = NULL;
3720 addr = g_new0(SocketAddress, 1);
3722 if (strncmp(addrstr, "unix:", 5) == 0) {
3723 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3724 addr->u.q_unix.path = g_strdup(addrstr + 5);
3726 if (websocket) {
3727 error_setg(errp, "UNIX sockets not supported with websock");
3728 goto cleanup;
3731 if (to) {
3732 error_setg(errp, "Port range not support with UNIX socket");
3733 goto cleanup;
3735 ret = 0;
3736 } else {
3737 const char *port;
3738 size_t hostlen;
3739 unsigned long long baseport = 0;
3740 InetSocketAddress *inet;
3742 port = strrchr(addrstr, ':');
3743 if (!port) {
3744 if (websocket) {
3745 hostlen = 0;
3746 port = addrstr;
3747 } else {
3748 error_setg(errp, "no vnc port specified");
3749 goto cleanup;
3751 } else {
3752 hostlen = port - addrstr;
3753 port++;
3754 if (*port == '\0') {
3755 error_setg(errp, "vnc port cannot be empty");
3756 goto cleanup;
3760 addr->type = SOCKET_ADDRESS_TYPE_INET;
3761 inet = &addr->u.inet;
3762 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3763 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3764 } else {
3765 inet->host = g_strndup(addrstr, hostlen);
3767 /* plain VNC port is just an offset, for websocket
3768 * port is absolute */
3769 if (websocket) {
3770 if (g_str_equal(addrstr, "") ||
3771 g_str_equal(addrstr, "on")) {
3772 if (displaynum == -1) {
3773 error_setg(errp, "explicit websocket port is required");
3774 goto cleanup;
3776 inet->port = g_strdup_printf(
3777 "%d", displaynum + 5700);
3778 if (to) {
3779 inet->has_to = true;
3780 inet->to = to + 5700;
3782 } else {
3783 inet->port = g_strdup(port);
3785 } else {
3786 int offset = reverse ? 0 : 5900;
3787 if (parse_uint_full(port, &baseport, 10) < 0) {
3788 error_setg(errp, "can't convert to a number: %s", port);
3789 goto cleanup;
3791 if (baseport > 65535 ||
3792 baseport + offset > 65535) {
3793 error_setg(errp, "port %s out of range", port);
3794 goto cleanup;
3796 inet->port = g_strdup_printf(
3797 "%d", (int)baseport + offset);
3799 if (to) {
3800 inet->has_to = true;
3801 inet->to = to + offset;
3805 inet->ipv4 = ipv4;
3806 inet->has_ipv4 = has_ipv4;
3807 inet->ipv6 = ipv6;
3808 inet->has_ipv6 = has_ipv6;
3810 ret = baseport;
3813 *retaddr = addr;
3815 cleanup:
3816 if (ret < 0) {
3817 qapi_free_SocketAddress(addr);
3819 return ret;
3822 static void vnc_free_addresses(SocketAddress ***retsaddr,
3823 size_t *retnsaddr)
3825 size_t i;
3827 for (i = 0; i < *retnsaddr; i++) {
3828 qapi_free_SocketAddress((*retsaddr)[i]);
3830 g_free(*retsaddr);
3832 *retsaddr = NULL;
3833 *retnsaddr = 0;
3836 static int vnc_display_get_addresses(QemuOpts *opts,
3837 bool reverse,
3838 SocketAddress ***retsaddr,
3839 size_t *retnsaddr,
3840 SocketAddress ***retwsaddr,
3841 size_t *retnwsaddr,
3842 Error **errp)
3844 SocketAddress *saddr = NULL;
3845 SocketAddress *wsaddr = NULL;
3846 QemuOptsIter addriter;
3847 const char *addr;
3848 int to = qemu_opt_get_number(opts, "to", 0);
3849 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3850 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3851 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3852 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3853 int displaynum = -1;
3854 int ret = -1;
3856 *retsaddr = NULL;
3857 *retnsaddr = 0;
3858 *retwsaddr = NULL;
3859 *retnwsaddr = 0;
3861 addr = qemu_opt_get(opts, "vnc");
3862 if (addr == NULL || g_str_equal(addr, "none")) {
3863 ret = 0;
3864 goto cleanup;
3866 if (qemu_opt_get(opts, "websocket") &&
3867 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3868 error_setg(errp,
3869 "SHA1 hash support is required for websockets");
3870 goto cleanup;
3873 qemu_opt_iter_init(&addriter, opts, "vnc");
3874 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3875 int rv;
3876 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3877 has_ipv4, has_ipv6,
3878 ipv4, ipv6,
3879 &saddr, errp);
3880 if (rv < 0) {
3881 goto cleanup;
3883 /* Historical compat - first listen address can be used
3884 * to set the default websocket port
3886 if (displaynum == -1) {
3887 displaynum = rv;
3889 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3890 (*retsaddr)[(*retnsaddr)++] = saddr;
3893 /* If we had multiple primary displays, we don't do defaults
3894 * for websocket, and require explicit config instead. */
3895 if (*retnsaddr > 1) {
3896 displaynum = -1;
3899 qemu_opt_iter_init(&addriter, opts, "websocket");
3900 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3901 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3902 has_ipv4, has_ipv6,
3903 ipv4, ipv6,
3904 &wsaddr, errp) < 0) {
3905 goto cleanup;
3908 /* Historical compat - if only a single listen address was
3909 * provided, then this is used to set the default listen
3910 * address for websocket too
3912 if (*retnsaddr == 1 &&
3913 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3914 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3915 g_str_equal(wsaddr->u.inet.host, "") &&
3916 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3917 g_free(wsaddr->u.inet.host);
3918 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3921 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3922 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3925 ret = 0;
3926 cleanup:
3927 if (ret < 0) {
3928 vnc_free_addresses(retsaddr, retnsaddr);
3929 vnc_free_addresses(retwsaddr, retnwsaddr);
3931 return ret;
3934 static int vnc_display_connect(VncDisplay *vd,
3935 SocketAddress **saddr,
3936 size_t nsaddr,
3937 SocketAddress **wsaddr,
3938 size_t nwsaddr,
3939 Error **errp)
3941 /* connect to viewer */
3942 QIOChannelSocket *sioc = NULL;
3943 if (nwsaddr != 0) {
3944 error_setg(errp, "Cannot use websockets in reverse mode");
3945 return -1;
3947 if (nsaddr != 1) {
3948 error_setg(errp, "Expected a single address in reverse mode");
3949 return -1;
3951 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3952 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3953 sioc = qio_channel_socket_new();
3954 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3955 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3956 object_unref(OBJECT(sioc));
3957 return -1;
3959 vnc_connect(vd, sioc, false, false);
3960 object_unref(OBJECT(sioc));
3961 return 0;
3965 static int vnc_display_listen(VncDisplay *vd,
3966 SocketAddress **saddr,
3967 size_t nsaddr,
3968 SocketAddress **wsaddr,
3969 size_t nwsaddr,
3970 Error **errp)
3972 size_t i;
3974 if (nsaddr) {
3975 vd->listener = qio_net_listener_new();
3976 qio_net_listener_set_name(vd->listener, "vnc-listen");
3977 for (i = 0; i < nsaddr; i++) {
3978 if (qio_net_listener_open_sync(vd->listener,
3979 saddr[i], 1,
3980 errp) < 0) {
3981 return -1;
3985 qio_net_listener_set_client_func(vd->listener,
3986 vnc_listen_io, vd, NULL);
3989 if (nwsaddr) {
3990 vd->wslistener = qio_net_listener_new();
3991 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
3992 for (i = 0; i < nwsaddr; i++) {
3993 if (qio_net_listener_open_sync(vd->wslistener,
3994 wsaddr[i], 1,
3995 errp) < 0) {
3996 return -1;
4000 qio_net_listener_set_client_func(vd->wslistener,
4001 vnc_listen_io, vd, NULL);
4004 return 0;
4008 void vnc_display_open(const char *id, Error **errp)
4010 VncDisplay *vd = vnc_display_find(id);
4011 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
4012 SocketAddress **saddr = NULL, **wsaddr = NULL;
4013 size_t nsaddr, nwsaddr;
4014 const char *share, *device_id;
4015 QemuConsole *con;
4016 bool password = false;
4017 bool reverse = false;
4018 const char *credid;
4019 bool sasl = false;
4020 const char *tlsauthz;
4021 const char *saslauthz;
4022 int lock_key_sync = 1;
4023 int key_delay_ms;
4024 const char *audiodev;
4025 const char *passwordSecret;
4027 if (!vd) {
4028 error_setg(errp, "VNC display not active");
4029 return;
4031 vnc_display_close(vd);
4033 if (!opts) {
4034 return;
4037 reverse = qemu_opt_get_bool(opts, "reverse", false);
4038 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
4039 &wsaddr, &nwsaddr, errp) < 0) {
4040 goto fail;
4044 passwordSecret = qemu_opt_get(opts, "password-secret");
4045 if (passwordSecret) {
4046 if (qemu_opt_get(opts, "password")) {
4047 error_setg(errp,
4048 "'password' flag is redundant with 'password-secret'");
4049 goto fail;
4051 vd->password = qcrypto_secret_lookup_as_utf8(passwordSecret,
4052 errp);
4053 if (!vd->password) {
4054 goto fail;
4056 password = true;
4057 } else {
4058 password = qemu_opt_get_bool(opts, "password", false);
4060 if (password) {
4061 if (fips_get_state()) {
4062 error_setg(errp,
4063 "VNC password auth disabled due to FIPS mode, "
4064 "consider using the VeNCrypt or SASL authentication "
4065 "methods as an alternative");
4066 goto fail;
4068 if (!qcrypto_cipher_supports(
4069 QCRYPTO_CIPHER_ALG_DES, QCRYPTO_CIPHER_MODE_ECB)) {
4070 error_setg(errp,
4071 "Cipher backend does not support DES algorithm");
4072 goto fail;
4076 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
4077 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
4078 sasl = qemu_opt_get_bool(opts, "sasl", false);
4079 #ifndef CONFIG_VNC_SASL
4080 if (sasl) {
4081 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
4082 goto fail;
4084 #endif /* CONFIG_VNC_SASL */
4085 credid = qemu_opt_get(opts, "tls-creds");
4086 if (credid) {
4087 Object *creds;
4088 creds = object_resolve_path_component(
4089 object_get_objects_root(), credid);
4090 if (!creds) {
4091 error_setg(errp, "No TLS credentials with id '%s'",
4092 credid);
4093 goto fail;
4095 vd->tlscreds = (QCryptoTLSCreds *)
4096 object_dynamic_cast(creds,
4097 TYPE_QCRYPTO_TLS_CREDS);
4098 if (!vd->tlscreds) {
4099 error_setg(errp, "Object with id '%s' is not TLS credentials",
4100 credid);
4101 goto fail;
4103 object_ref(OBJECT(vd->tlscreds));
4105 if (!qcrypto_tls_creds_check_endpoint(vd->tlscreds,
4106 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
4107 errp)) {
4108 goto fail;
4111 tlsauthz = qemu_opt_get(opts, "tls-authz");
4112 if (tlsauthz && !vd->tlscreds) {
4113 error_setg(errp, "'tls-authz' provided but TLS is not enabled");
4114 goto fail;
4117 saslauthz = qemu_opt_get(opts, "sasl-authz");
4118 if (saslauthz && !sasl) {
4119 error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
4120 goto fail;
4123 share = qemu_opt_get(opts, "share");
4124 if (share) {
4125 if (strcmp(share, "ignore") == 0) {
4126 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4127 } else if (strcmp(share, "allow-exclusive") == 0) {
4128 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4129 } else if (strcmp(share, "force-shared") == 0) {
4130 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4131 } else {
4132 error_setg(errp, "unknown vnc share= option");
4133 goto fail;
4135 } else {
4136 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4138 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4140 #ifdef CONFIG_VNC_JPEG
4141 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4142 #endif
4143 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
4144 /* adaptive updates are only used with tight encoding and
4145 * if lossy updates are enabled so we can disable all the
4146 * calculations otherwise */
4147 if (!vd->lossy) {
4148 vd->non_adaptive = true;
4151 vd->power_control = qemu_opt_get_bool(opts, "power-control", false);
4153 if (tlsauthz) {
4154 vd->tlsauthzid = g_strdup(tlsauthz);
4156 #ifdef CONFIG_VNC_SASL
4157 if (sasl) {
4158 if (saslauthz) {
4159 vd->sasl.authzid = g_strdup(saslauthz);
4162 #endif
4164 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4165 vd->tlscreds, password,
4166 sasl, false, errp) < 0) {
4167 goto fail;
4169 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
4171 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4172 vd->tlscreds, password,
4173 sasl, true, errp) < 0) {
4174 goto fail;
4176 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
4178 #ifdef CONFIG_VNC_SASL
4179 if (sasl && !vnc_sasl_server_init(errp)) {
4180 goto fail;
4182 #endif
4183 vd->lock_key_sync = lock_key_sync;
4184 if (lock_key_sync) {
4185 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4187 vd->ledstate = 0;
4189 audiodev = qemu_opt_get(opts, "audiodev");
4190 if (audiodev) {
4191 vd->audio_state = audio_state_by_name(audiodev);
4192 if (!vd->audio_state) {
4193 error_setg(errp, "Audiodev '%s' not found", audiodev);
4194 goto fail;
4198 device_id = qemu_opt_get(opts, "display");
4199 if (device_id) {
4200 int head = qemu_opt_get_number(opts, "head", 0);
4201 Error *err = NULL;
4203 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4204 if (err) {
4205 error_propagate(errp, err);
4206 goto fail;
4208 } else {
4209 con = NULL;
4212 if (con != vd->dcl.con) {
4213 qkbd_state_free(vd->kbd);
4214 unregister_displaychangelistener(&vd->dcl);
4215 vd->dcl.con = con;
4216 register_displaychangelistener(&vd->dcl);
4217 vd->kbd = qkbd_state_init(vd->dcl.con);
4219 qkbd_state_set_delay(vd->kbd, key_delay_ms);
4221 if (saddr == NULL) {
4222 goto cleanup;
4225 if (reverse) {
4226 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4227 goto fail;
4229 } else {
4230 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4231 goto fail;
4235 if (qemu_opt_get(opts, "to")) {
4236 vnc_display_print_local_addr(vd);
4239 cleanup:
4240 vnc_free_addresses(&saddr, &nsaddr);
4241 vnc_free_addresses(&wsaddr, &nwsaddr);
4242 return;
4244 fail:
4245 vnc_display_close(vd);
4246 goto cleanup;
4249 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4251 VncDisplay *vd = vnc_display_find(id);
4252 QIOChannelSocket *sioc;
4254 if (!vd) {
4255 return;
4258 sioc = qio_channel_socket_new_fd(csock, NULL);
4259 if (sioc) {
4260 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4261 vnc_connect(vd, sioc, skipauth, false);
4262 object_unref(OBJECT(sioc));
4266 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4268 int i = 2;
4269 char *id;
4271 id = g_strdup("default");
4272 while (qemu_opts_find(olist, id)) {
4273 g_free(id);
4274 id = g_strdup_printf("vnc%d", i++);
4276 qemu_opts_set_id(opts, id);
4279 void vnc_parse(const char *str)
4281 QemuOptsList *olist = qemu_find_opts("vnc");
4282 QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str));
4283 const char *id;
4285 if (!opts) {
4286 exit(1);
4289 id = qemu_opts_id(opts);
4290 if (!id) {
4291 /* auto-assign id if not present */
4292 vnc_auto_assign_id(olist, opts);
4296 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4298 Error *local_err = NULL;
4299 char *id = (char *)qemu_opts_id(opts);
4301 assert(id);
4302 vnc_display_init(id, &local_err);
4303 if (local_err) {
4304 error_propagate(errp, local_err);
4305 return -1;
4307 vnc_display_open(id, &local_err);
4308 if (local_err != NULL) {
4309 error_propagate(errp, local_err);
4310 return -1;
4312 return 0;
4315 static void vnc_register_config(void)
4317 qemu_add_opts(&qemu_vnc_opts);
4319 opts_init(vnc_register_config);