scsi-disk: pass SCSI status to scsi_handle_rw_error
[qemu/ar7.git] / ui / vnc.c
blob16bb3be770b290863445c728b9283836b627ac38
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/tlscredsanon.h"
49 #include "crypto/tlscredsx509.h"
50 #include "crypto/random.h"
51 #include "qom/object_interfaces.h"
52 #include "qemu/cutils.h"
53 #include "qemu/help_option.h"
54 #include "io/dns-resolver.h"
56 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
57 #define VNC_REFRESH_INTERVAL_INC 50
58 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
59 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
60 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
62 #include "vnc_keysym.h"
63 #include "crypto/cipher.h"
65 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
66 QTAILQ_HEAD_INITIALIZER(vnc_displays);
68 static int vnc_cursor_define(VncState *vs);
69 static void vnc_update_throttle_offset(VncState *vs);
71 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
73 #ifdef _VNC_DEBUG
74 static const char *mn[] = {
75 [0] = "undefined",
76 [VNC_SHARE_MODE_CONNECTING] = "connecting",
77 [VNC_SHARE_MODE_SHARED] = "shared",
78 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
79 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
81 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
82 vs->ioc, mn[vs->share_mode], mn[mode]);
83 #endif
85 switch (vs->share_mode) {
86 case VNC_SHARE_MODE_CONNECTING:
87 vs->vd->num_connecting--;
88 break;
89 case VNC_SHARE_MODE_SHARED:
90 vs->vd->num_shared--;
91 break;
92 case VNC_SHARE_MODE_EXCLUSIVE:
93 vs->vd->num_exclusive--;
94 break;
95 default:
96 break;
99 vs->share_mode = mode;
101 switch (vs->share_mode) {
102 case VNC_SHARE_MODE_CONNECTING:
103 vs->vd->num_connecting++;
104 break;
105 case VNC_SHARE_MODE_SHARED:
106 vs->vd->num_shared++;
107 break;
108 case VNC_SHARE_MODE_EXCLUSIVE:
109 vs->vd->num_exclusive++;
110 break;
111 default:
112 break;
117 static void vnc_init_basic_info(SocketAddress *addr,
118 VncBasicInfo *info,
119 Error **errp)
121 switch (addr->type) {
122 case SOCKET_ADDRESS_TYPE_INET:
123 info->host = g_strdup(addr->u.inet.host);
124 info->service = g_strdup(addr->u.inet.port);
125 if (addr->u.inet.ipv6) {
126 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
127 } else {
128 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
130 break;
132 case SOCKET_ADDRESS_TYPE_UNIX:
133 info->host = g_strdup("");
134 info->service = g_strdup(addr->u.q_unix.path);
135 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
136 break;
138 case SOCKET_ADDRESS_TYPE_VSOCK:
139 case SOCKET_ADDRESS_TYPE_FD:
140 error_setg(errp, "Unsupported socket address type %s",
141 SocketAddressType_str(addr->type));
142 break;
143 default:
144 abort();
147 return;
150 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
151 VncBasicInfo *info,
152 Error **errp)
154 SocketAddress *addr = NULL;
156 if (!ioc) {
157 error_setg(errp, "No listener socket available");
158 return;
161 addr = qio_channel_socket_get_local_address(ioc, errp);
162 if (!addr) {
163 return;
166 vnc_init_basic_info(addr, info, errp);
167 qapi_free_SocketAddress(addr);
170 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
171 VncBasicInfo *info,
172 Error **errp)
174 SocketAddress *addr = NULL;
176 addr = qio_channel_socket_get_remote_address(ioc, errp);
177 if (!addr) {
178 return;
181 vnc_init_basic_info(addr, info, errp);
182 qapi_free_SocketAddress(addr);
185 static const char *vnc_auth_name(VncDisplay *vd) {
186 switch (vd->auth) {
187 case VNC_AUTH_INVALID:
188 return "invalid";
189 case VNC_AUTH_NONE:
190 return "none";
191 case VNC_AUTH_VNC:
192 return "vnc";
193 case VNC_AUTH_RA2:
194 return "ra2";
195 case VNC_AUTH_RA2NE:
196 return "ra2ne";
197 case VNC_AUTH_TIGHT:
198 return "tight";
199 case VNC_AUTH_ULTRA:
200 return "ultra";
201 case VNC_AUTH_TLS:
202 return "tls";
203 case VNC_AUTH_VENCRYPT:
204 switch (vd->subauth) {
205 case VNC_AUTH_VENCRYPT_PLAIN:
206 return "vencrypt+plain";
207 case VNC_AUTH_VENCRYPT_TLSNONE:
208 return "vencrypt+tls+none";
209 case VNC_AUTH_VENCRYPT_TLSVNC:
210 return "vencrypt+tls+vnc";
211 case VNC_AUTH_VENCRYPT_TLSPLAIN:
212 return "vencrypt+tls+plain";
213 case VNC_AUTH_VENCRYPT_X509NONE:
214 return "vencrypt+x509+none";
215 case VNC_AUTH_VENCRYPT_X509VNC:
216 return "vencrypt+x509+vnc";
217 case VNC_AUTH_VENCRYPT_X509PLAIN:
218 return "vencrypt+x509+plain";
219 case VNC_AUTH_VENCRYPT_TLSSASL:
220 return "vencrypt+tls+sasl";
221 case VNC_AUTH_VENCRYPT_X509SASL:
222 return "vencrypt+x509+sasl";
223 default:
224 return "vencrypt";
226 case VNC_AUTH_SASL:
227 return "sasl";
229 return "unknown";
232 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
234 VncServerInfo *info;
235 Error *err = NULL;
237 if (!vd->listener || !vd->listener->nsioc) {
238 return NULL;
241 info = g_malloc0(sizeof(*info));
242 vnc_init_basic_info_from_server_addr(vd->listener->sioc[0],
243 qapi_VncServerInfo_base(info), &err);
244 info->has_auth = true;
245 info->auth = g_strdup(vnc_auth_name(vd));
246 if (err) {
247 qapi_free_VncServerInfo(info);
248 info = NULL;
249 error_free(err);
251 return info;
254 static void vnc_client_cache_auth(VncState *client)
256 if (!client->info) {
257 return;
260 if (client->tls) {
261 client->info->x509_dname =
262 qcrypto_tls_session_get_peer_name(client->tls);
263 client->info->has_x509_dname =
264 client->info->x509_dname != NULL;
266 #ifdef CONFIG_VNC_SASL
267 if (client->sasl.conn &&
268 client->sasl.username) {
269 client->info->has_sasl_username = true;
270 client->info->sasl_username = g_strdup(client->sasl.username);
272 #endif
275 static void vnc_client_cache_addr(VncState *client)
277 Error *err = NULL;
279 client->info = g_malloc0(sizeof(*client->info));
280 vnc_init_basic_info_from_remote_addr(client->sioc,
281 qapi_VncClientInfo_base(client->info),
282 &err);
283 client->info->websocket = client->websocket;
284 if (err) {
285 qapi_free_VncClientInfo(client->info);
286 client->info = NULL;
287 error_free(err);
291 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
293 VncServerInfo *si;
295 if (!vs->info) {
296 return;
299 si = vnc_server_info_get(vs->vd);
300 if (!si) {
301 return;
304 switch (event) {
305 case QAPI_EVENT_VNC_CONNECTED:
306 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info));
307 break;
308 case QAPI_EVENT_VNC_INITIALIZED:
309 qapi_event_send_vnc_initialized(si, vs->info);
310 break;
311 case QAPI_EVENT_VNC_DISCONNECTED:
312 qapi_event_send_vnc_disconnected(si, vs->info);
313 break;
314 default:
315 break;
318 qapi_free_VncServerInfo(si);
321 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
323 VncClientInfo *info;
324 Error *err = NULL;
326 info = g_malloc0(sizeof(*info));
328 vnc_init_basic_info_from_remote_addr(client->sioc,
329 qapi_VncClientInfo_base(info),
330 &err);
331 if (err) {
332 error_free(err);
333 qapi_free_VncClientInfo(info);
334 return NULL;
337 info->websocket = client->websocket;
339 if (client->tls) {
340 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
341 info->has_x509_dname = info->x509_dname != NULL;
343 #ifdef CONFIG_VNC_SASL
344 if (client->sasl.conn && client->sasl.username) {
345 info->has_sasl_username = true;
346 info->sasl_username = g_strdup(client->sasl.username);
348 #endif
350 return info;
353 static VncDisplay *vnc_display_find(const char *id)
355 VncDisplay *vd;
357 if (id == NULL) {
358 return QTAILQ_FIRST(&vnc_displays);
360 QTAILQ_FOREACH(vd, &vnc_displays, next) {
361 if (strcmp(id, vd->id) == 0) {
362 return vd;
365 return NULL;
368 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
370 VncClientInfoList *prev = NULL;
371 VncState *client;
373 QTAILQ_FOREACH(client, &vd->clients, next) {
374 QAPI_LIST_PREPEND(prev, qmp_query_vnc_client(client));
376 return prev;
379 VncInfo *qmp_query_vnc(Error **errp)
381 VncInfo *info = g_malloc0(sizeof(*info));
382 VncDisplay *vd = vnc_display_find(NULL);
383 SocketAddress *addr = NULL;
385 if (vd == NULL || !vd->listener || !vd->listener->nsioc) {
386 info->enabled = false;
387 } else {
388 info->enabled = true;
390 /* for compatibility with the original command */
391 info->has_clients = true;
392 info->clients = qmp_query_client_list(vd);
394 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0],
395 errp);
396 if (!addr) {
397 goto out_error;
400 switch (addr->type) {
401 case SOCKET_ADDRESS_TYPE_INET:
402 info->host = g_strdup(addr->u.inet.host);
403 info->service = g_strdup(addr->u.inet.port);
404 if (addr->u.inet.ipv6) {
405 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
406 } else {
407 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
409 break;
411 case SOCKET_ADDRESS_TYPE_UNIX:
412 info->host = g_strdup("");
413 info->service = g_strdup(addr->u.q_unix.path);
414 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
415 break;
417 case SOCKET_ADDRESS_TYPE_VSOCK:
418 case SOCKET_ADDRESS_TYPE_FD:
419 error_setg(errp, "Unsupported socket address type %s",
420 SocketAddressType_str(addr->type));
421 goto out_error;
422 default:
423 abort();
426 info->has_host = true;
427 info->has_service = true;
428 info->has_family = true;
430 info->has_auth = true;
431 info->auth = g_strdup(vnc_auth_name(vd));
434 qapi_free_SocketAddress(addr);
435 return info;
437 out_error:
438 qapi_free_SocketAddress(addr);
439 qapi_free_VncInfo(info);
440 return NULL;
444 static void qmp_query_auth(int auth, int subauth,
445 VncPrimaryAuth *qmp_auth,
446 VncVencryptSubAuth *qmp_vencrypt,
447 bool *qmp_has_vencrypt);
449 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
450 bool websocket,
451 int auth,
452 int subauth,
453 VncServerInfo2List *prev)
455 VncServerInfo2 *info;
456 Error *err = NULL;
457 SocketAddress *addr;
459 addr = qio_channel_socket_get_local_address(ioc, NULL);
460 if (!addr) {
461 return prev;
464 info = g_new0(VncServerInfo2, 1);
465 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
466 qapi_free_SocketAddress(addr);
467 if (err) {
468 qapi_free_VncServerInfo2(info);
469 error_free(err);
470 return prev;
472 info->websocket = websocket;
474 qmp_query_auth(auth, subauth, &info->auth,
475 &info->vencrypt, &info->has_vencrypt);
477 QAPI_LIST_PREPEND(prev, info);
478 return prev;
481 static void qmp_query_auth(int auth, int subauth,
482 VncPrimaryAuth *qmp_auth,
483 VncVencryptSubAuth *qmp_vencrypt,
484 bool *qmp_has_vencrypt)
486 switch (auth) {
487 case VNC_AUTH_VNC:
488 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
489 break;
490 case VNC_AUTH_RA2:
491 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
492 break;
493 case VNC_AUTH_RA2NE:
494 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
495 break;
496 case VNC_AUTH_TIGHT:
497 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
498 break;
499 case VNC_AUTH_ULTRA:
500 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
501 break;
502 case VNC_AUTH_TLS:
503 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
504 break;
505 case VNC_AUTH_VENCRYPT:
506 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
507 *qmp_has_vencrypt = true;
508 switch (subauth) {
509 case VNC_AUTH_VENCRYPT_PLAIN:
510 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
511 break;
512 case VNC_AUTH_VENCRYPT_TLSNONE:
513 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
514 break;
515 case VNC_AUTH_VENCRYPT_TLSVNC:
516 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
517 break;
518 case VNC_AUTH_VENCRYPT_TLSPLAIN:
519 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
520 break;
521 case VNC_AUTH_VENCRYPT_X509NONE:
522 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
523 break;
524 case VNC_AUTH_VENCRYPT_X509VNC:
525 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
526 break;
527 case VNC_AUTH_VENCRYPT_X509PLAIN:
528 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
529 break;
530 case VNC_AUTH_VENCRYPT_TLSSASL:
531 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
532 break;
533 case VNC_AUTH_VENCRYPT_X509SASL:
534 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
535 break;
536 default:
537 *qmp_has_vencrypt = false;
538 break;
540 break;
541 case VNC_AUTH_SASL:
542 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
543 break;
544 case VNC_AUTH_NONE:
545 default:
546 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
547 break;
551 VncInfo2List *qmp_query_vnc_servers(Error **errp)
553 VncInfo2List *prev = NULL;
554 VncInfo2 *info;
555 VncDisplay *vd;
556 DeviceState *dev;
557 size_t i;
559 QTAILQ_FOREACH(vd, &vnc_displays, next) {
560 info = g_new0(VncInfo2, 1);
561 info->id = g_strdup(vd->id);
562 info->clients = qmp_query_client_list(vd);
563 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
564 &info->vencrypt, &info->has_vencrypt);
565 if (vd->dcl.con) {
566 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
567 "device", &error_abort));
568 info->has_display = true;
569 info->display = g_strdup(dev->id);
571 for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) {
572 info->server = qmp_query_server_entry(
573 vd->listener->sioc[i], false, vd->auth, vd->subauth,
574 info->server);
576 for (i = 0; vd->wslistener != NULL && i < vd->wslistener->nsioc; i++) {
577 info->server = qmp_query_server_entry(
578 vd->wslistener->sioc[i], true, vd->ws_auth,
579 vd->ws_subauth, info->server);
582 QAPI_LIST_PREPEND(prev, info);
584 return prev;
587 /* TODO
588 1) Get the queue working for IO.
589 2) there is some weirdness when using the -S option (the screen is grey
590 and not totally invalidated
591 3) resolutions > 1024
594 static int vnc_update_client(VncState *vs, int has_dirty);
595 static void vnc_disconnect_start(VncState *vs);
597 static void vnc_colordepth(VncState *vs);
598 static void framebuffer_update_request(VncState *vs, int incremental,
599 int x_position, int y_position,
600 int w, int h);
601 static void vnc_refresh(DisplayChangeListener *dcl);
602 static int vnc_refresh_server_surface(VncDisplay *vd);
604 static int vnc_width(VncDisplay *vd)
606 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
607 VNC_DIRTY_PIXELS_PER_BIT));
610 static int vnc_height(VncDisplay *vd)
612 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
615 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
616 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
617 VncDisplay *vd,
618 int x, int y, int w, int h)
620 int width = vnc_width(vd);
621 int height = vnc_height(vd);
623 /* this is needed this to ensure we updated all affected
624 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
625 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
626 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
628 x = MIN(x, width);
629 y = MIN(y, height);
630 w = MIN(x + w, width) - x;
631 h = MIN(y + h, height);
633 for (; y < h; y++) {
634 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
635 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
639 static void vnc_dpy_update(DisplayChangeListener *dcl,
640 int x, int y, int w, int h)
642 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
643 struct VncSurface *s = &vd->guest;
645 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
648 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
649 int32_t encoding)
651 vnc_write_u16(vs, x);
652 vnc_write_u16(vs, y);
653 vnc_write_u16(vs, w);
654 vnc_write_u16(vs, h);
656 vnc_write_s32(vs, encoding);
659 static void vnc_desktop_resize_ext(VncState *vs, int reject_reason)
661 vnc_lock_output(vs);
662 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
663 vnc_write_u8(vs, 0);
664 vnc_write_u16(vs, 1); /* number of rects */
665 vnc_framebuffer_update(vs,
666 reject_reason ? 1 : 0,
667 reject_reason,
668 vs->client_width, vs->client_height,
669 VNC_ENCODING_DESKTOP_RESIZE_EXT);
670 vnc_write_u8(vs, 1); /* number of screens */
671 vnc_write_u8(vs, 0); /* padding */
672 vnc_write_u8(vs, 0); /* padding */
673 vnc_write_u8(vs, 0); /* padding */
674 vnc_write_u32(vs, 0); /* screen id */
675 vnc_write_u16(vs, 0); /* screen x-pos */
676 vnc_write_u16(vs, 0); /* screen y-pos */
677 vnc_write_u16(vs, vs->client_width);
678 vnc_write_u16(vs, vs->client_height);
679 vnc_write_u32(vs, 0); /* screen flags */
680 vnc_unlock_output(vs);
681 vnc_flush(vs);
684 static void vnc_desktop_resize(VncState *vs)
686 if (vs->ioc == NULL || (!vnc_has_feature(vs, VNC_FEATURE_RESIZE) &&
687 !vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT))) {
688 return;
690 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
691 vs->client_height == pixman_image_get_height(vs->vd->server)) {
692 return;
695 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
696 pixman_image_get_width(vs->vd->server) >= 0);
697 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
698 pixman_image_get_height(vs->vd->server) >= 0);
699 vs->client_width = pixman_image_get_width(vs->vd->server);
700 vs->client_height = pixman_image_get_height(vs->vd->server);
702 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
703 vnc_desktop_resize_ext(vs, 0);
704 return;
707 vnc_lock_output(vs);
708 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
709 vnc_write_u8(vs, 0);
710 vnc_write_u16(vs, 1); /* number of rects */
711 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
712 VNC_ENCODING_DESKTOPRESIZE);
713 vnc_unlock_output(vs);
714 vnc_flush(vs);
717 static void vnc_abort_display_jobs(VncDisplay *vd)
719 VncState *vs;
721 QTAILQ_FOREACH(vs, &vd->clients, next) {
722 vnc_lock_output(vs);
723 vs->abort = true;
724 vnc_unlock_output(vs);
726 QTAILQ_FOREACH(vs, &vd->clients, next) {
727 vnc_jobs_join(vs);
729 QTAILQ_FOREACH(vs, &vd->clients, next) {
730 vnc_lock_output(vs);
731 if (vs->update == VNC_STATE_UPDATE_NONE &&
732 vs->job_update != VNC_STATE_UPDATE_NONE) {
733 /* job aborted before completion */
734 vs->update = vs->job_update;
735 vs->job_update = VNC_STATE_UPDATE_NONE;
737 vs->abort = false;
738 vnc_unlock_output(vs);
742 int vnc_server_fb_stride(VncDisplay *vd)
744 return pixman_image_get_stride(vd->server);
747 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
749 uint8_t *ptr;
751 ptr = (uint8_t *)pixman_image_get_data(vd->server);
752 ptr += y * vnc_server_fb_stride(vd);
753 ptr += x * VNC_SERVER_FB_BYTES;
754 return ptr;
757 static void vnc_update_server_surface(VncDisplay *vd)
759 int width, height;
761 qemu_pixman_image_unref(vd->server);
762 vd->server = NULL;
764 if (QTAILQ_EMPTY(&vd->clients)) {
765 return;
768 width = vnc_width(vd);
769 height = vnc_height(vd);
770 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
771 width, height,
772 NULL, 0);
774 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
775 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
776 width, height);
779 static bool vnc_check_pageflip(DisplaySurface *s1,
780 DisplaySurface *s2)
782 return (s1 != NULL &&
783 s2 != NULL &&
784 surface_width(s1) == surface_width(s2) &&
785 surface_height(s1) == surface_height(s2) &&
786 surface_format(s1) == surface_format(s2));
790 static void vnc_dpy_switch(DisplayChangeListener *dcl,
791 DisplaySurface *surface)
793 static const char placeholder_msg[] =
794 "Display output is not active.";
795 static DisplaySurface *placeholder;
796 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
797 bool pageflip = vnc_check_pageflip(vd->ds, surface);
798 VncState *vs;
800 if (surface == NULL) {
801 if (placeholder == NULL) {
802 placeholder = qemu_create_message_surface(640, 480, placeholder_msg);
804 surface = placeholder;
807 vnc_abort_display_jobs(vd);
808 vd->ds = surface;
810 /* guest surface */
811 qemu_pixman_image_unref(vd->guest.fb);
812 vd->guest.fb = pixman_image_ref(surface->image);
813 vd->guest.format = surface->format;
815 if (pageflip) {
816 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
817 surface_width(surface),
818 surface_height(surface));
819 return;
822 /* server surface */
823 vnc_update_server_surface(vd);
825 QTAILQ_FOREACH(vs, &vd->clients, next) {
826 vnc_colordepth(vs);
827 vnc_desktop_resize(vs);
828 vnc_cursor_define(vs);
829 memset(vs->dirty, 0x00, sizeof(vs->dirty));
830 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
831 vnc_width(vd),
832 vnc_height(vd));
833 vnc_update_throttle_offset(vs);
837 /* fastest code */
838 static void vnc_write_pixels_copy(VncState *vs,
839 void *pixels, int size)
841 vnc_write(vs, pixels, size);
844 /* slowest but generic code. */
845 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
847 uint8_t r, g, b;
849 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
850 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
851 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
852 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
853 #else
854 # error need some bits here if you change VNC_SERVER_FB_FORMAT
855 #endif
856 v = (r << vs->client_pf.rshift) |
857 (g << vs->client_pf.gshift) |
858 (b << vs->client_pf.bshift);
859 switch (vs->client_pf.bytes_per_pixel) {
860 case 1:
861 buf[0] = v;
862 break;
863 case 2:
864 if (vs->client_be) {
865 buf[0] = v >> 8;
866 buf[1] = v;
867 } else {
868 buf[1] = v >> 8;
869 buf[0] = v;
871 break;
872 default:
873 case 4:
874 if (vs->client_be) {
875 buf[0] = v >> 24;
876 buf[1] = v >> 16;
877 buf[2] = v >> 8;
878 buf[3] = v;
879 } else {
880 buf[3] = v >> 24;
881 buf[2] = v >> 16;
882 buf[1] = v >> 8;
883 buf[0] = v;
885 break;
889 static void vnc_write_pixels_generic(VncState *vs,
890 void *pixels1, int size)
892 uint8_t buf[4];
894 if (VNC_SERVER_FB_BYTES == 4) {
895 uint32_t *pixels = pixels1;
896 int n, i;
897 n = size >> 2;
898 for (i = 0; i < n; i++) {
899 vnc_convert_pixel(vs, buf, pixels[i]);
900 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
905 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
907 int i;
908 uint8_t *row;
909 VncDisplay *vd = vs->vd;
911 row = vnc_server_fb_ptr(vd, x, y);
912 for (i = 0; i < h; i++) {
913 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
914 row += vnc_server_fb_stride(vd);
916 return 1;
919 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
921 int n = 0;
923 switch(vs->vnc_encoding) {
924 case VNC_ENCODING_ZLIB:
925 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
926 break;
927 case VNC_ENCODING_HEXTILE:
928 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
929 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
930 break;
931 case VNC_ENCODING_TIGHT:
932 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
933 break;
934 case VNC_ENCODING_TIGHT_PNG:
935 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
936 break;
937 case VNC_ENCODING_ZRLE:
938 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
939 break;
940 case VNC_ENCODING_ZYWRLE:
941 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
942 break;
943 default:
944 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
945 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
946 break;
948 return n;
951 static void vnc_mouse_set(DisplayChangeListener *dcl,
952 int x, int y, int visible)
954 /* can we ask the client(s) to move the pointer ??? */
957 static int vnc_cursor_define(VncState *vs)
959 QEMUCursor *c = vs->vd->cursor;
960 int isize;
962 if (!vs->vd->cursor) {
963 return -1;
966 if (vnc_has_feature(vs, VNC_FEATURE_ALPHA_CURSOR)) {
967 vnc_lock_output(vs);
968 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
969 vnc_write_u8(vs, 0); /* padding */
970 vnc_write_u16(vs, 1); /* # of rects */
971 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
972 VNC_ENCODING_ALPHA_CURSOR);
973 vnc_write_s32(vs, VNC_ENCODING_RAW);
974 vnc_write(vs, c->data, c->width * c->height * 4);
975 vnc_unlock_output(vs);
976 return 0;
978 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
979 vnc_lock_output(vs);
980 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
981 vnc_write_u8(vs, 0); /* padding */
982 vnc_write_u16(vs, 1); /* # of rects */
983 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
984 VNC_ENCODING_RICH_CURSOR);
985 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
986 vnc_write_pixels_generic(vs, c->data, isize);
987 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
988 vnc_unlock_output(vs);
989 return 0;
991 return -1;
994 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
995 QEMUCursor *c)
997 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
998 VncState *vs;
1000 cursor_put(vd->cursor);
1001 g_free(vd->cursor_mask);
1003 vd->cursor = c;
1004 cursor_get(vd->cursor);
1005 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1006 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1007 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1009 QTAILQ_FOREACH(vs, &vd->clients, next) {
1010 vnc_cursor_define(vs);
1014 static int find_and_clear_dirty_height(VncState *vs,
1015 int y, int last_x, int x, int height)
1017 int h;
1019 for (h = 1; h < (height - y); h++) {
1020 if (!test_bit(last_x, vs->dirty[y + h])) {
1021 break;
1023 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1026 return h;
1030 * Figure out how much pending data we should allow in the output
1031 * buffer before we throttle incremental display updates, and/or
1032 * drop audio samples.
1034 * We allow for equiv of 1 full display's worth of FB updates,
1035 * and 1 second of audio samples. If audio backlog was larger
1036 * than that the client would already suffering awful audio
1037 * glitches, so dropping samples is no worse really).
1039 static void vnc_update_throttle_offset(VncState *vs)
1041 size_t offset =
1042 vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
1044 if (vs->audio_cap) {
1045 int bps;
1046 switch (vs->as.fmt) {
1047 default:
1048 case AUDIO_FORMAT_U8:
1049 case AUDIO_FORMAT_S8:
1050 bps = 1;
1051 break;
1052 case AUDIO_FORMAT_U16:
1053 case AUDIO_FORMAT_S16:
1054 bps = 2;
1055 break;
1056 case AUDIO_FORMAT_U32:
1057 case AUDIO_FORMAT_S32:
1058 bps = 4;
1059 break;
1061 offset += vs->as.freq * bps * vs->as.nchannels;
1064 /* Put a floor of 1MB on offset, so that if we have a large pending
1065 * buffer and the display is resized to a small size & back again
1066 * we don't suddenly apply a tiny send limit
1068 offset = MAX(offset, 1024 * 1024);
1070 if (vs->throttle_output_offset != offset) {
1071 trace_vnc_client_throttle_threshold(
1072 vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
1073 vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
1076 vs->throttle_output_offset = offset;
1079 static bool vnc_should_update(VncState *vs)
1081 switch (vs->update) {
1082 case VNC_STATE_UPDATE_NONE:
1083 break;
1084 case VNC_STATE_UPDATE_INCREMENTAL:
1085 /* Only allow incremental updates if the pending send queue
1086 * is less than the permitted threshold, and the job worker
1087 * is completely idle.
1089 if (vs->output.offset < vs->throttle_output_offset &&
1090 vs->job_update == VNC_STATE_UPDATE_NONE) {
1091 return true;
1093 trace_vnc_client_throttle_incremental(
1094 vs, vs->ioc, vs->job_update, vs->output.offset);
1095 break;
1096 case VNC_STATE_UPDATE_FORCE:
1097 /* Only allow forced updates if the pending send queue
1098 * does not contain a previous forced update, and the
1099 * job worker is completely idle.
1101 * Note this means we'll queue a forced update, even if
1102 * the output buffer size is otherwise over the throttle
1103 * output limit.
1105 if (vs->force_update_offset == 0 &&
1106 vs->job_update == VNC_STATE_UPDATE_NONE) {
1107 return true;
1109 trace_vnc_client_throttle_forced(
1110 vs, vs->ioc, vs->job_update, vs->force_update_offset);
1111 break;
1113 return false;
1116 static int vnc_update_client(VncState *vs, int has_dirty)
1118 VncDisplay *vd = vs->vd;
1119 VncJob *job;
1120 int y;
1121 int height, width;
1122 int n = 0;
1124 if (vs->disconnecting) {
1125 vnc_disconnect_finish(vs);
1126 return 0;
1129 vs->has_dirty += has_dirty;
1130 if (!vnc_should_update(vs)) {
1131 return 0;
1134 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
1135 return 0;
1139 * Send screen updates to the vnc client using the server
1140 * surface and server dirty map. guest surface updates
1141 * happening in parallel don't disturb us, the next pass will
1142 * send them to the client.
1144 job = vnc_job_new(vs);
1146 height = pixman_image_get_height(vd->server);
1147 width = pixman_image_get_width(vd->server);
1149 y = 0;
1150 for (;;) {
1151 int x, h;
1152 unsigned long x2;
1153 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1154 height * VNC_DIRTY_BPL(vs),
1155 y * VNC_DIRTY_BPL(vs));
1156 if (offset == height * VNC_DIRTY_BPL(vs)) {
1157 /* no more dirty bits */
1158 break;
1160 y = offset / VNC_DIRTY_BPL(vs);
1161 x = offset % VNC_DIRTY_BPL(vs);
1162 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1163 VNC_DIRTY_BPL(vs), x);
1164 bitmap_clear(vs->dirty[y], x, x2 - x);
1165 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1166 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1167 if (x2 > x) {
1168 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1169 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1171 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1172 y += h;
1173 if (y == height) {
1174 break;
1179 vs->job_update = vs->update;
1180 vs->update = VNC_STATE_UPDATE_NONE;
1181 vnc_job_push(job);
1182 vs->has_dirty = 0;
1183 return n;
1186 /* audio */
1187 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1189 VncState *vs = opaque;
1191 assert(vs->magic == VNC_MAGIC);
1192 switch (cmd) {
1193 case AUD_CNOTIFY_DISABLE:
1194 vnc_lock_output(vs);
1195 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1196 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1197 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1198 vnc_unlock_output(vs);
1199 vnc_flush(vs);
1200 break;
1202 case AUD_CNOTIFY_ENABLE:
1203 vnc_lock_output(vs);
1204 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1205 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1206 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1207 vnc_unlock_output(vs);
1208 vnc_flush(vs);
1209 break;
1213 static void audio_capture_destroy(void *opaque)
1217 static void audio_capture(void *opaque, const void *buf, int size)
1219 VncState *vs = opaque;
1221 assert(vs->magic == VNC_MAGIC);
1222 vnc_lock_output(vs);
1223 if (vs->output.offset < vs->throttle_output_offset) {
1224 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1225 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1226 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1227 vnc_write_u32(vs, size);
1228 vnc_write(vs, buf, size);
1229 } else {
1230 trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
1232 vnc_unlock_output(vs);
1233 vnc_flush(vs);
1236 static void audio_add(VncState *vs)
1238 struct audio_capture_ops ops;
1240 if (vs->audio_cap) {
1241 error_report("audio already running");
1242 return;
1245 ops.notify = audio_capture_notify;
1246 ops.destroy = audio_capture_destroy;
1247 ops.capture = audio_capture;
1249 vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs);
1250 if (!vs->audio_cap) {
1251 error_report("Failed to add audio capture");
1255 static void audio_del(VncState *vs)
1257 if (vs->audio_cap) {
1258 AUD_del_capture(vs->audio_cap, vs);
1259 vs->audio_cap = NULL;
1263 static void vnc_disconnect_start(VncState *vs)
1265 if (vs->disconnecting) {
1266 return;
1268 trace_vnc_client_disconnect_start(vs, vs->ioc);
1269 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1270 if (vs->ioc_tag) {
1271 g_source_remove(vs->ioc_tag);
1272 vs->ioc_tag = 0;
1274 qio_channel_close(vs->ioc, NULL);
1275 vs->disconnecting = TRUE;
1278 void vnc_disconnect_finish(VncState *vs)
1280 int i;
1282 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1284 vnc_jobs_join(vs); /* Wait encoding jobs */
1286 vnc_lock_output(vs);
1287 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1289 buffer_free(&vs->input);
1290 buffer_free(&vs->output);
1292 qapi_free_VncClientInfo(vs->info);
1294 vnc_zlib_clear(vs);
1295 vnc_tight_clear(vs);
1296 vnc_zrle_clear(vs);
1298 #ifdef CONFIG_VNC_SASL
1299 vnc_sasl_client_cleanup(vs);
1300 #endif /* CONFIG_VNC_SASL */
1301 audio_del(vs);
1302 qkbd_state_lift_all_keys(vs->vd->kbd);
1304 if (vs->mouse_mode_notifier.notify != NULL) {
1305 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1307 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1308 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1309 /* last client gone */
1310 vnc_update_server_surface(vs->vd);
1313 vnc_unlock_output(vs);
1315 qemu_mutex_destroy(&vs->output_mutex);
1316 if (vs->bh != NULL) {
1317 qemu_bh_delete(vs->bh);
1319 buffer_free(&vs->jobs_buffer);
1321 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1322 g_free(vs->lossy_rect[i]);
1324 g_free(vs->lossy_rect);
1326 object_unref(OBJECT(vs->ioc));
1327 vs->ioc = NULL;
1328 object_unref(OBJECT(vs->sioc));
1329 vs->sioc = NULL;
1330 vs->magic = 0;
1331 g_free(vs->zrle);
1332 g_free(vs->tight);
1333 g_free(vs);
1336 size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err)
1338 if (ret <= 0) {
1339 if (ret == 0) {
1340 trace_vnc_client_eof(vs, vs->ioc);
1341 vnc_disconnect_start(vs);
1342 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1343 trace_vnc_client_io_error(vs, vs->ioc,
1344 err ? error_get_pretty(err) : "Unknown");
1345 vnc_disconnect_start(vs);
1348 error_free(err);
1349 return 0;
1351 return ret;
1355 void vnc_client_error(VncState *vs)
1357 VNC_DEBUG("Closing down client sock: protocol error\n");
1358 vnc_disconnect_start(vs);
1363 * Called to write a chunk of data to the client socket. The data may
1364 * be the raw data, or may have already been encoded by SASL.
1365 * The data will be written either straight onto the socket, or
1366 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1368 * NB, it is theoretically possible to have 2 layers of encryption,
1369 * both SASL, and this TLS layer. It is highly unlikely in practice
1370 * though, since SASL encryption will typically be a no-op if TLS
1371 * is active
1373 * Returns the number of bytes written, which may be less than
1374 * the requested 'datalen' if the socket would block. Returns
1375 * 0 on I/O error, and disconnects the client socket.
1377 size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1379 Error *err = NULL;
1380 ssize_t ret;
1381 ret = qio_channel_write(vs->ioc, (const char *)data, datalen, &err);
1382 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1383 return vnc_client_io_error(vs, ret, err);
1388 * Called to write buffered data to the client socket, when not
1389 * using any SASL SSF encryption layers. Will write as much data
1390 * as possible without blocking. If all buffered data is written,
1391 * will switch the FD poll() handler back to read monitoring.
1393 * Returns the number of bytes written, which may be less than
1394 * the buffered output data if the socket would block. Returns
1395 * 0 on I/O error, and disconnects the client socket.
1397 static size_t vnc_client_write_plain(VncState *vs)
1399 size_t offset;
1400 size_t ret;
1402 #ifdef CONFIG_VNC_SASL
1403 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1404 vs->output.buffer, vs->output.capacity, vs->output.offset,
1405 vs->sasl.waitWriteSSF);
1407 if (vs->sasl.conn &&
1408 vs->sasl.runSSF &&
1409 vs->sasl.waitWriteSSF) {
1410 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1411 if (ret)
1412 vs->sasl.waitWriteSSF -= ret;
1413 } else
1414 #endif /* CONFIG_VNC_SASL */
1415 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1416 if (!ret)
1417 return 0;
1419 if (ret >= vs->force_update_offset) {
1420 if (vs->force_update_offset != 0) {
1421 trace_vnc_client_unthrottle_forced(vs, vs->ioc);
1423 vs->force_update_offset = 0;
1424 } else {
1425 vs->force_update_offset -= ret;
1427 offset = vs->output.offset;
1428 buffer_advance(&vs->output, ret);
1429 if (offset >= vs->throttle_output_offset &&
1430 vs->output.offset < vs->throttle_output_offset) {
1431 trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
1434 if (vs->output.offset == 0) {
1435 if (vs->ioc_tag) {
1436 g_source_remove(vs->ioc_tag);
1438 vs->ioc_tag = qio_channel_add_watch(
1439 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1440 vnc_client_io, vs, NULL);
1443 return ret;
1448 * First function called whenever there is data to be written to
1449 * the client socket. Will delegate actual work according to whether
1450 * SASL SSF layers are enabled (thus requiring encryption calls)
1452 static void vnc_client_write_locked(VncState *vs)
1454 #ifdef CONFIG_VNC_SASL
1455 if (vs->sasl.conn &&
1456 vs->sasl.runSSF &&
1457 !vs->sasl.waitWriteSSF) {
1458 vnc_client_write_sasl(vs);
1459 } else
1460 #endif /* CONFIG_VNC_SASL */
1462 vnc_client_write_plain(vs);
1466 static void vnc_client_write(VncState *vs)
1468 assert(vs->magic == VNC_MAGIC);
1469 vnc_lock_output(vs);
1470 if (vs->output.offset) {
1471 vnc_client_write_locked(vs);
1472 } else if (vs->ioc != NULL) {
1473 if (vs->ioc_tag) {
1474 g_source_remove(vs->ioc_tag);
1476 vs->ioc_tag = qio_channel_add_watch(
1477 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1478 vnc_client_io, vs, NULL);
1480 vnc_unlock_output(vs);
1483 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1485 vs->read_handler = func;
1486 vs->read_handler_expect = expecting;
1491 * Called to read a chunk of data from the client socket. The data may
1492 * be the raw data, or may need to be further decoded by SASL.
1493 * The data will be read either straight from to the socket, or
1494 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1496 * NB, it is theoretically possible to have 2 layers of encryption,
1497 * both SASL, and this TLS layer. It is highly unlikely in practice
1498 * though, since SASL encryption will typically be a no-op if TLS
1499 * is active
1501 * Returns the number of bytes read, which may be less than
1502 * the requested 'datalen' if the socket would block. Returns
1503 * 0 on I/O error or EOF, and disconnects the client socket.
1505 size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1507 ssize_t ret;
1508 Error *err = NULL;
1509 ret = qio_channel_read(vs->ioc, (char *)data, datalen, &err);
1510 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1511 return vnc_client_io_error(vs, ret, err);
1516 * Called to read data from the client socket to the input buffer,
1517 * when not using any SASL SSF encryption layers. Will read as much
1518 * data as possible without blocking.
1520 * Returns the number of bytes read, which may be less than
1521 * the requested 'datalen' if the socket would block. Returns
1522 * 0 on I/O error or EOF, and disconnects the client socket.
1524 static size_t vnc_client_read_plain(VncState *vs)
1526 size_t ret;
1527 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1528 vs->input.buffer, vs->input.capacity, vs->input.offset);
1529 buffer_reserve(&vs->input, 4096);
1530 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1531 if (!ret)
1532 return 0;
1533 vs->input.offset += ret;
1534 return ret;
1537 static void vnc_jobs_bh(void *opaque)
1539 VncState *vs = opaque;
1541 assert(vs->magic == VNC_MAGIC);
1542 vnc_jobs_consume_buffer(vs);
1546 * First function called whenever there is more data to be read from
1547 * the client socket. Will delegate actual work according to whether
1548 * SASL SSF layers are enabled (thus requiring decryption calls)
1549 * Returns 0 on success, -1 if client disconnected
1551 static int vnc_client_read(VncState *vs)
1553 size_t ret;
1555 #ifdef CONFIG_VNC_SASL
1556 if (vs->sasl.conn && vs->sasl.runSSF)
1557 ret = vnc_client_read_sasl(vs);
1558 else
1559 #endif /* CONFIG_VNC_SASL */
1560 ret = vnc_client_read_plain(vs);
1561 if (!ret) {
1562 if (vs->disconnecting) {
1563 vnc_disconnect_finish(vs);
1564 return -1;
1566 return 0;
1569 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1570 size_t len = vs->read_handler_expect;
1571 int ret;
1573 ret = vs->read_handler(vs, vs->input.buffer, len);
1574 if (vs->disconnecting) {
1575 vnc_disconnect_finish(vs);
1576 return -1;
1579 if (!ret) {
1580 buffer_advance(&vs->input, len);
1581 } else {
1582 vs->read_handler_expect = ret;
1585 return 0;
1588 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1589 GIOCondition condition, void *opaque)
1591 VncState *vs = opaque;
1593 assert(vs->magic == VNC_MAGIC);
1595 if (condition & (G_IO_HUP | G_IO_ERR)) {
1596 vnc_disconnect_start(vs);
1597 return TRUE;
1600 if (condition & G_IO_IN) {
1601 if (vnc_client_read(vs) < 0) {
1602 /* vs is free()ed here */
1603 return TRUE;
1606 if (condition & G_IO_OUT) {
1607 vnc_client_write(vs);
1610 if (vs->disconnecting) {
1611 if (vs->ioc_tag != 0) {
1612 g_source_remove(vs->ioc_tag);
1614 vs->ioc_tag = 0;
1616 return TRUE;
1621 * Scale factor to apply to vs->throttle_output_offset when checking for
1622 * hard limit. Worst case normal usage could be x2, if we have a complete
1623 * incremental update and complete forced update in the output buffer.
1624 * So x3 should be good enough, but we pick x5 to be conservative and thus
1625 * (hopefully) never trigger incorrectly.
1627 #define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1629 void vnc_write(VncState *vs, const void *data, size_t len)
1631 assert(vs->magic == VNC_MAGIC);
1632 if (vs->disconnecting) {
1633 return;
1635 /* Protection against malicious client/guest to prevent our output
1636 * buffer growing without bound if client stops reading data. This
1637 * should rarely trigger, because we have earlier throttling code
1638 * which stops issuing framebuffer updates and drops audio data
1639 * if the throttle_output_offset value is exceeded. So we only reach
1640 * this higher level if a huge number of pseudo-encodings get
1641 * triggered while data can't be sent on the socket.
1643 * NB throttle_output_offset can be zero during early protocol
1644 * handshake, or from the job thread's VncState clone
1646 if (vs->throttle_output_offset != 0 &&
1647 (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
1648 vs->throttle_output_offset) {
1649 trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
1650 vs->throttle_output_offset);
1651 vnc_disconnect_start(vs);
1652 return;
1654 buffer_reserve(&vs->output, len);
1656 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1657 if (vs->ioc_tag) {
1658 g_source_remove(vs->ioc_tag);
1660 vs->ioc_tag = qio_channel_add_watch(
1661 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT,
1662 vnc_client_io, vs, NULL);
1665 buffer_append(&vs->output, data, len);
1668 void vnc_write_s32(VncState *vs, int32_t value)
1670 vnc_write_u32(vs, *(uint32_t *)&value);
1673 void vnc_write_u32(VncState *vs, uint32_t value)
1675 uint8_t buf[4];
1677 buf[0] = (value >> 24) & 0xFF;
1678 buf[1] = (value >> 16) & 0xFF;
1679 buf[2] = (value >> 8) & 0xFF;
1680 buf[3] = value & 0xFF;
1682 vnc_write(vs, buf, 4);
1685 void vnc_write_u16(VncState *vs, uint16_t value)
1687 uint8_t buf[2];
1689 buf[0] = (value >> 8) & 0xFF;
1690 buf[1] = value & 0xFF;
1692 vnc_write(vs, buf, 2);
1695 void vnc_write_u8(VncState *vs, uint8_t value)
1697 vnc_write(vs, (char *)&value, 1);
1700 void vnc_flush(VncState *vs)
1702 vnc_lock_output(vs);
1703 if (vs->ioc != NULL && vs->output.offset) {
1704 vnc_client_write_locked(vs);
1706 if (vs->disconnecting) {
1707 if (vs->ioc_tag != 0) {
1708 g_source_remove(vs->ioc_tag);
1710 vs->ioc_tag = 0;
1712 vnc_unlock_output(vs);
1715 static uint8_t read_u8(uint8_t *data, size_t offset)
1717 return data[offset];
1720 static uint16_t read_u16(uint8_t *data, size_t offset)
1722 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1725 static int32_t read_s32(uint8_t *data, size_t offset)
1727 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1728 (data[offset + 2] << 8) | data[offset + 3]);
1731 uint32_t read_u32(uint8_t *data, size_t offset)
1733 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1734 (data[offset + 2] << 8) | data[offset + 3]);
1737 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1741 static void check_pointer_type_change(Notifier *notifier, void *data)
1743 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1744 int absolute = qemu_input_is_absolute();
1746 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1747 vnc_lock_output(vs);
1748 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1749 vnc_write_u8(vs, 0);
1750 vnc_write_u16(vs, 1);
1751 vnc_framebuffer_update(vs, absolute, 0,
1752 pixman_image_get_width(vs->vd->server),
1753 pixman_image_get_height(vs->vd->server),
1754 VNC_ENCODING_POINTER_TYPE_CHANGE);
1755 vnc_unlock_output(vs);
1756 vnc_flush(vs);
1758 vs->absolute = absolute;
1761 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1763 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1764 [INPUT_BUTTON_LEFT] = 0x01,
1765 [INPUT_BUTTON_MIDDLE] = 0x02,
1766 [INPUT_BUTTON_RIGHT] = 0x04,
1767 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1768 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1770 QemuConsole *con = vs->vd->dcl.con;
1771 int width = pixman_image_get_width(vs->vd->server);
1772 int height = pixman_image_get_height(vs->vd->server);
1774 if (vs->last_bmask != button_mask) {
1775 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1776 vs->last_bmask = button_mask;
1779 if (vs->absolute) {
1780 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1781 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1782 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1783 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1784 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1785 } else {
1786 if (vs->last_x != -1) {
1787 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1788 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1790 vs->last_x = x;
1791 vs->last_y = y;
1793 qemu_input_event_sync();
1796 static void press_key(VncState *vs, QKeyCode qcode)
1798 qkbd_state_key_event(vs->vd->kbd, qcode, true);
1799 qkbd_state_key_event(vs->vd->kbd, qcode, false);
1802 static void vnc_led_state_change(VncState *vs)
1804 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1805 return;
1808 vnc_lock_output(vs);
1809 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1810 vnc_write_u8(vs, 0);
1811 vnc_write_u16(vs, 1);
1812 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1813 vnc_write_u8(vs, vs->vd->ledstate);
1814 vnc_unlock_output(vs);
1815 vnc_flush(vs);
1818 static void kbd_leds(void *opaque, int ledstate)
1820 VncDisplay *vd = opaque;
1821 VncState *client;
1823 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1824 (ledstate & QEMU_NUM_LOCK_LED),
1825 (ledstate & QEMU_SCROLL_LOCK_LED));
1827 if (ledstate == vd->ledstate) {
1828 return;
1831 vd->ledstate = ledstate;
1833 QTAILQ_FOREACH(client, &vd->clients, next) {
1834 vnc_led_state_change(client);
1838 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1840 QKeyCode qcode = qemu_input_key_number_to_qcode(keycode);
1842 /* QEMU console switch */
1843 switch (qcode) {
1844 case Q_KEY_CODE_1 ... Q_KEY_CODE_9: /* '1' to '9' keys */
1845 if (vs->vd->dcl.con == NULL && down &&
1846 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) &&
1847 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {
1848 /* Reset the modifiers sent to the current console */
1849 qkbd_state_lift_all_keys(vs->vd->kbd);
1850 console_select(qcode - Q_KEY_CODE_1);
1851 return;
1853 default:
1854 break;
1857 /* Turn off the lock state sync logic if the client support the led
1858 state extension.
1860 if (down && vs->vd->lock_key_sync &&
1861 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1862 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1863 /* If the numlock state needs to change then simulate an additional
1864 keypress before sending this one. This will happen if the user
1865 toggles numlock away from the VNC window.
1867 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1868 if (!qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1869 trace_vnc_key_sync_numlock(true);
1870 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1872 } else {
1873 if (qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1874 trace_vnc_key_sync_numlock(false);
1875 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1880 if (down && vs->vd->lock_key_sync &&
1881 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1882 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1883 /* If the capslock state needs to change then simulate an additional
1884 keypress before sending this one. This will happen if the user
1885 toggles capslock away from the VNC window.
1887 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1888 bool shift = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_SHIFT);
1889 bool capslock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CAPSLOCK);
1890 if (capslock) {
1891 if (uppercase == shift) {
1892 trace_vnc_key_sync_capslock(false);
1893 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1895 } else {
1896 if (uppercase != shift) {
1897 trace_vnc_key_sync_capslock(true);
1898 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1903 qkbd_state_key_event(vs->vd->kbd, qcode, down);
1904 if (!qemu_console_is_graphic(NULL)) {
1905 bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK);
1906 bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL);
1907 /* QEMU console emulation */
1908 if (down) {
1909 switch (keycode) {
1910 case 0x2a: /* Left Shift */
1911 case 0x36: /* Right Shift */
1912 case 0x1d: /* Left CTRL */
1913 case 0x9d: /* Right CTRL */
1914 case 0x38: /* Left ALT */
1915 case 0xb8: /* Right ALT */
1916 break;
1917 case 0xc8:
1918 kbd_put_keysym(QEMU_KEY_UP);
1919 break;
1920 case 0xd0:
1921 kbd_put_keysym(QEMU_KEY_DOWN);
1922 break;
1923 case 0xcb:
1924 kbd_put_keysym(QEMU_KEY_LEFT);
1925 break;
1926 case 0xcd:
1927 kbd_put_keysym(QEMU_KEY_RIGHT);
1928 break;
1929 case 0xd3:
1930 kbd_put_keysym(QEMU_KEY_DELETE);
1931 break;
1932 case 0xc7:
1933 kbd_put_keysym(QEMU_KEY_HOME);
1934 break;
1935 case 0xcf:
1936 kbd_put_keysym(QEMU_KEY_END);
1937 break;
1938 case 0xc9:
1939 kbd_put_keysym(QEMU_KEY_PAGEUP);
1940 break;
1941 case 0xd1:
1942 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1943 break;
1945 case 0x47:
1946 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1947 break;
1948 case 0x48:
1949 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1950 break;
1951 case 0x49:
1952 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1953 break;
1954 case 0x4b:
1955 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1956 break;
1957 case 0x4c:
1958 kbd_put_keysym('5');
1959 break;
1960 case 0x4d:
1961 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1962 break;
1963 case 0x4f:
1964 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1965 break;
1966 case 0x50:
1967 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1968 break;
1969 case 0x51:
1970 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1971 break;
1972 case 0x52:
1973 kbd_put_keysym('0');
1974 break;
1975 case 0x53:
1976 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1977 break;
1979 case 0xb5:
1980 kbd_put_keysym('/');
1981 break;
1982 case 0x37:
1983 kbd_put_keysym('*');
1984 break;
1985 case 0x4a:
1986 kbd_put_keysym('-');
1987 break;
1988 case 0x4e:
1989 kbd_put_keysym('+');
1990 break;
1991 case 0x9c:
1992 kbd_put_keysym('\n');
1993 break;
1995 default:
1996 if (control) {
1997 kbd_put_keysym(sym & 0x1f);
1998 } else {
1999 kbd_put_keysym(sym);
2001 break;
2007 static const char *code2name(int keycode)
2009 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
2012 static void key_event(VncState *vs, int down, uint32_t sym)
2014 int keycode;
2015 int lsym = sym;
2017 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2018 lsym = lsym - 'A' + 'a';
2021 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
2022 vs->vd->kbd, down) & SCANCODE_KEYMASK;
2023 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2024 do_key_event(vs, down, keycode, sym);
2027 static void ext_key_event(VncState *vs, int down,
2028 uint32_t sym, uint16_t keycode)
2030 /* if the user specifies a keyboard layout, always use it */
2031 if (keyboard_layout) {
2032 key_event(vs, down, sym);
2033 } else {
2034 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2035 do_key_event(vs, down, keycode, sym);
2039 static void framebuffer_update_request(VncState *vs, int incremental,
2040 int x, int y, int w, int h)
2042 if (incremental) {
2043 if (vs->update != VNC_STATE_UPDATE_FORCE) {
2044 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
2046 } else {
2047 vs->update = VNC_STATE_UPDATE_FORCE;
2048 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2049 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
2050 vnc_desktop_resize_ext(vs, 0);
2055 static void send_ext_key_event_ack(VncState *vs)
2057 vnc_lock_output(vs);
2058 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2059 vnc_write_u8(vs, 0);
2060 vnc_write_u16(vs, 1);
2061 vnc_framebuffer_update(vs, 0, 0,
2062 pixman_image_get_width(vs->vd->server),
2063 pixman_image_get_height(vs->vd->server),
2064 VNC_ENCODING_EXT_KEY_EVENT);
2065 vnc_unlock_output(vs);
2066 vnc_flush(vs);
2069 static void send_ext_audio_ack(VncState *vs)
2071 vnc_lock_output(vs);
2072 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2073 vnc_write_u8(vs, 0);
2074 vnc_write_u16(vs, 1);
2075 vnc_framebuffer_update(vs, 0, 0,
2076 pixman_image_get_width(vs->vd->server),
2077 pixman_image_get_height(vs->vd->server),
2078 VNC_ENCODING_AUDIO);
2079 vnc_unlock_output(vs);
2080 vnc_flush(vs);
2083 static void send_xvp_message(VncState *vs, int code)
2085 vnc_lock_output(vs);
2086 vnc_write_u8(vs, VNC_MSG_SERVER_XVP);
2087 vnc_write_u8(vs, 0); /* pad */
2088 vnc_write_u8(vs, 1); /* version */
2089 vnc_write_u8(vs, code);
2090 vnc_unlock_output(vs);
2091 vnc_flush(vs);
2094 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2096 int i;
2097 unsigned int enc = 0;
2099 vs->features = 0;
2100 vs->vnc_encoding = 0;
2101 vs->tight->compression = 9;
2102 vs->tight->quality = -1; /* Lossless by default */
2103 vs->absolute = -1;
2106 * Start from the end because the encodings are sent in order of preference.
2107 * This way the preferred encoding (first encoding defined in the array)
2108 * will be set at the end of the loop.
2110 for (i = n_encodings - 1; i >= 0; i--) {
2111 enc = encodings[i];
2112 switch (enc) {
2113 case VNC_ENCODING_RAW:
2114 vs->vnc_encoding = enc;
2115 break;
2116 case VNC_ENCODING_HEXTILE:
2117 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2118 vs->vnc_encoding = enc;
2119 break;
2120 case VNC_ENCODING_TIGHT:
2121 vs->features |= VNC_FEATURE_TIGHT_MASK;
2122 vs->vnc_encoding = enc;
2123 break;
2124 #ifdef CONFIG_VNC_PNG
2125 case VNC_ENCODING_TIGHT_PNG:
2126 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2127 vs->vnc_encoding = enc;
2128 break;
2129 #endif
2130 case VNC_ENCODING_ZLIB:
2132 * VNC_ENCODING_ZRLE compresses better than VNC_ENCODING_ZLIB.
2133 * So prioritize ZRLE, even if the client hints that it prefers
2134 * ZLIB.
2136 if ((vs->features & VNC_FEATURE_ZRLE_MASK) == 0) {
2137 vs->features |= VNC_FEATURE_ZLIB_MASK;
2138 vs->vnc_encoding = enc;
2140 break;
2141 case VNC_ENCODING_ZRLE:
2142 vs->features |= VNC_FEATURE_ZRLE_MASK;
2143 vs->vnc_encoding = enc;
2144 break;
2145 case VNC_ENCODING_ZYWRLE:
2146 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2147 vs->vnc_encoding = enc;
2148 break;
2149 case VNC_ENCODING_DESKTOPRESIZE:
2150 vs->features |= VNC_FEATURE_RESIZE_MASK;
2151 break;
2152 case VNC_ENCODING_DESKTOP_RESIZE_EXT:
2153 vs->features |= VNC_FEATURE_RESIZE_EXT_MASK;
2154 break;
2155 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2156 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2157 break;
2158 case VNC_ENCODING_RICH_CURSOR:
2159 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2160 break;
2161 case VNC_ENCODING_ALPHA_CURSOR:
2162 vs->features |= VNC_FEATURE_ALPHA_CURSOR_MASK;
2163 break;
2164 case VNC_ENCODING_EXT_KEY_EVENT:
2165 send_ext_key_event_ack(vs);
2166 break;
2167 case VNC_ENCODING_AUDIO:
2168 send_ext_audio_ack(vs);
2169 break;
2170 case VNC_ENCODING_WMVi:
2171 vs->features |= VNC_FEATURE_WMVI_MASK;
2172 break;
2173 case VNC_ENCODING_LED_STATE:
2174 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2175 break;
2176 case VNC_ENCODING_XVP:
2177 if (vs->vd->power_control) {
2178 vs->features |= VNC_FEATURE_XVP;
2179 send_xvp_message(vs, VNC_XVP_CODE_INIT);
2181 break;
2182 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2183 vs->tight->compression = (enc & 0x0F);
2184 break;
2185 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2186 if (vs->vd->lossy) {
2187 vs->tight->quality = (enc & 0x0F);
2189 break;
2190 default:
2191 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2192 break;
2195 vnc_desktop_resize(vs);
2196 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2197 vnc_led_state_change(vs);
2198 vnc_cursor_define(vs);
2201 static void set_pixel_conversion(VncState *vs)
2203 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2205 if (fmt == VNC_SERVER_FB_FORMAT) {
2206 vs->write_pixels = vnc_write_pixels_copy;
2207 vnc_hextile_set_pixel_conversion(vs, 0);
2208 } else {
2209 vs->write_pixels = vnc_write_pixels_generic;
2210 vnc_hextile_set_pixel_conversion(vs, 1);
2214 static void send_color_map(VncState *vs)
2216 int i;
2218 vnc_lock_output(vs);
2219 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2220 vnc_write_u8(vs, 0); /* padding */
2221 vnc_write_u16(vs, 0); /* first color */
2222 vnc_write_u16(vs, 256); /* # of colors */
2224 for (i = 0; i < 256; i++) {
2225 PixelFormat *pf = &vs->client_pf;
2227 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2228 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2229 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2231 vnc_unlock_output(vs);
2234 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2235 int big_endian_flag, int true_color_flag,
2236 int red_max, int green_max, int blue_max,
2237 int red_shift, int green_shift, int blue_shift)
2239 if (!true_color_flag) {
2240 /* Expose a reasonable default 256 color map */
2241 bits_per_pixel = 8;
2242 red_max = 7;
2243 green_max = 7;
2244 blue_max = 3;
2245 red_shift = 0;
2246 green_shift = 3;
2247 blue_shift = 6;
2250 switch (bits_per_pixel) {
2251 case 8:
2252 case 16:
2253 case 32:
2254 break;
2255 default:
2256 vnc_client_error(vs);
2257 return;
2260 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2261 vs->client_pf.rbits = ctpopl(red_max);
2262 vs->client_pf.rshift = red_shift;
2263 vs->client_pf.rmask = red_max << red_shift;
2264 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2265 vs->client_pf.gbits = ctpopl(green_max);
2266 vs->client_pf.gshift = green_shift;
2267 vs->client_pf.gmask = green_max << green_shift;
2268 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2269 vs->client_pf.bbits = ctpopl(blue_max);
2270 vs->client_pf.bshift = blue_shift;
2271 vs->client_pf.bmask = blue_max << blue_shift;
2272 vs->client_pf.bits_per_pixel = bits_per_pixel;
2273 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2274 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2275 vs->client_be = big_endian_flag;
2277 if (!true_color_flag) {
2278 send_color_map(vs);
2281 set_pixel_conversion(vs);
2283 graphic_hw_invalidate(vs->vd->dcl.con);
2284 graphic_hw_update(vs->vd->dcl.con);
2287 static void pixel_format_message (VncState *vs) {
2288 char pad[3] = { 0, 0, 0 };
2290 vs->client_pf = qemu_default_pixelformat(32);
2292 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2293 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2295 #ifdef HOST_WORDS_BIGENDIAN
2296 vnc_write_u8(vs, 1); /* big-endian-flag */
2297 #else
2298 vnc_write_u8(vs, 0); /* big-endian-flag */
2299 #endif
2300 vnc_write_u8(vs, 1); /* true-color-flag */
2301 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2302 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2303 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2304 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2305 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2306 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2307 vnc_write(vs, pad, 3); /* padding */
2309 vnc_hextile_set_pixel_conversion(vs, 0);
2310 vs->write_pixels = vnc_write_pixels_copy;
2313 static void vnc_colordepth(VncState *vs)
2315 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2316 /* Sending a WMVi message to notify the client*/
2317 vnc_lock_output(vs);
2318 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2319 vnc_write_u8(vs, 0);
2320 vnc_write_u16(vs, 1); /* number of rects */
2321 vnc_framebuffer_update(vs, 0, 0,
2322 pixman_image_get_width(vs->vd->server),
2323 pixman_image_get_height(vs->vd->server),
2324 VNC_ENCODING_WMVi);
2325 pixel_format_message(vs);
2326 vnc_unlock_output(vs);
2327 vnc_flush(vs);
2328 } else {
2329 set_pixel_conversion(vs);
2333 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2335 int i;
2336 uint16_t limit;
2337 uint32_t freq;
2338 VncDisplay *vd = vs->vd;
2340 if (data[0] > 3) {
2341 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2344 switch (data[0]) {
2345 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2346 if (len == 1)
2347 return 20;
2349 set_pixel_format(vs, read_u8(data, 4),
2350 read_u8(data, 6), read_u8(data, 7),
2351 read_u16(data, 8), read_u16(data, 10),
2352 read_u16(data, 12), read_u8(data, 14),
2353 read_u8(data, 15), read_u8(data, 16));
2354 break;
2355 case VNC_MSG_CLIENT_SET_ENCODINGS:
2356 if (len == 1)
2357 return 4;
2359 if (len == 4) {
2360 limit = read_u16(data, 2);
2361 if (limit > 0)
2362 return 4 + (limit * 4);
2363 } else
2364 limit = read_u16(data, 2);
2366 for (i = 0; i < limit; i++) {
2367 int32_t val = read_s32(data, 4 + (i * 4));
2368 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2371 set_encodings(vs, (int32_t *)(data + 4), limit);
2372 break;
2373 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2374 if (len == 1)
2375 return 10;
2377 framebuffer_update_request(vs,
2378 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2379 read_u16(data, 6), read_u16(data, 8));
2380 break;
2381 case VNC_MSG_CLIENT_KEY_EVENT:
2382 if (len == 1)
2383 return 8;
2385 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2386 break;
2387 case VNC_MSG_CLIENT_POINTER_EVENT:
2388 if (len == 1)
2389 return 6;
2391 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2392 break;
2393 case VNC_MSG_CLIENT_CUT_TEXT:
2394 if (len == 1) {
2395 return 8;
2397 if (len == 8) {
2398 uint32_t dlen = read_u32(data, 4);
2399 if (dlen > (1 << 20)) {
2400 error_report("vnc: client_cut_text msg payload has %u bytes"
2401 " which exceeds our limit of 1MB.", dlen);
2402 vnc_client_error(vs);
2403 break;
2405 if (dlen > 0) {
2406 return 8 + dlen;
2410 client_cut_text(vs, read_u32(data, 4), data + 8);
2411 break;
2412 case VNC_MSG_CLIENT_XVP:
2413 if (!(vs->features & VNC_FEATURE_XVP)) {
2414 error_report("vnc: xvp client message while disabled");
2415 vnc_client_error(vs);
2416 break;
2418 if (len == 1) {
2419 return 4;
2421 if (len == 4) {
2422 uint8_t version = read_u8(data, 2);
2423 uint8_t action = read_u8(data, 3);
2425 if (version != 1) {
2426 error_report("vnc: xvp client message version %d != 1",
2427 version);
2428 vnc_client_error(vs);
2429 break;
2432 switch (action) {
2433 case VNC_XVP_ACTION_SHUTDOWN:
2434 qemu_system_powerdown_request();
2435 break;
2436 case VNC_XVP_ACTION_REBOOT:
2437 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2438 break;
2439 case VNC_XVP_ACTION_RESET:
2440 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
2441 break;
2442 default:
2443 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2444 break;
2447 break;
2448 case VNC_MSG_CLIENT_QEMU:
2449 if (len == 1)
2450 return 2;
2452 switch (read_u8(data, 1)) {
2453 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2454 if (len == 2)
2455 return 12;
2457 ext_key_event(vs, read_u16(data, 2),
2458 read_u32(data, 4), read_u32(data, 8));
2459 break;
2460 case VNC_MSG_CLIENT_QEMU_AUDIO:
2461 if (len == 2)
2462 return 4;
2464 switch (read_u16 (data, 2)) {
2465 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2466 audio_add(vs);
2467 break;
2468 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2469 audio_del(vs);
2470 break;
2471 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2472 if (len == 4)
2473 return 10;
2474 switch (read_u8(data, 4)) {
2475 case 0: vs->as.fmt = AUDIO_FORMAT_U8; break;
2476 case 1: vs->as.fmt = AUDIO_FORMAT_S8; break;
2477 case 2: vs->as.fmt = AUDIO_FORMAT_U16; break;
2478 case 3: vs->as.fmt = AUDIO_FORMAT_S16; break;
2479 case 4: vs->as.fmt = AUDIO_FORMAT_U32; break;
2480 case 5: vs->as.fmt = AUDIO_FORMAT_S32; break;
2481 default:
2482 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2483 vnc_client_error(vs);
2484 break;
2486 vs->as.nchannels = read_u8(data, 5);
2487 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2488 VNC_DEBUG("Invalid audio channel count %d\n",
2489 read_u8(data, 5));
2490 vnc_client_error(vs);
2491 break;
2493 freq = read_u32(data, 6);
2494 /* No official limit for protocol, but 48khz is a sensible
2495 * upper bound for trustworthy clients, and this limit
2496 * protects calculations involving 'vs->as.freq' later.
2498 if (freq > 48000) {
2499 VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
2500 vnc_client_error(vs);
2501 break;
2503 vs->as.freq = freq;
2504 break;
2505 default:
2506 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2507 vnc_client_error(vs);
2508 break;
2510 break;
2512 default:
2513 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2514 vnc_client_error(vs);
2515 break;
2517 break;
2518 case VNC_MSG_CLIENT_SET_DESKTOP_SIZE:
2520 size_t size;
2521 uint8_t screens;
2523 if (len < 8) {
2524 return 8;
2527 screens = read_u8(data, 6);
2528 size = 8 + screens * 16;
2529 if (len < size) {
2530 return size;
2533 if (dpy_ui_info_supported(vs->vd->dcl.con)) {
2534 QemuUIInfo info;
2535 memset(&info, 0, sizeof(info));
2536 info.width = read_u16(data, 2);
2537 info.height = read_u16(data, 4);
2538 dpy_set_ui_info(vs->vd->dcl.con, &info);
2539 vnc_desktop_resize_ext(vs, 4 /* Request forwarded */);
2540 } else {
2541 vnc_desktop_resize_ext(vs, 3 /* Invalid screen layout */);
2544 break;
2546 default:
2547 VNC_DEBUG("Msg: %d\n", data[0]);
2548 vnc_client_error(vs);
2549 break;
2552 vnc_update_throttle_offset(vs);
2553 vnc_read_when(vs, protocol_client_msg, 1);
2554 return 0;
2557 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2559 char buf[1024];
2560 VncShareMode mode;
2561 int size;
2563 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2564 switch (vs->vd->share_policy) {
2565 case VNC_SHARE_POLICY_IGNORE:
2567 * Ignore the shared flag. Nothing to do here.
2569 * Doesn't conform to the rfb spec but is traditional qemu
2570 * behavior, thus left here as option for compatibility
2571 * reasons.
2573 break;
2574 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2576 * Policy: Allow clients ask for exclusive access.
2578 * Implementation: When a client asks for exclusive access,
2579 * disconnect all others. Shared connects are allowed as long
2580 * as no exclusive connection exists.
2582 * This is how the rfb spec suggests to handle the shared flag.
2584 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2585 VncState *client;
2586 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2587 if (vs == client) {
2588 continue;
2590 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2591 client->share_mode != VNC_SHARE_MODE_SHARED) {
2592 continue;
2594 vnc_disconnect_start(client);
2597 if (mode == VNC_SHARE_MODE_SHARED) {
2598 if (vs->vd->num_exclusive > 0) {
2599 vnc_disconnect_start(vs);
2600 return 0;
2603 break;
2604 case VNC_SHARE_POLICY_FORCE_SHARED:
2606 * Policy: Shared connects only.
2607 * Implementation: Disallow clients asking for exclusive access.
2609 * Useful for shared desktop sessions where you don't want
2610 * someone forgetting to say -shared when running the vnc
2611 * client disconnect everybody else.
2613 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2614 vnc_disconnect_start(vs);
2615 return 0;
2617 break;
2619 vnc_set_share_mode(vs, mode);
2621 if (vs->vd->num_shared > vs->vd->connections_limit) {
2622 vnc_disconnect_start(vs);
2623 return 0;
2626 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
2627 pixman_image_get_width(vs->vd->server) >= 0);
2628 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
2629 pixman_image_get_height(vs->vd->server) >= 0);
2630 vs->client_width = pixman_image_get_width(vs->vd->server);
2631 vs->client_height = pixman_image_get_height(vs->vd->server);
2632 vnc_write_u16(vs, vs->client_width);
2633 vnc_write_u16(vs, vs->client_height);
2635 pixel_format_message(vs);
2637 if (qemu_name) {
2638 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2639 if (size > sizeof(buf)) {
2640 size = sizeof(buf);
2642 } else {
2643 size = snprintf(buf, sizeof(buf), "QEMU");
2646 vnc_write_u32(vs, size);
2647 vnc_write(vs, buf, size);
2648 vnc_flush(vs);
2650 vnc_client_cache_auth(vs);
2651 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2653 vnc_read_when(vs, protocol_client_msg, 1);
2655 return 0;
2658 void start_client_init(VncState *vs)
2660 vnc_read_when(vs, protocol_client_init, 1);
2663 static void authentication_failed(VncState *vs)
2665 vnc_write_u32(vs, 1); /* Reject auth */
2666 if (vs->minor >= 8) {
2667 static const char err[] = "Authentication failed";
2668 vnc_write_u32(vs, sizeof(err));
2669 vnc_write(vs, err, sizeof(err));
2671 vnc_flush(vs);
2672 vnc_client_error(vs);
2675 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2677 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2678 size_t i, pwlen;
2679 unsigned char key[8];
2680 time_t now = time(NULL);
2681 QCryptoCipher *cipher = NULL;
2682 Error *err = NULL;
2684 if (!vs->vd->password) {
2685 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2686 goto reject;
2688 if (vs->vd->expires < now) {
2689 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2690 goto reject;
2693 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2695 /* Calculate the expected challenge response */
2696 pwlen = strlen(vs->vd->password);
2697 for (i=0; i<sizeof(key); i++)
2698 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2700 cipher = qcrypto_cipher_new(
2701 QCRYPTO_CIPHER_ALG_DES_RFB,
2702 QCRYPTO_CIPHER_MODE_ECB,
2703 key, G_N_ELEMENTS(key),
2704 &err);
2705 if (!cipher) {
2706 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2707 error_get_pretty(err));
2708 error_free(err);
2709 goto reject;
2712 if (qcrypto_cipher_encrypt(cipher,
2713 vs->challenge,
2714 response,
2715 VNC_AUTH_CHALLENGE_SIZE,
2716 &err) < 0) {
2717 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2718 error_get_pretty(err));
2719 error_free(err);
2720 goto reject;
2723 /* Compare expected vs actual challenge response */
2724 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2725 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2726 goto reject;
2727 } else {
2728 trace_vnc_auth_pass(vs, vs->auth);
2729 vnc_write_u32(vs, 0); /* Accept auth */
2730 vnc_flush(vs);
2732 start_client_init(vs);
2735 qcrypto_cipher_free(cipher);
2736 return 0;
2738 reject:
2739 authentication_failed(vs);
2740 qcrypto_cipher_free(cipher);
2741 return 0;
2744 void start_auth_vnc(VncState *vs)
2746 Error *err = NULL;
2748 if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) {
2749 trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
2750 error_get_pretty(err));
2751 error_free(err);
2752 authentication_failed(vs);
2753 return;
2756 /* Send client a 'random' challenge */
2757 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2758 vnc_flush(vs);
2760 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2764 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2766 /* We only advertise 1 auth scheme at a time, so client
2767 * must pick the one we sent. Verify this */
2768 if (data[0] != vs->auth) { /* Reject auth */
2769 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2770 authentication_failed(vs);
2771 } else { /* Accept requested auth */
2772 trace_vnc_auth_start(vs, vs->auth);
2773 switch (vs->auth) {
2774 case VNC_AUTH_NONE:
2775 if (vs->minor >= 8) {
2776 vnc_write_u32(vs, 0); /* Accept auth completion */
2777 vnc_flush(vs);
2779 trace_vnc_auth_pass(vs, vs->auth);
2780 start_client_init(vs);
2781 break;
2783 case VNC_AUTH_VNC:
2784 start_auth_vnc(vs);
2785 break;
2787 case VNC_AUTH_VENCRYPT:
2788 start_auth_vencrypt(vs);
2789 break;
2791 #ifdef CONFIG_VNC_SASL
2792 case VNC_AUTH_SASL:
2793 start_auth_sasl(vs);
2794 break;
2795 #endif /* CONFIG_VNC_SASL */
2797 default: /* Should not be possible, but just in case */
2798 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2799 authentication_failed(vs);
2802 return 0;
2805 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2807 char local[13];
2809 memcpy(local, version, 12);
2810 local[12] = 0;
2812 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2813 VNC_DEBUG("Malformed protocol version %s\n", local);
2814 vnc_client_error(vs);
2815 return 0;
2817 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2818 if (vs->major != 3 ||
2819 (vs->minor != 3 &&
2820 vs->minor != 4 &&
2821 vs->minor != 5 &&
2822 vs->minor != 7 &&
2823 vs->minor != 8)) {
2824 VNC_DEBUG("Unsupported client version\n");
2825 vnc_write_u32(vs, VNC_AUTH_INVALID);
2826 vnc_flush(vs);
2827 vnc_client_error(vs);
2828 return 0;
2830 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2831 * as equivalent to v3.3 by servers
2833 if (vs->minor == 4 || vs->minor == 5)
2834 vs->minor = 3;
2836 if (vs->minor == 3) {
2837 trace_vnc_auth_start(vs, vs->auth);
2838 if (vs->auth == VNC_AUTH_NONE) {
2839 vnc_write_u32(vs, vs->auth);
2840 vnc_flush(vs);
2841 trace_vnc_auth_pass(vs, vs->auth);
2842 start_client_init(vs);
2843 } else if (vs->auth == VNC_AUTH_VNC) {
2844 VNC_DEBUG("Tell client VNC auth\n");
2845 vnc_write_u32(vs, vs->auth);
2846 vnc_flush(vs);
2847 start_auth_vnc(vs);
2848 } else {
2849 trace_vnc_auth_fail(vs, vs->auth,
2850 "Unsupported auth method for v3.3", "");
2851 vnc_write_u32(vs, VNC_AUTH_INVALID);
2852 vnc_flush(vs);
2853 vnc_client_error(vs);
2855 } else {
2856 vnc_write_u8(vs, 1); /* num auth */
2857 vnc_write_u8(vs, vs->auth);
2858 vnc_read_when(vs, protocol_client_auth, 1);
2859 vnc_flush(vs);
2862 return 0;
2865 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2867 struct VncSurface *vs = &vd->guest;
2869 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2872 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2874 int i, j;
2876 w = (x + w) / VNC_STAT_RECT;
2877 h = (y + h) / VNC_STAT_RECT;
2878 x /= VNC_STAT_RECT;
2879 y /= VNC_STAT_RECT;
2881 for (j = y; j <= h; j++) {
2882 for (i = x; i <= w; i++) {
2883 vs->lossy_rect[j][i] = 1;
2888 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2890 VncState *vs;
2891 int sty = y / VNC_STAT_RECT;
2892 int stx = x / VNC_STAT_RECT;
2893 int has_dirty = 0;
2895 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2896 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2898 QTAILQ_FOREACH(vs, &vd->clients, next) {
2899 int j;
2901 /* kernel send buffers are full -> refresh later */
2902 if (vs->output.offset) {
2903 continue;
2906 if (!vs->lossy_rect[sty][stx]) {
2907 continue;
2910 vs->lossy_rect[sty][stx] = 0;
2911 for (j = 0; j < VNC_STAT_RECT; ++j) {
2912 bitmap_set(vs->dirty[y + j],
2913 x / VNC_DIRTY_PIXELS_PER_BIT,
2914 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2916 has_dirty++;
2919 return has_dirty;
2922 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2924 int width = MIN(pixman_image_get_width(vd->guest.fb),
2925 pixman_image_get_width(vd->server));
2926 int height = MIN(pixman_image_get_height(vd->guest.fb),
2927 pixman_image_get_height(vd->server));
2928 int x, y;
2929 struct timeval res;
2930 int has_dirty = 0;
2932 for (y = 0; y < height; y += VNC_STAT_RECT) {
2933 for (x = 0; x < width; x += VNC_STAT_RECT) {
2934 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2936 rect->updated = false;
2940 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2942 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2943 return has_dirty;
2945 vd->guest.last_freq_check = *tv;
2947 for (y = 0; y < height; y += VNC_STAT_RECT) {
2948 for (x = 0; x < width; x += VNC_STAT_RECT) {
2949 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2950 int count = ARRAY_SIZE(rect->times);
2951 struct timeval min, max;
2953 if (!timerisset(&rect->times[count - 1])) {
2954 continue ;
2957 max = rect->times[(rect->idx + count - 1) % count];
2958 qemu_timersub(tv, &max, &res);
2960 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2961 rect->freq = 0;
2962 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2963 memset(rect->times, 0, sizeof (rect->times));
2964 continue ;
2967 min = rect->times[rect->idx];
2968 max = rect->times[(rect->idx + count - 1) % count];
2969 qemu_timersub(&max, &min, &res);
2971 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2972 rect->freq /= count;
2973 rect->freq = 1. / rect->freq;
2976 return has_dirty;
2979 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2981 int i, j;
2982 double total = 0;
2983 int num = 0;
2985 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2986 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2988 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2989 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2990 total += vnc_stat_rect(vs->vd, i, j)->freq;
2991 num++;
2995 if (num) {
2996 return total / num;
2997 } else {
2998 return 0;
3002 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
3004 VncRectStat *rect;
3006 rect = vnc_stat_rect(vd, x, y);
3007 if (rect->updated) {
3008 return ;
3010 rect->times[rect->idx] = *tv;
3011 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
3012 rect->updated = true;
3015 static int vnc_refresh_server_surface(VncDisplay *vd)
3017 int width = MIN(pixman_image_get_width(vd->guest.fb),
3018 pixman_image_get_width(vd->server));
3019 int height = MIN(pixman_image_get_height(vd->guest.fb),
3020 pixman_image_get_height(vd->server));
3021 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
3022 uint8_t *guest_row0 = NULL, *server_row0;
3023 VncState *vs;
3024 int has_dirty = 0;
3025 pixman_image_t *tmpbuf = NULL;
3027 struct timeval tv = { 0, 0 };
3029 if (!vd->non_adaptive) {
3030 gettimeofday(&tv, NULL);
3031 has_dirty = vnc_update_stats(vd, &tv);
3035 * Walk through the guest dirty map.
3036 * Check and copy modified bits from guest to server surface.
3037 * Update server dirty map.
3039 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
3040 server_stride = guest_stride = guest_ll =
3041 pixman_image_get_stride(vd->server);
3042 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
3043 server_stride);
3044 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3045 int width = pixman_image_get_width(vd->server);
3046 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
3047 } else {
3048 int guest_bpp =
3049 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
3050 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
3051 guest_stride = pixman_image_get_stride(vd->guest.fb);
3052 guest_ll = pixman_image_get_width(vd->guest.fb)
3053 * DIV_ROUND_UP(guest_bpp, 8);
3055 line_bytes = MIN(server_stride, guest_ll);
3057 for (;;) {
3058 int x;
3059 uint8_t *guest_ptr, *server_ptr;
3060 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3061 height * VNC_DIRTY_BPL(&vd->guest),
3062 y * VNC_DIRTY_BPL(&vd->guest));
3063 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3064 /* no more dirty bits */
3065 break;
3067 y = offset / VNC_DIRTY_BPL(&vd->guest);
3068 x = offset % VNC_DIRTY_BPL(&vd->guest);
3070 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
3072 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3073 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
3074 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
3075 } else {
3076 guest_ptr = guest_row0 + y * guest_stride;
3078 guest_ptr += x * cmp_bytes;
3080 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
3081 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
3082 int _cmp_bytes = cmp_bytes;
3083 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
3084 continue;
3086 if ((x + 1) * cmp_bytes > line_bytes) {
3087 _cmp_bytes = line_bytes - x * cmp_bytes;
3089 assert(_cmp_bytes >= 0);
3090 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
3091 continue;
3093 memcpy(server_ptr, guest_ptr, _cmp_bytes);
3094 if (!vd->non_adaptive) {
3095 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
3096 y, &tv);
3098 QTAILQ_FOREACH(vs, &vd->clients, next) {
3099 set_bit(x, vs->dirty[y]);
3101 has_dirty++;
3104 y++;
3106 qemu_pixman_image_unref(tmpbuf);
3107 return has_dirty;
3110 static void vnc_refresh(DisplayChangeListener *dcl)
3112 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
3113 VncState *vs, *vn;
3114 int has_dirty, rects = 0;
3116 if (QTAILQ_EMPTY(&vd->clients)) {
3117 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
3118 return;
3121 graphic_hw_update(vd->dcl.con);
3123 if (vnc_trylock_display(vd)) {
3124 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3125 return;
3128 has_dirty = vnc_refresh_server_surface(vd);
3129 vnc_unlock_display(vd);
3131 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
3132 rects += vnc_update_client(vs, has_dirty);
3133 /* vs might be free()ed here */
3136 if (has_dirty && rects) {
3137 vd->dcl.update_interval /= 2;
3138 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3139 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3141 } else {
3142 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3143 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3144 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3149 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
3150 bool skipauth, bool websocket)
3152 VncState *vs = g_new0(VncState, 1);
3153 bool first_client = QTAILQ_EMPTY(&vd->clients);
3154 int i;
3156 trace_vnc_client_connect(vs, sioc);
3157 vs->zrle = g_new0(VncZrle, 1);
3158 vs->tight = g_new0(VncTight, 1);
3159 vs->magic = VNC_MAGIC;
3160 vs->sioc = sioc;
3161 object_ref(OBJECT(vs->sioc));
3162 vs->ioc = QIO_CHANNEL(sioc);
3163 object_ref(OBJECT(vs->ioc));
3164 vs->vd = vd;
3166 buffer_init(&vs->input, "vnc-input/%p", sioc);
3167 buffer_init(&vs->output, "vnc-output/%p", sioc);
3168 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
3170 buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc);
3171 buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc);
3172 buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc);
3173 #ifdef CONFIG_VNC_JPEG
3174 buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc);
3175 #endif
3176 #ifdef CONFIG_VNC_PNG
3177 buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc);
3178 #endif
3179 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3180 buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc);
3181 buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc);
3182 buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc);
3184 if (skipauth) {
3185 vs->auth = VNC_AUTH_NONE;
3186 vs->subauth = VNC_AUTH_INVALID;
3187 } else {
3188 if (websocket) {
3189 vs->auth = vd->ws_auth;
3190 vs->subauth = VNC_AUTH_INVALID;
3191 } else {
3192 vs->auth = vd->auth;
3193 vs->subauth = vd->subauth;
3196 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3197 sioc, websocket, vs->auth, vs->subauth);
3199 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3200 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3201 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3204 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3205 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3206 qio_channel_set_blocking(vs->ioc, false, NULL);
3207 if (vs->ioc_tag) {
3208 g_source_remove(vs->ioc_tag);
3210 if (websocket) {
3211 vs->websocket = 1;
3212 if (vd->tlscreds) {
3213 vs->ioc_tag = qio_channel_add_watch(
3214 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3215 vncws_tls_handshake_io, vs, NULL);
3216 } else {
3217 vs->ioc_tag = qio_channel_add_watch(
3218 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3219 vncws_handshake_io, vs, NULL);
3221 } else {
3222 vs->ioc_tag = qio_channel_add_watch(
3223 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3224 vnc_client_io, vs, NULL);
3227 vnc_client_cache_addr(vs);
3228 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3229 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3231 vs->last_x = -1;
3232 vs->last_y = -1;
3234 vs->as.freq = 44100;
3235 vs->as.nchannels = 2;
3236 vs->as.fmt = AUDIO_FORMAT_S16;
3237 vs->as.endianness = 0;
3239 qemu_mutex_init(&vs->output_mutex);
3240 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3242 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3243 if (first_client) {
3244 vnc_update_server_surface(vd);
3247 graphic_hw_update(vd->dcl.con);
3249 if (!vs->websocket) {
3250 vnc_start_protocol(vs);
3253 if (vd->num_connecting > vd->connections_limit) {
3254 QTAILQ_FOREACH(vs, &vd->clients, next) {
3255 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3256 vnc_disconnect_start(vs);
3257 return;
3263 void vnc_start_protocol(VncState *vs)
3265 vnc_write(vs, "RFB 003.008\n", 12);
3266 vnc_flush(vs);
3267 vnc_read_when(vs, protocol_version, 12);
3269 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3270 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3273 static void vnc_listen_io(QIONetListener *listener,
3274 QIOChannelSocket *cioc,
3275 void *opaque)
3277 VncDisplay *vd = opaque;
3278 bool isWebsock = listener == vd->wslistener;
3280 qio_channel_set_name(QIO_CHANNEL(cioc),
3281 isWebsock ? "vnc-ws-server" : "vnc-server");
3282 qio_channel_set_delay(QIO_CHANNEL(cioc), false);
3283 vnc_connect(vd, cioc, false, isWebsock);
3286 static const DisplayChangeListenerOps dcl_ops = {
3287 .dpy_name = "vnc",
3288 .dpy_refresh = vnc_refresh,
3289 .dpy_gfx_update = vnc_dpy_update,
3290 .dpy_gfx_switch = vnc_dpy_switch,
3291 .dpy_gfx_check_format = qemu_pixman_check_format,
3292 .dpy_mouse_set = vnc_mouse_set,
3293 .dpy_cursor_define = vnc_dpy_cursor_define,
3296 void vnc_display_init(const char *id, Error **errp)
3298 VncDisplay *vd;
3300 if (vnc_display_find(id) != NULL) {
3301 return;
3303 vd = g_malloc0(sizeof(*vd));
3305 vd->id = strdup(id);
3306 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3308 QTAILQ_INIT(&vd->clients);
3309 vd->expires = TIME_MAX;
3311 if (keyboard_layout) {
3312 trace_vnc_key_map_init(keyboard_layout);
3313 vd->kbd_layout = init_keyboard_layout(name2keysym,
3314 keyboard_layout, errp);
3315 } else {
3316 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
3319 if (!vd->kbd_layout) {
3320 return;
3323 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3324 vd->connections_limit = 32;
3326 qemu_mutex_init(&vd->mutex);
3327 vnc_start_worker_thread();
3329 vd->dcl.ops = &dcl_ops;
3330 register_displaychangelistener(&vd->dcl);
3331 vd->kbd = qkbd_state_init(vd->dcl.con);
3335 static void vnc_display_close(VncDisplay *vd)
3337 if (!vd) {
3338 return;
3340 vd->is_unix = false;
3342 if (vd->listener) {
3343 qio_net_listener_disconnect(vd->listener);
3344 object_unref(OBJECT(vd->listener));
3346 vd->listener = NULL;
3348 if (vd->wslistener) {
3349 qio_net_listener_disconnect(vd->wslistener);
3350 object_unref(OBJECT(vd->wslistener));
3352 vd->wslistener = NULL;
3354 vd->auth = VNC_AUTH_INVALID;
3355 vd->subauth = VNC_AUTH_INVALID;
3356 if (vd->tlscreds) {
3357 object_unref(OBJECT(vd->tlscreds));
3358 vd->tlscreds = NULL;
3360 if (vd->tlsauthz) {
3361 object_unparent(OBJECT(vd->tlsauthz));
3362 vd->tlsauthz = NULL;
3364 g_free(vd->tlsauthzid);
3365 vd->tlsauthzid = NULL;
3366 if (vd->lock_key_sync) {
3367 qemu_remove_led_event_handler(vd->led);
3368 vd->led = NULL;
3370 #ifdef CONFIG_VNC_SASL
3371 if (vd->sasl.authz) {
3372 object_unparent(OBJECT(vd->sasl.authz));
3373 vd->sasl.authz = NULL;
3375 g_free(vd->sasl.authzid);
3376 vd->sasl.authzid = NULL;
3377 #endif
3380 int vnc_display_password(const char *id, const char *password)
3382 VncDisplay *vd = vnc_display_find(id);
3384 if (!vd) {
3385 return -EINVAL;
3387 if (vd->auth == VNC_AUTH_NONE) {
3388 error_printf_unless_qmp("If you want use passwords please enable "
3389 "password auth using '-vnc ${dpy},password'.\n");
3390 return -EINVAL;
3393 g_free(vd->password);
3394 vd->password = g_strdup(password);
3396 return 0;
3399 int vnc_display_pw_expire(const char *id, time_t expires)
3401 VncDisplay *vd = vnc_display_find(id);
3403 if (!vd) {
3404 return -EINVAL;
3407 vd->expires = expires;
3408 return 0;
3411 static void vnc_display_print_local_addr(VncDisplay *vd)
3413 SocketAddress *addr;
3415 if (!vd->listener || !vd->listener->nsioc) {
3416 return;
3419 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], NULL);
3420 if (!addr) {
3421 return;
3424 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3425 qapi_free_SocketAddress(addr);
3426 return;
3428 error_printf_unless_qmp("VNC server running on %s:%s\n",
3429 addr->u.inet.host,
3430 addr->u.inet.port);
3431 qapi_free_SocketAddress(addr);
3434 static QemuOptsList qemu_vnc_opts = {
3435 .name = "vnc",
3436 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3437 .implied_opt_name = "vnc",
3438 .desc = {
3440 .name = "vnc",
3441 .type = QEMU_OPT_STRING,
3443 .name = "websocket",
3444 .type = QEMU_OPT_STRING,
3446 .name = "tls-creds",
3447 .type = QEMU_OPT_STRING,
3449 .name = "share",
3450 .type = QEMU_OPT_STRING,
3452 .name = "display",
3453 .type = QEMU_OPT_STRING,
3455 .name = "head",
3456 .type = QEMU_OPT_NUMBER,
3458 .name = "connections",
3459 .type = QEMU_OPT_NUMBER,
3461 .name = "to",
3462 .type = QEMU_OPT_NUMBER,
3464 .name = "ipv4",
3465 .type = QEMU_OPT_BOOL,
3467 .name = "ipv6",
3468 .type = QEMU_OPT_BOOL,
3470 .name = "password",
3471 .type = QEMU_OPT_BOOL,
3473 .name = "reverse",
3474 .type = QEMU_OPT_BOOL,
3476 .name = "lock-key-sync",
3477 .type = QEMU_OPT_BOOL,
3479 .name = "key-delay-ms",
3480 .type = QEMU_OPT_NUMBER,
3482 .name = "sasl",
3483 .type = QEMU_OPT_BOOL,
3485 .name = "acl",
3486 .type = QEMU_OPT_BOOL,
3488 .name = "tls-authz",
3489 .type = QEMU_OPT_STRING,
3491 .name = "sasl-authz",
3492 .type = QEMU_OPT_STRING,
3494 .name = "lossy",
3495 .type = QEMU_OPT_BOOL,
3497 .name = "non-adaptive",
3498 .type = QEMU_OPT_BOOL,
3500 .name = "audiodev",
3501 .type = QEMU_OPT_STRING,
3503 .name = "power-control",
3504 .type = QEMU_OPT_BOOL,
3506 { /* end of list */ }
3511 static int
3512 vnc_display_setup_auth(int *auth,
3513 int *subauth,
3514 QCryptoTLSCreds *tlscreds,
3515 bool password,
3516 bool sasl,
3517 bool websocket,
3518 Error **errp)
3521 * We have a choice of 3 authentication options
3523 * 1. none
3524 * 2. vnc
3525 * 3. sasl
3527 * The channel can be run in 2 modes
3529 * 1. clear
3530 * 2. tls
3532 * And TLS can use 2 types of credentials
3534 * 1. anon
3535 * 2. x509
3537 * We thus have 9 possible logical combinations
3539 * 1. clear + none
3540 * 2. clear + vnc
3541 * 3. clear + sasl
3542 * 4. tls + anon + none
3543 * 5. tls + anon + vnc
3544 * 6. tls + anon + sasl
3545 * 7. tls + x509 + none
3546 * 8. tls + x509 + vnc
3547 * 9. tls + x509 + sasl
3549 * These need to be mapped into the VNC auth schemes
3550 * in an appropriate manner. In regular VNC, all the
3551 * TLS options get mapped into VNC_AUTH_VENCRYPT
3552 * sub-auth types.
3554 * In websockets, the https:// protocol already provides
3555 * TLS support, so there is no need to make use of the
3556 * VeNCrypt extension. Furthermore, websockets browser
3557 * clients could not use VeNCrypt even if they wanted to,
3558 * as they cannot control when the TLS handshake takes
3559 * place. Thus there is no option but to rely on https://,
3560 * meaning combinations 4->6 and 7->9 will be mapped to
3561 * VNC auth schemes in the same way as combos 1->3.
3563 * Regardless of fact that we have a different mapping to
3564 * VNC auth mechs for plain VNC vs websockets VNC, the end
3565 * result has the same security characteristics.
3567 if (websocket || !tlscreds) {
3568 if (password) {
3569 VNC_DEBUG("Initializing VNC server with password auth\n");
3570 *auth = VNC_AUTH_VNC;
3571 } else if (sasl) {
3572 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3573 *auth = VNC_AUTH_SASL;
3574 } else {
3575 VNC_DEBUG("Initializing VNC server with no auth\n");
3576 *auth = VNC_AUTH_NONE;
3578 *subauth = VNC_AUTH_INVALID;
3579 } else {
3580 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3581 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3582 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3583 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3585 if (!is_x509 && !is_anon) {
3586 error_setg(errp,
3587 "Unsupported TLS cred type %s",
3588 object_get_typename(OBJECT(tlscreds)));
3589 return -1;
3591 *auth = VNC_AUTH_VENCRYPT;
3592 if (password) {
3593 if (is_x509) {
3594 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3595 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3596 } else {
3597 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3598 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3601 } else if (sasl) {
3602 if (is_x509) {
3603 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3604 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3605 } else {
3606 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3607 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3609 } else {
3610 if (is_x509) {
3611 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3612 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3613 } else {
3614 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3615 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3619 return 0;
3623 static int vnc_display_get_address(const char *addrstr,
3624 bool websocket,
3625 bool reverse,
3626 int displaynum,
3627 int to,
3628 bool has_ipv4,
3629 bool has_ipv6,
3630 bool ipv4,
3631 bool ipv6,
3632 SocketAddress **retaddr,
3633 Error **errp)
3635 int ret = -1;
3636 SocketAddress *addr = NULL;
3638 addr = g_new0(SocketAddress, 1);
3640 if (strncmp(addrstr, "unix:", 5) == 0) {
3641 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3642 addr->u.q_unix.path = g_strdup(addrstr + 5);
3644 if (websocket) {
3645 error_setg(errp, "UNIX sockets not supported with websock");
3646 goto cleanup;
3649 if (to) {
3650 error_setg(errp, "Port range not support with UNIX socket");
3651 goto cleanup;
3653 ret = 0;
3654 } else {
3655 const char *port;
3656 size_t hostlen;
3657 unsigned long long baseport = 0;
3658 InetSocketAddress *inet;
3660 port = strrchr(addrstr, ':');
3661 if (!port) {
3662 if (websocket) {
3663 hostlen = 0;
3664 port = addrstr;
3665 } else {
3666 error_setg(errp, "no vnc port specified");
3667 goto cleanup;
3669 } else {
3670 hostlen = port - addrstr;
3671 port++;
3672 if (*port == '\0') {
3673 error_setg(errp, "vnc port cannot be empty");
3674 goto cleanup;
3678 addr->type = SOCKET_ADDRESS_TYPE_INET;
3679 inet = &addr->u.inet;
3680 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3681 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3682 } else {
3683 inet->host = g_strndup(addrstr, hostlen);
3685 /* plain VNC port is just an offset, for websocket
3686 * port is absolute */
3687 if (websocket) {
3688 if (g_str_equal(addrstr, "") ||
3689 g_str_equal(addrstr, "on")) {
3690 if (displaynum == -1) {
3691 error_setg(errp, "explicit websocket port is required");
3692 goto cleanup;
3694 inet->port = g_strdup_printf(
3695 "%d", displaynum + 5700);
3696 if (to) {
3697 inet->has_to = true;
3698 inet->to = to + 5700;
3700 } else {
3701 inet->port = g_strdup(port);
3703 } else {
3704 int offset = reverse ? 0 : 5900;
3705 if (parse_uint_full(port, &baseport, 10) < 0) {
3706 error_setg(errp, "can't convert to a number: %s", port);
3707 goto cleanup;
3709 if (baseport > 65535 ||
3710 baseport + offset > 65535) {
3711 error_setg(errp, "port %s out of range", port);
3712 goto cleanup;
3714 inet->port = g_strdup_printf(
3715 "%d", (int)baseport + offset);
3717 if (to) {
3718 inet->has_to = true;
3719 inet->to = to + offset;
3723 inet->ipv4 = ipv4;
3724 inet->has_ipv4 = has_ipv4;
3725 inet->ipv6 = ipv6;
3726 inet->has_ipv6 = has_ipv6;
3728 ret = baseport;
3731 *retaddr = addr;
3733 cleanup:
3734 if (ret < 0) {
3735 qapi_free_SocketAddress(addr);
3737 return ret;
3740 static void vnc_free_addresses(SocketAddress ***retsaddr,
3741 size_t *retnsaddr)
3743 size_t i;
3745 for (i = 0; i < *retnsaddr; i++) {
3746 qapi_free_SocketAddress((*retsaddr)[i]);
3748 g_free(*retsaddr);
3750 *retsaddr = NULL;
3751 *retnsaddr = 0;
3754 static int vnc_display_get_addresses(QemuOpts *opts,
3755 bool reverse,
3756 SocketAddress ***retsaddr,
3757 size_t *retnsaddr,
3758 SocketAddress ***retwsaddr,
3759 size_t *retnwsaddr,
3760 Error **errp)
3762 SocketAddress *saddr = NULL;
3763 SocketAddress *wsaddr = NULL;
3764 QemuOptsIter addriter;
3765 const char *addr;
3766 int to = qemu_opt_get_number(opts, "to", 0);
3767 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3768 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3769 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3770 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3771 int displaynum = -1;
3772 int ret = -1;
3774 *retsaddr = NULL;
3775 *retnsaddr = 0;
3776 *retwsaddr = NULL;
3777 *retnwsaddr = 0;
3779 addr = qemu_opt_get(opts, "vnc");
3780 if (addr == NULL || g_str_equal(addr, "none")) {
3781 ret = 0;
3782 goto cleanup;
3784 if (qemu_opt_get(opts, "websocket") &&
3785 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3786 error_setg(errp,
3787 "SHA1 hash support is required for websockets");
3788 goto cleanup;
3791 qemu_opt_iter_init(&addriter, opts, "vnc");
3792 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3793 int rv;
3794 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3795 has_ipv4, has_ipv6,
3796 ipv4, ipv6,
3797 &saddr, errp);
3798 if (rv < 0) {
3799 goto cleanup;
3801 /* Historical compat - first listen address can be used
3802 * to set the default websocket port
3804 if (displaynum == -1) {
3805 displaynum = rv;
3807 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3808 (*retsaddr)[(*retnsaddr)++] = saddr;
3811 /* If we had multiple primary displays, we don't do defaults
3812 * for websocket, and require explicit config instead. */
3813 if (*retnsaddr > 1) {
3814 displaynum = -1;
3817 qemu_opt_iter_init(&addriter, opts, "websocket");
3818 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3819 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3820 has_ipv4, has_ipv6,
3821 ipv4, ipv6,
3822 &wsaddr, errp) < 0) {
3823 goto cleanup;
3826 /* Historical compat - if only a single listen address was
3827 * provided, then this is used to set the default listen
3828 * address for websocket too
3830 if (*retnsaddr == 1 &&
3831 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3832 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3833 g_str_equal(wsaddr->u.inet.host, "") &&
3834 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3835 g_free(wsaddr->u.inet.host);
3836 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3839 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3840 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3843 ret = 0;
3844 cleanup:
3845 if (ret < 0) {
3846 vnc_free_addresses(retsaddr, retnsaddr);
3847 vnc_free_addresses(retwsaddr, retnwsaddr);
3849 return ret;
3852 static int vnc_display_connect(VncDisplay *vd,
3853 SocketAddress **saddr,
3854 size_t nsaddr,
3855 SocketAddress **wsaddr,
3856 size_t nwsaddr,
3857 Error **errp)
3859 /* connect to viewer */
3860 QIOChannelSocket *sioc = NULL;
3861 if (nwsaddr != 0) {
3862 error_setg(errp, "Cannot use websockets in reverse mode");
3863 return -1;
3865 if (nsaddr != 1) {
3866 error_setg(errp, "Expected a single address in reverse mode");
3867 return -1;
3869 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3870 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3871 sioc = qio_channel_socket_new();
3872 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3873 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3874 object_unref(OBJECT(sioc));
3875 return -1;
3877 vnc_connect(vd, sioc, false, false);
3878 object_unref(OBJECT(sioc));
3879 return 0;
3883 static int vnc_display_listen(VncDisplay *vd,
3884 SocketAddress **saddr,
3885 size_t nsaddr,
3886 SocketAddress **wsaddr,
3887 size_t nwsaddr,
3888 Error **errp)
3890 size_t i;
3892 if (nsaddr) {
3893 vd->listener = qio_net_listener_new();
3894 qio_net_listener_set_name(vd->listener, "vnc-listen");
3895 for (i = 0; i < nsaddr; i++) {
3896 if (qio_net_listener_open_sync(vd->listener,
3897 saddr[i], 1,
3898 errp) < 0) {
3899 return -1;
3903 qio_net_listener_set_client_func(vd->listener,
3904 vnc_listen_io, vd, NULL);
3907 if (nwsaddr) {
3908 vd->wslistener = qio_net_listener_new();
3909 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
3910 for (i = 0; i < nwsaddr; i++) {
3911 if (qio_net_listener_open_sync(vd->wslistener,
3912 wsaddr[i], 1,
3913 errp) < 0) {
3914 return -1;
3918 qio_net_listener_set_client_func(vd->wslistener,
3919 vnc_listen_io, vd, NULL);
3922 return 0;
3926 void vnc_display_open(const char *id, Error **errp)
3928 VncDisplay *vd = vnc_display_find(id);
3929 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3930 SocketAddress **saddr = NULL, **wsaddr = NULL;
3931 size_t nsaddr, nwsaddr;
3932 const char *share, *device_id;
3933 QemuConsole *con;
3934 bool password = false;
3935 bool reverse = false;
3936 const char *credid;
3937 bool sasl = false;
3938 int acl = 0;
3939 const char *tlsauthz;
3940 const char *saslauthz;
3941 int lock_key_sync = 1;
3942 int key_delay_ms;
3943 const char *audiodev;
3945 if (!vd) {
3946 error_setg(errp, "VNC display not active");
3947 return;
3949 vnc_display_close(vd);
3951 if (!opts) {
3952 return;
3955 reverse = qemu_opt_get_bool(opts, "reverse", false);
3956 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3957 &wsaddr, &nwsaddr, errp) < 0) {
3958 goto fail;
3961 password = qemu_opt_get_bool(opts, "password", false);
3962 if (password) {
3963 if (fips_get_state()) {
3964 error_setg(errp,
3965 "VNC password auth disabled due to FIPS mode, "
3966 "consider using the VeNCrypt or SASL authentication "
3967 "methods as an alternative");
3968 goto fail;
3970 if (!qcrypto_cipher_supports(
3971 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3972 error_setg(errp,
3973 "Cipher backend does not support DES RFB algorithm");
3974 goto fail;
3978 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3979 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
3980 sasl = qemu_opt_get_bool(opts, "sasl", false);
3981 #ifndef CONFIG_VNC_SASL
3982 if (sasl) {
3983 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3984 goto fail;
3986 #endif /* CONFIG_VNC_SASL */
3987 credid = qemu_opt_get(opts, "tls-creds");
3988 if (credid) {
3989 Object *creds;
3990 creds = object_resolve_path_component(
3991 object_get_objects_root(), credid);
3992 if (!creds) {
3993 error_setg(errp, "No TLS credentials with id '%s'",
3994 credid);
3995 goto fail;
3997 vd->tlscreds = (QCryptoTLSCreds *)
3998 object_dynamic_cast(creds,
3999 TYPE_QCRYPTO_TLS_CREDS);
4000 if (!vd->tlscreds) {
4001 error_setg(errp, "Object with id '%s' is not TLS credentials",
4002 credid);
4003 goto fail;
4005 object_ref(OBJECT(vd->tlscreds));
4007 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
4008 error_setg(errp,
4009 "Expecting TLS credentials with a server endpoint");
4010 goto fail;
4013 if (qemu_opt_get(opts, "acl")) {
4014 error_report("The 'acl' option to -vnc is deprecated. "
4015 "Please use the 'tls-authz' and 'sasl-authz' "
4016 "options instead");
4018 acl = qemu_opt_get_bool(opts, "acl", false);
4019 tlsauthz = qemu_opt_get(opts, "tls-authz");
4020 if (acl && tlsauthz) {
4021 error_setg(errp, "'acl' option is mutually exclusive with the "
4022 "'tls-authz' option");
4023 goto fail;
4025 if (tlsauthz && !vd->tlscreds) {
4026 error_setg(errp, "'tls-authz' provided but TLS is not enabled");
4027 goto fail;
4030 saslauthz = qemu_opt_get(opts, "sasl-authz");
4031 if (acl && saslauthz) {
4032 error_setg(errp, "'acl' option is mutually exclusive with the "
4033 "'sasl-authz' option");
4034 goto fail;
4036 if (saslauthz && !sasl) {
4037 error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
4038 goto fail;
4041 share = qemu_opt_get(opts, "share");
4042 if (share) {
4043 if (strcmp(share, "ignore") == 0) {
4044 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4045 } else if (strcmp(share, "allow-exclusive") == 0) {
4046 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4047 } else if (strcmp(share, "force-shared") == 0) {
4048 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4049 } else {
4050 error_setg(errp, "unknown vnc share= option");
4051 goto fail;
4053 } else {
4054 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4056 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4058 #ifdef CONFIG_VNC_JPEG
4059 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4060 #endif
4061 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
4062 /* adaptive updates are only used with tight encoding and
4063 * if lossy updates are enabled so we can disable all the
4064 * calculations otherwise */
4065 if (!vd->lossy) {
4066 vd->non_adaptive = true;
4069 vd->power_control = qemu_opt_get_bool(opts, "power-control", false);
4071 if (tlsauthz) {
4072 vd->tlsauthzid = g_strdup(tlsauthz);
4073 } else if (acl) {
4074 if (strcmp(vd->id, "default") == 0) {
4075 vd->tlsauthzid = g_strdup("vnc.x509dname");
4076 } else {
4077 vd->tlsauthzid = g_strdup_printf("vnc.%s.x509dname", vd->id);
4079 vd->tlsauthz = QAUTHZ(qauthz_list_new(vd->tlsauthzid,
4080 QAUTHZ_LIST_POLICY_DENY,
4081 &error_abort));
4083 #ifdef CONFIG_VNC_SASL
4084 if (sasl) {
4085 if (saslauthz) {
4086 vd->sasl.authzid = g_strdup(saslauthz);
4087 } else if (acl) {
4088 if (strcmp(vd->id, "default") == 0) {
4089 vd->sasl.authzid = g_strdup("vnc.username");
4090 } else {
4091 vd->sasl.authzid = g_strdup_printf("vnc.%s.username", vd->id);
4093 vd->sasl.authz = QAUTHZ(qauthz_list_new(vd->sasl.authzid,
4094 QAUTHZ_LIST_POLICY_DENY,
4095 &error_abort));
4098 #endif
4100 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4101 vd->tlscreds, password,
4102 sasl, false, errp) < 0) {
4103 goto fail;
4105 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
4107 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4108 vd->tlscreds, password,
4109 sasl, true, errp) < 0) {
4110 goto fail;
4112 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
4114 #ifdef CONFIG_VNC_SASL
4115 if (sasl) {
4116 int saslErr = sasl_server_init(NULL, "qemu");
4118 if (saslErr != SASL_OK) {
4119 error_setg(errp, "Failed to initialize SASL auth: %s",
4120 sasl_errstring(saslErr, NULL, NULL));
4121 goto fail;
4124 #endif
4125 vd->lock_key_sync = lock_key_sync;
4126 if (lock_key_sync) {
4127 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4129 vd->ledstate = 0;
4131 audiodev = qemu_opt_get(opts, "audiodev");
4132 if (audiodev) {
4133 vd->audio_state = audio_state_by_name(audiodev);
4134 if (!vd->audio_state) {
4135 error_setg(errp, "Audiodev '%s' not found", audiodev);
4136 goto fail;
4140 device_id = qemu_opt_get(opts, "display");
4141 if (device_id) {
4142 int head = qemu_opt_get_number(opts, "head", 0);
4143 Error *err = NULL;
4145 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4146 if (err) {
4147 error_propagate(errp, err);
4148 goto fail;
4150 } else {
4151 con = NULL;
4154 if (con != vd->dcl.con) {
4155 qkbd_state_free(vd->kbd);
4156 unregister_displaychangelistener(&vd->dcl);
4157 vd->dcl.con = con;
4158 register_displaychangelistener(&vd->dcl);
4159 vd->kbd = qkbd_state_init(vd->dcl.con);
4161 qkbd_state_set_delay(vd->kbd, key_delay_ms);
4163 if (saddr == NULL) {
4164 goto cleanup;
4167 if (reverse) {
4168 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4169 goto fail;
4171 } else {
4172 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4173 goto fail;
4177 if (qemu_opt_get(opts, "to")) {
4178 vnc_display_print_local_addr(vd);
4181 cleanup:
4182 vnc_free_addresses(&saddr, &nsaddr);
4183 vnc_free_addresses(&wsaddr, &nwsaddr);
4184 return;
4186 fail:
4187 vnc_display_close(vd);
4188 goto cleanup;
4191 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4193 VncDisplay *vd = vnc_display_find(id);
4194 QIOChannelSocket *sioc;
4196 if (!vd) {
4197 return;
4200 sioc = qio_channel_socket_new_fd(csock, NULL);
4201 if (sioc) {
4202 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4203 vnc_connect(vd, sioc, skipauth, false);
4204 object_unref(OBJECT(sioc));
4208 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4210 int i = 2;
4211 char *id;
4213 id = g_strdup("default");
4214 while (qemu_opts_find(olist, id)) {
4215 g_free(id);
4216 id = g_strdup_printf("vnc%d", i++);
4218 qemu_opts_set_id(opts, id);
4221 void vnc_parse(const char *str)
4223 QemuOptsList *olist = qemu_find_opts("vnc");
4224 QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str));
4225 const char *id;
4227 if (!opts) {
4228 exit(1);
4231 id = qemu_opts_id(opts);
4232 if (!id) {
4233 /* auto-assign id if not present */
4234 vnc_auto_assign_id(olist, opts);
4238 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4240 Error *local_err = NULL;
4241 char *id = (char *)qemu_opts_id(opts);
4243 assert(id);
4244 vnc_display_init(id, &local_err);
4245 if (local_err) {
4246 error_propagate(errp, local_err);
4247 return -1;
4249 vnc_display_open(id, &local_err);
4250 if (local_err != NULL) {
4251 error_propagate(errp, local_err);
4252 return -1;
4254 return 0;
4257 static void vnc_register_config(void)
4259 qemu_add_opts(&qemu_vnc_opts);
4261 opts_init(vnc_register_config);